From dcc501aec364f27f03aabfd5db6d5362a966be86 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 15 Dec 2015 17:23:58 +0100 Subject: [PATCH 001/112] 5.6.27-76.0 --- mysql-test/suite/tokudb.add_index/t/suite.opt | 1 + .../suite/tokudb.alter_table/t/suite.opt | 1 + .../tokudb.bugs/r/db756_card_part_hash.result | 6 +- .../r/db756_card_part_hash_1.result | 6 +- .../r/db756_card_part_hash_1_pick.result | 6 +- .../r/db756_card_part_hash_2.result | 6 +- .../r/db756_card_part_hash_2_pick.result | 4 +- .../r/db757_part_alter_analyze.result | 16 +- .../suite/tokudb.bugs/t/5585-master.opt | 2 +- mysql-test/suite/tokudb.bugs/t/5585.test | 3 +- mysql-test/suite/tokudb.bugs/t/disabled.def | 3 + mysql-test/suite/tokudb.bugs/t/suite.opt | 1 + .../r/partition_alter4_tokudb.result | 192 +- .../r/partition_auto_increment_tokudb.result | 4 + mysql-test/suite/tokudb.parts/t/disabled.def | 2 + ...partition_auto_increment_tokudb-master.opt | 1 - .../t/partition_auto_increment_tokudb.test | 5 + mysql-test/suite/tokudb.parts/t/suite.opt | 1 + mysql-test/suite/tokudb.rpl/combinations | 8 + .../r/rpl_parallel_tokudb_delete_pk.result | 7 + ...rallel_tokudb_update_pk_uc0_lookup0.result | 7 + .../r/rpl_parallel_tokudb_write_pk.result | 4 + .../tokudb.rpl/r/rpl_tokudb_delete_pk.result | 7 + .../r/rpl_tokudb_delete_pk_lookup1.result | 7 + .../tokudb.rpl/r/rpl_tokudb_mixed_dml.result | 1 + .../r/rpl_tokudb_read_only_ff.result | 7 + .../r/rpl_tokudb_read_only_ft.result | 7 + .../r/rpl_tokudb_read_only_tf.result | 7 + .../r/rpl_tokudb_read_only_tt.result | 7 + .../r/rpl_tokudb_update_pk_uc0_lookup0.result | 7 + .../r/rpl_tokudb_update_pk_uc0_lookup1.result | 7 + .../r/rpl_tokudb_update_pk_uc1_lookup0.result | 7 + .../r/rpl_tokudb_update_pk_uc1_lookup1.result | 7 + ...pl_tokudb_update_unique_uc0_lookup0.result | 7 + ...pl_tokudb_update_unique_uc0_lookup1.result | 7 + .../tokudb.rpl/r/rpl_tokudb_write_pk.result | 4 + .../r/rpl_tokudb_write_pk_uc1.result | 4 + .../r/rpl_tokudb_write_unique.result | 4 + .../r/rpl_tokudb_write_unique_uc1.result | 4 + .../tokudb.rpl/t/rpl_parallel_tokudb.test | 1 + .../t/rpl_parallel_tokudb_delete_pk-slave.opt | 2 +- .../t/rpl_parallel_tokudb_delete_pk.test | 2 +- ...lel_tokudb_update_pk_uc0_lookup0-slave.opt | 2 +- ...parallel_tokudb_update_pk_uc0_lookup0.test | 2 +- .../t/rpl_parallel_tokudb_write_pk-slave.opt | 2 +- .../t/rpl_parallel_tokudb_write_pk.test | 2 +- .../t/rpl_tokudb_delete_pk-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_delete_pk.test | 2 +- .../t/rpl_tokudb_delete_pk_lookup1-slave.opt | 2 +- .../t/rpl_tokudb_delete_pk_lookup1.test | 2 +- .../t/rpl_tokudb_mixed_dml-master.opt | 2 - .../tokudb.rpl/t/rpl_tokudb_mixed_dml.test | 3 + .../t/rpl_tokudb_read_only_ff-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_read_only_ff.test | 2 +- .../t/rpl_tokudb_read_only_ft-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_read_only_ft.test | 2 +- .../t/rpl_tokudb_read_only_tf-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_read_only_tf.test | 2 +- .../t/rpl_tokudb_read_only_tt-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_read_only_tt.test | 2 +- ...rpl_tokudb_update_pk_uc0_lookup0-slave.opt | 2 +- .../t/rpl_tokudb_update_pk_uc0_lookup0.test | 2 +- ...rpl_tokudb_update_pk_uc0_lookup1-slave.opt | 2 +- .../t/rpl_tokudb_update_pk_uc0_lookup1.test | 2 +- ...rpl_tokudb_update_pk_uc1_lookup0-slave.opt | 2 +- .../t/rpl_tokudb_update_pk_uc1_lookup0.test | 2 +- ...rpl_tokudb_update_pk_uc1_lookup1-slave.opt | 2 +- .../t/rpl_tokudb_update_pk_uc1_lookup1.test | 2 +- ...tokudb_update_unique_uc0_lookup0-slave.opt | 2 +- .../rpl_tokudb_update_unique_uc0_lookup0.test | 2 +- ...tokudb_update_unique_uc0_lookup1-slave.opt | 2 +- .../rpl_tokudb_update_unique_uc0_lookup1.test | 2 +- .../t/rpl_tokudb_write_pk-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_write_pk.test | 2 +- .../t/rpl_tokudb_write_pk_uc1-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test | 2 +- .../t/rpl_tokudb_write_unique-slave.opt | 2 +- .../tokudb.rpl/t/rpl_tokudb_write_unique.test | 2 +- .../t/rpl_tokudb_write_unique_uc1-slave.opt | 2 +- .../t/rpl_tokudb_write_unique_uc1.test | 2 +- mysql-test/suite/tokudb.rpl/t/suite.opt | 1 + .../r/tokudb_analyze_delete_fraction.result | 73 + .../tokudb_analyze_in_background_basic.result | 99 + .../r/tokudb_analyze_mode_basic.result | 89 + .../r/tokudb_analyze_throttle_basic.result | 61 + .../r/tokudb_analyze_time_basic.result | 61 + .../r/tokudb_auto_analyze.result | 61 + ...udb_cardinality_scale_percent_basic.result | 36 + mysql-test/suite/tokudb.sys_vars/t/suite.opt | 1 + .../t/tokudb_analyze_delete_fraction.test | 56 + .../t/tokudb_analyze_in_background_basic.test | 80 + .../t/tokudb_analyze_mode_basic.test | 72 + .../t/tokudb_analyze_throttle_basic.test | 50 + .../t/tokudb_analyze_time_basic.test | 50 + .../t/tokudb_auto_analyze.test | 50 + ...okudb_cardinality_scale_percent_basic.test | 32 + .../tokudb/r/background_job_manager.result | Bin 0 -> 6893 bytes .../suite/tokudb/r/card_add_drop.result | 22 +- .../suite/tokudb/r/card_add_index.result | 16 +- .../tokudb/r/card_auto_analyze_lots.result | 800 +++++ .../suite/tokudb/r/card_drop_index.result | 10 +- .../suite/tokudb/r/card_drop_index_2.result | 10 +- mysql-test/suite/tokudb/r/card_drop_pk.result | 16 +- mysql-test/suite/tokudb/r/card_pk_2.result | 6 +- mysql-test/suite/tokudb/r/card_pk_sk.result | 8 +- .../suite/tokudb/r/card_scale_percent.result | 42 + mysql-test/suite/tokudb/r/card_sk.result | 6 +- mysql-test/suite/tokudb/r/card_sk_2.result | 8 +- .../suite/tokudb/r/cluster_2968-0.result | 2 +- .../suite/tokudb/r/cluster_2968-1.result | 8 +- .../suite/tokudb/r/cluster_2968-2.result | 8 +- .../suite/tokudb/r/cluster_2968-3.result | 8 +- mysql-test/suite/tokudb/r/type_bit.result | 2 +- .../tokudb/t/background_job_manager.test | 139 + .../tokudb/t/card_auto_analyze_lots.test | 82 + .../suite/tokudb/t/card_scale_percent.test | 56 + mysql-test/suite/tokudb/t/disabled.def | 23 + .../suite/tokudb/t/rows-32m-seq-insert.test | 3 +- mysql-test/suite/tokudb/t/suite.opt | 1 + storage/tokudb/CMakeLists.txt | 38 +- storage/tokudb/PerconaFT/CMakeLists.txt | 4 +- ...CTestCustom.cmake => CTestCustom.cmake.in} | 0 .../PerconaFT/buildheader/CMakeLists.txt | 4 +- .../tokudb/PerconaFT/buildheader/make_tdb.cc | 5 +- .../cmake_modules/FindValgrind.cmake | 2 +- .../cmake_modules/TokuMergeLibs.cmake | 3 +- .../cmake_modules/TokuSetupCTest.cmake | 5 +- .../cmake_modules/TokuSetupCompiler.cmake | 6 +- .../cmake_modules/TokuThirdParty.cmake | 3 +- storage/tokudb/PerconaFT/ft/CMakeLists.txt | 1 + storage/tokudb/PerconaFT/ft/ft-flusher.cc | 6 +- storage/tokudb/PerconaFT/ft/ft-internal.h | 5 + storage/tokudb/PerconaFT/ft/ft-ops.cc | 11 +- storage/tokudb/PerconaFT/ft/ft-ops.h | 9 + .../tokudb/PerconaFT/ft/ft-recount-rows.cc | 115 + storage/tokudb/PerconaFT/ft/ft-status.cc | 36 +- .../tokudb/PerconaFT/ft/ft-test-helpers.cc | 29 +- storage/tokudb/PerconaFT/ft/ft.cc | 44 +- storage/tokudb/PerconaFT/ft/ft.h | 6 +- storage/tokudb/PerconaFT/ft/leafentry.h | 88 +- storage/tokudb/PerconaFT/ft/loader/loader.cc | 121 +- .../tokudb/PerconaFT/ft/logger/log_upgrade.cc | 5 +- storage/tokudb/PerconaFT/ft/logger/logger.h | 1 + storage/tokudb/PerconaFT/ft/node.cc | 475 ++- storage/tokudb/PerconaFT/ft/node.h | 67 +- .../PerconaFT/ft/serialize/ft-serialize.cc | 13 +- .../ft/serialize/ft_layout_version.h | 1 + .../tokudb/PerconaFT/ft/tests/CMakeLists.txt | 2 +- .../tokudb/PerconaFT/ft/tests/make-tree.cc | 11 +- .../tokudb/PerconaFT/ft/tests/msnfilter.cc | 68 +- .../PerconaFT/ft/tests/orthopush-flush.cc | 94 +- .../PerconaFT/ft/tests/verify-bad-msn.cc | 11 +- .../PerconaFT/ft/tests/verify-bad-pivots.cc | 11 +- .../PerconaFT/ft/tests/verify-dup-in-leaf.cc | 11 +- .../PerconaFT/ft/tests/verify-dup-pivots.cc | 11 +- .../ft/tests/verify-misrouted-msgs.cc | 11 +- .../ft/tests/verify-unsorted-leaf.cc | 11 +- .../ft/tests/verify-unsorted-pivots.cc | 11 +- .../tokudb/PerconaFT/ft/txn/rollback-apply.cc | 1 + storage/tokudb/PerconaFT/ft/txn/txn.cc | 19 +- .../tokudb/PerconaFT/ft/txn/txn_manager.cc | 21 +- storage/tokudb/PerconaFT/ft/txn/txn_manager.h | 9 + storage/tokudb/PerconaFT/ft/ule.cc | 1169 +++++--- .../PerconaFT/locktree/tests/CMakeLists.txt | 2 +- .../portability/tests/CMakeLists.txt | 2 +- .../PerconaFT/portability/toku_pthread.h | 33 +- .../tokudb/PerconaFT/portability/toku_time.h | 10 + storage/tokudb/PerconaFT/src/export.map | 1 + .../tokudb/PerconaFT/src/tests/CMakeLists.txt | 6 +- .../src/tests/rollback-inconsistency.cc | 161 + .../src/tests/stat64-root-changes.cc | 4 +- .../PerconaFT/src/tests/test_db_rowcount.cc | 528 ++++ .../txn_manager_handle_snapshot_atomicity.cc | 217 ++ storage/tokudb/PerconaFT/src/ydb.cc | 4 + storage/tokudb/PerconaFT/src/ydb.h | 3 + storage/tokudb/PerconaFT/src/ydb_db.cc | 20 + storage/tokudb/PerconaFT/tools/CMakeLists.txt | 2 +- .../PerconaFT/util/tests/CMakeLists.txt | 2 +- storage/tokudb/ha_tokudb.cc | 2577 ++++++++++------- storage/tokudb/ha_tokudb.h | 384 ++- storage/tokudb/ha_tokudb_admin.cc | 998 ++++++- storage/tokudb/ha_tokudb_alter_56.cc | 1244 +++++--- storage/tokudb/ha_tokudb_alter_common.cc | 433 +-- storage/tokudb/ha_tokudb_update.cc | 532 ++-- storage/tokudb/hatoku_cmp.cc | 410 ++- storage/tokudb/hatoku_cmp.h | 6 +- storage/tokudb/hatoku_defines.h | 370 +-- storage/tokudb/hatoku_hton.cc | 2144 +++++--------- storage/tokudb/hatoku_hton.h | 497 +--- storage/tokudb/tokudb_background.cc | 253 ++ storage/tokudb/tokudb_background.h | 212 ++ storage/tokudb/tokudb_buffer.h | 93 +- storage/tokudb/tokudb_card.h | 204 +- storage/tokudb/tokudb_debug.h | 171 ++ storage/tokudb/tokudb_information_schema.cc | 1208 ++++++++ storage/tokudb/tokudb_information_schema.h | 46 + storage/tokudb/tokudb_math.h | 42 +- storage/tokudb/tokudb_memory.h | 102 + storage/tokudb/tokudb_status.h | 442 ++- storage/tokudb/tokudb_sysvars.cc | 1099 +++++++ storage/tokudb/tokudb_sysvars.h | 147 + storage/tokudb/tokudb_thread.cc | 35 + storage/tokudb/tokudb_thread.h | 548 ++++ storage/tokudb/tokudb_time.h | 73 + storage/tokudb/tokudb_txn.h | 155 + storage/tokudb/tokudb_update_fun.cc | 977 ++++--- 206 files changed, 15619 insertions(+), 5969 deletions(-) create mode 100644 mysql-test/suite/tokudb.add_index/t/suite.opt create mode 100644 mysql-test/suite/tokudb.alter_table/t/suite.opt create mode 100644 mysql-test/suite/tokudb.bugs/t/suite.opt delete mode 100644 mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb-master.opt create mode 100644 mysql-test/suite/tokudb.parts/t/suite.opt create mode 100644 mysql-test/suite/tokudb.rpl/combinations delete mode 100644 mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml-master.opt create mode 100644 mysql-test/suite/tokudb.rpl/t/suite.opt create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_delete_fraction.result create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_in_background_basic.result create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_mode_basic.result create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_throttle_basic.result create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_time_basic.result create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_auto_analyze.result create mode 100644 mysql-test/suite/tokudb.sys_vars/r/tokudb_cardinality_scale_percent_basic.result create mode 100644 mysql-test/suite/tokudb.sys_vars/t/suite.opt create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_delete_fraction.test create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_in_background_basic.test create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_mode_basic.test create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_throttle_basic.test create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_time_basic.test create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_auto_analyze.test create mode 100644 mysql-test/suite/tokudb.sys_vars/t/tokudb_cardinality_scale_percent_basic.test create mode 100644 mysql-test/suite/tokudb/r/background_job_manager.result create mode 100644 mysql-test/suite/tokudb/r/card_auto_analyze_lots.result create mode 100644 mysql-test/suite/tokudb/r/card_scale_percent.result create mode 100644 mysql-test/suite/tokudb/t/background_job_manager.test create mode 100644 mysql-test/suite/tokudb/t/card_auto_analyze_lots.test create mode 100644 mysql-test/suite/tokudb/t/card_scale_percent.test create mode 100644 mysql-test/suite/tokudb/t/suite.opt rename storage/tokudb/PerconaFT/{CTestCustom.cmake => CTestCustom.cmake.in} (100%) create mode 100644 storage/tokudb/PerconaFT/ft/ft-recount-rows.cc create mode 100644 storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc create mode 100644 storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc create mode 100644 storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc create mode 100644 storage/tokudb/tokudb_background.cc create mode 100644 storage/tokudb/tokudb_background.h create mode 100644 storage/tokudb/tokudb_debug.h create mode 100644 storage/tokudb/tokudb_information_schema.cc create mode 100644 storage/tokudb/tokudb_information_schema.h create mode 100644 storage/tokudb/tokudb_memory.h create mode 100644 storage/tokudb/tokudb_sysvars.cc create mode 100644 storage/tokudb/tokudb_sysvars.h create mode 100644 storage/tokudb/tokudb_thread.cc create mode 100644 storage/tokudb/tokudb_thread.h create mode 100644 storage/tokudb/tokudb_time.h create mode 100644 storage/tokudb/tokudb_txn.h diff --git a/mysql-test/suite/tokudb.add_index/t/suite.opt b/mysql-test/suite/tokudb.add_index/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb.add_index/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.alter_table/t/suite.opt b/mysql-test/suite/tokudb.alter_table/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb.alter_table/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash.result b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash.result index c1ca24b0551e5..70bc86e1abc7a 100644 --- a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash.result +++ b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash.result @@ -4,18 +4,18 @@ create table t (id int, x int, primary key (id), key (x)) partition by hash(id) show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 2 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,1),(5,1); insert into t values (2,1),(4,1),(6,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 6 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 6 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 6 NULL NULL BTREE -t 1 x 1 x A 2 NULL NULL YES BTREE +t 1 x 1 x A 6 NULL NULL YES BTREE drop table t; diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1.result b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1.result index c82c922a87ae1..b6d9fd7da8537 100644 --- a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1.result +++ b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1.result @@ -4,17 +4,17 @@ create table t (id int, x int, primary key (id), key (x)) partition by hash(id) show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 2 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,1),(5,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A 1 NULL NULL YES BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE drop table t; diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1_pick.result b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1_pick.result index 576d1adee6c34..caaa963c325ad 100644 --- a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1_pick.result +++ b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1_pick.result @@ -4,18 +4,18 @@ create table t (id int, x int, primary key (id), key (x)) partition by hash(id) show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 2 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,2),(5,3); insert into t values (2,1),(4,1),(6,1),(8,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 7 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 7 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 7 NULL NULL BTREE -t 1 x 1 x A 1 NULL NULL YES BTREE +t 1 x 1 x A 7 NULL NULL YES BTREE drop table t; diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2.result b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2.result index 8937ddabbe3ac..6d345d98c95ff 100644 --- a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2.result +++ b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2.result @@ -4,17 +4,17 @@ create table t (id int, x int, primary key (id), key (x)) partition by hash(id) show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 2 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (2,1),(4,1),(6,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A 1 NULL NULL YES BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE drop table t; diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2_pick.result b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2_pick.result index 89b51a5a6b026..06639c311cf9a 100644 --- a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2_pick.result +++ b/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2_pick.result @@ -4,13 +4,13 @@ create table t (id int, x int, primary key (id), key (x)) partition by hash(id) show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 2 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,2),(5,3),(7,4); insert into t values (2,1),(4,1),(6,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 7 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE +t 1 x 1 x A 7 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK diff --git a/mysql-test/suite/tokudb.bugs/r/db757_part_alter_analyze.result b/mysql-test/suite/tokudb.bugs/r/db757_part_alter_analyze.result index d80e3e4eac82d..4b82cb06026af 100644 --- a/mysql-test/suite/tokudb.bugs/r/db757_part_alter_analyze.result +++ b/mysql-test/suite/tokudb.bugs/r/db757_part_alter_analyze.result @@ -7,15 +7,15 @@ insert into t values (1,1,1),(2,1,2),(3,1,3),(4,1,4); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 5 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE -t 1 y 1 y A NULL NULL NULL YES BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE +t 1 y 1 y A 5 NULL NULL YES BTREE alter table t analyze partition p0; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 5 NULL NULL BTREE -t 1 x 1 x A 1 NULL NULL YES BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE t 1 y 1 y A 5 NULL NULL YES BTREE alter table t analyze partition p1; Table Op Msg_type Msg_text @@ -23,13 +23,13 @@ test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 5 NULL NULL BTREE -t 1 x 1 x A 1 NULL NULL YES BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE t 1 y 1 y A 5 NULL NULL YES BTREE insert into t values (100,1,1),(200,2,1),(300,3,1),(400,4,1),(500,5,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 9 NULL NULL BTREE -t 1 x 1 x A 2 NULL NULL YES BTREE +t 1 x 1 x A 9 NULL NULL YES BTREE t 1 y 1 y A 9 NULL NULL YES BTREE alter table t analyze partition p0; Table Op Msg_type Msg_text @@ -37,8 +37,8 @@ test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 9 NULL NULL BTREE -t 1 x 1 x A NULL NULL NULL YES BTREE -t 1 y 1 y A NULL NULL NULL YES BTREE +t 1 x 1 x A 9 NULL NULL YES BTREE +t 1 y 1 y A 9 NULL NULL YES BTREE alter table t analyze partition p1; Table Op Msg_type Msg_text test.t analyze status OK @@ -46,5 +46,5 @@ show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 9 NULL NULL BTREE t 1 x 1 x A 9 NULL NULL YES BTREE -t 1 y 1 y A 1 NULL NULL YES BTREE +t 1 y 1 y A 4 NULL NULL YES BTREE drop table t; diff --git a/mysql-test/suite/tokudb.bugs/t/5585-master.opt b/mysql-test/suite/tokudb.bugs/t/5585-master.opt index 017432e797dfb..acad193fd765e 100644 --- a/mysql-test/suite/tokudb.bugs/t/5585-master.opt +++ b/mysql-test/suite/tokudb.bugs/t/5585-master.opt @@ -1 +1 @@ ---tokudb-cache-size=1000000000 --innodb-buffer-pool-size=1000000000 +--loose-tokudb-cache-size=1000000000 --innodb-buffer-pool-size=1000000000 diff --git a/mysql-test/suite/tokudb.bugs/t/5585.test b/mysql-test/suite/tokudb.bugs/t/5585.test index bf0df681e7a6d..6cc5fb223c03d 100644 --- a/mysql-test/suite/tokudb.bugs/t/5585.test +++ b/mysql-test/suite/tokudb.bugs/t/5585.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc --source include/have_tokudb.inc +--source include/big_test.inc --disable_warnings drop table if exists t1, t2; @@ -64,4 +65,4 @@ select t1.file_id, (select hits from t2 where t2.file_id = t1.file_id and t2.insert_ts = date(date_sub(now(),interval 1 day))) as d from t1; -drop table if exists t1, t2; \ No newline at end of file +drop table if exists t1, t2; diff --git a/mysql-test/suite/tokudb.bugs/t/disabled.def b/mysql-test/suite/tokudb.bugs/t/disabled.def index 7e67d159d7a50..8c755dde8f5ab 100644 --- a/mysql-test/suite/tokudb.bugs/t/disabled.def +++ b/mysql-test/suite/tokudb.bugs/t/disabled.def @@ -11,3 +11,6 @@ checkpoint_lock_2: test can not work when the checkpoint_safe_lock is a fair rwl 6053: tokudb is not the default storage engine 1883: tokutek's auto inc singleton patch missing 3083: no patch to find_shortest_key to prefer PK over CK +db768 : https://tokutek.atlassian.net/browse/DB-768 +dict_leak_3518 : https://tokutek.atlassian.net/browse/DB-635 +1872 : https://tokutek.atlassian.net/browse/DB-750 diff --git a/mysql-test/suite/tokudb.bugs/t/suite.opt b/mysql-test/suite/tokudb.bugs/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb.bugs/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter4_tokudb.result b/mysql-test/suite/tokudb.parts/r/partition_alter4_tokudb.result index 644c4815a36c0..b4e8e47b7d96b 100644 --- a/mysql-test/suite/tokudb.parts/r/partition_alter4_tokudb.result +++ b/mysql-test/suite/tokudb.parts/r/partition_alter4_tokudb.result @@ -7560,7 +7560,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -8019,7 +8020,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -8489,7 +8491,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -8960,7 +8963,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -9425,7 +9429,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -9896,7 +9901,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -10372,7 +10378,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -10846,7 +10853,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -11310,7 +11318,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -11769,7 +11778,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -12239,7 +12249,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -12710,7 +12721,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -13175,7 +13187,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -13646,7 +13659,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -14122,7 +14136,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -14596,7 +14611,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 ANALYZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 analyze error Error in list of partitions to test.t1 +test.t1 analyze Error Error in list of partitions to test.t1 +test.t1 analyze status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -26313,7 +26329,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -26772,7 +26789,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -27242,7 +27260,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -27713,7 +27732,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -28178,7 +28198,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -28649,7 +28670,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -29125,7 +29147,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -29599,7 +29622,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -30063,7 +30087,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -30522,7 +30547,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -30992,7 +31018,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -31463,7 +31490,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -31928,7 +31956,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -32399,7 +32428,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -32875,7 +32905,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -33349,7 +33380,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 CHECK PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 check error Error in list of partitions to test.t1 +test.t1 check Error Error in list of partitions to test.t1 +test.t1 check status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -45082,7 +45114,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -45541,7 +45574,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -46011,7 +46045,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -46482,7 +46517,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -46947,7 +46983,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -47418,7 +47455,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -47894,7 +47932,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -48368,7 +48407,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -48832,7 +48872,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -49291,7 +49332,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -49761,7 +49803,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -50232,7 +50275,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -50697,7 +50741,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -51168,7 +51213,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -51644,7 +51690,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -52118,7 +52165,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 optimize error Error in list of partitions to test.t1 +test.t1 optimize Error Error in list of partitions to test.t1 +test.t1 optimize status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -75368,7 +75416,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -75827,7 +75876,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -76297,7 +76347,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -76768,7 +76819,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -77233,7 +77285,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -77704,7 +77757,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -78180,7 +78234,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -78654,7 +78709,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_2,part_5,part_6,part_10; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -79118,7 +79174,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -79577,7 +79634,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -80047,7 +80105,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -80518,7 +80577,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -80983,7 +81043,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -81454,7 +81515,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -81930,7 +81992,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; @@ -82404,7 +82467,8 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 REPAIR PARTITION part_1,part_1,part_1; Table Op Msg_type Msg_text -test.t1 repair error Error in list of partitions to test.t1 +test.t1 repair Error Error in list of partitions to test.t1 +test.t1 repair status Operation failed INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN @max_row_div2 AND @max_row; diff --git a/mysql-test/suite/tokudb.parts/r/partition_auto_increment_tokudb.result b/mysql-test/suite/tokudb.parts/r/partition_auto_increment_tokudb.result index a40493a18f531..b4ae303adff70 100644 --- a/mysql-test/suite/tokudb.parts/r/partition_auto_increment_tokudb.result +++ b/mysql-test/suite/tokudb.parts/r/partition_auto_increment_tokudb.result @@ -1,3 +1,6 @@ +SET @tokudb_prelock_empty_saved = @@GLOBAL.tokudb_prelock_empty; +SET GLOBAL tokudb_prelock_empty = 0; +SET SESSION tokudb_prelock_empty = 0; DROP TABLE IF EXISTS t1; # test without partitioning for reference CREATE TABLE t1 ( @@ -1113,3 +1116,4 @@ a 0 DROP TABLE t1; ############################################################################## +SET GLOBAL tokudb_prelock_empty = @tokudb_prelock_empty_saved; diff --git a/mysql-test/suite/tokudb.parts/t/disabled.def b/mysql-test/suite/tokudb.parts/t/disabled.def index 90e599cd0353e..68d7693612ff9 100644 --- a/mysql-test/suite/tokudb.parts/t/disabled.def +++ b/mysql-test/suite/tokudb.parts/t/disabled.def @@ -1,2 +1,4 @@ partition_basic_symlink_tokudb : tokudb_file_per_table is not supported partition_reorganize_tokudb : tokudb_file_per_table is not supported +partition_mgm_lc0_tokudb : https://tokutek.atlassian.net/browse/DB-637 +partition_mgm_lc1_tokudb : https://tokutek.atlassian.net/browse/DB-637 diff --git a/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb-master.opt b/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb-master.opt deleted file mode 100644 index 857da664d10da..0000000000000 --- a/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb-master.opt +++ /dev/null @@ -1 +0,0 @@ ---tokudb-prelock-empty=0 diff --git a/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb.test b/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb.test index a13ddf65d4bd4..ceec2fda9ee6b 100644 --- a/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb.test +++ b/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb.test @@ -29,7 +29,12 @@ let $engine= 'TokuDB'; --source include/have_tokudb.inc +SET @tokudb_prelock_empty_saved = @@GLOBAL.tokudb_prelock_empty; +SET GLOBAL tokudb_prelock_empty = 0; +SET SESSION tokudb_prelock_empty = 0; + #------------------------------------------------------------------------------# # Execute the tests to be applied to all storage engines --source suite/parts/inc/partition_auto_increment.inc +SET GLOBAL tokudb_prelock_empty = @tokudb_prelock_empty_saved; diff --git a/mysql-test/suite/tokudb.parts/t/suite.opt b/mysql-test/suite/tokudb.parts/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb.parts/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.rpl/combinations b/mysql-test/suite/tokudb.rpl/combinations new file mode 100644 index 0000000000000..07042c2cbecd2 --- /dev/null +++ b/mysql-test/suite/tokudb.rpl/combinations @@ -0,0 +1,8 @@ +[row] +binlog-format=row + +[stmt] +binlog-format=statement + +[mix] +binlog-format=mixed diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_delete_pk.result b/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_delete_pk.result index 3021675bbda8c..afbc4b50da8ec 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_delete_pk.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_delete_pk.result @@ -6,6 +6,13 @@ Warnings: Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows OFF +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, primary key(a)) engine=tokudb; insert into t values (1); insert into t values (2),(3); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result b/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result index 39a6856d684f9..7aab8947940e9 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result @@ -6,6 +6,13 @@ Warnings: Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows OFF +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, primary key(a)) engine=tokudb; insert into t values (1,0); insert into t values (2,0),(3,0); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_write_pk.result b/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_write_pk.result index 314ccaedaf7be..64b495350c28e 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_write_pk.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_write_pk.result @@ -6,6 +6,10 @@ Warnings: Note 1753 slave_transaction_retries is not supported in multi-threaded slave mode. In the event of a transient failure, the slave will not retry the transaction and will stop. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_unique_checks%'; +Variable_name Value +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk.result index c77cbbc71c9f2..6fab29177d747 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows OFF +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, primary key(a)) engine=tokudb; insert into t values (1); insert into t values (2),(3); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk_lookup1.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk_lookup1.result index e178b8ad13780..f8efd5e04ee26 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk_lookup1.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk_lookup1.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks ON +tokudb_rpl_unique_checks_delay 0 create table t (a bigint not null, primary key(a)) engine=tokudb; insert into t values (1); insert into t values (2),(3); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_dml.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_dml.result index 9300d29bb290f..c11ae61b3caa7 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_dml.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_dml.result @@ -1,3 +1,4 @@ +SET SESSION tokudb_pk_insert_mode = 2; include/master-slave.inc Warnings: Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ff.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ff.result index 5926cdda565b9..76a5e31b969b9 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ff.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ff.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl%'; +Variable_name Value +tokudb_rpl_check_readonly OFF +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 0 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ft.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ft.result index 0b5ac77481f29..2930cb019b47b 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ft.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ft.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 0 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tf.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tf.result index 5926cdda565b9..76a5e31b969b9 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tf.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tf.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl%'; +Variable_name Value +tokudb_rpl_check_readonly OFF +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 0 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tt.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tt.result index 5926cdda565b9..0cba2a1cddba8 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tt.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tt.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 0 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result index 162655f9896f5..50f43ebe5bf09 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows OFF +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, primary key(a)) engine=tokudb; insert into t values (1,0); insert into t values (2,0),(3,0); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result index 3c9097184266b..9e7f932a3c970 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, primary key(a)) engine=tokudb; insert into t values (1,0); insert into t values (2,0),(3,0); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result index 3c9097184266b..348734b206dad 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows OFF +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks ON +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, primary key(a)) engine=tokudb; insert into t values (1,0); insert into t values (2,0),(3,0); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result index 3c9097184266b..bfd640e52e968 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks ON +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, primary key(a)) engine=tokudb; insert into t values (1,0); insert into t values (2,0),(3,0); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result index 941010071aea8..faf969f851a51 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows OFF +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, c bigint not null, primary key(a), unique key(c)) engine=tokudb; insert into t values (1,0,-1); insert into t values (2,0,-2),(3,0,-3); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result index 6a0b1126710be..9ac87512f8087 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result @@ -4,6 +4,13 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_%'; +Variable_name Value +tokudb_rpl_check_readonly ON +tokudb_rpl_lookup_rows ON +tokudb_rpl_lookup_rows_delay 10000 +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, b bigint not null, c bigint not null, primary key(a), unique key(c)) engine=tokudb; insert into t values (1,0,-1); insert into t values (2,0,-2),(3,0,-3); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk.result index 5926cdda565b9..ea1b84f8138ea 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk.result @@ -4,6 +4,10 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_unique_checks%'; +Variable_name Value +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk_uc1.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk_uc1.result index 0b5ac77481f29..c846ec8161216 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk_uc1.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk_uc1.result @@ -4,6 +4,10 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_unique_checks%'; +Variable_name Value +tokudb_rpl_unique_checks ON +tokudb_rpl_unique_checks_delay 10000 create table t (a bigint not null, primary key(a)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique.result index 60ffc0d05306a..808303387d56d 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique.result @@ -4,6 +4,10 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_unique_checks%'; +Variable_name Value +tokudb_rpl_unique_checks OFF +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, b bigint not null, primary key(a), unique key(b)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1,2); diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique_uc1.result b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique_uc1.result index 2f2cf58032e04..a40548cec62c8 100644 --- a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique_uc1.result +++ b/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique_uc1.result @@ -4,6 +4,10 @@ Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] drop table if exists t; +show variables like 'tokudb_rpl_unique_checks%'; +Variable_name Value +tokudb_rpl_unique_checks ON +tokudb_rpl_unique_checks_delay 5000 create table t (a bigint not null, b bigint not null, primary key(a), unique key(b)) engine=tokudb; select unix_timestamp() into @tstart; insert into t values (1,2); diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb.test b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb.test index efb60fac2babf..23d2d6cdf517c 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb.test @@ -1,3 +1,4 @@ +--source include/have_tokudb.inc #Want to skip this test from daily Valgrind execution --source include/no_valgrind_without_big.inc # diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt index 2c35be69b9886..042156e63d123 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt @@ -1,2 +1,2 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=OFF --slave-parallel-workers=2 +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=OFF --slave-parallel-workers=2 diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk.test b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk.test index fb42f40bb62d4..bedeb9513be19 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt index d84d7111bd6bc..fffefff5bcd39 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=OFF --slave-parallel-workers=2 +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=OFF --slave-parallel-workers=2 diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test index 998987349c7b5..6dd9b660eedfc 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk-slave.opt index 9e4f2f7048d5e..f2ed028613632 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk-slave.opt @@ -1,2 +1,2 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF --slave-parallel-workers=2 +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF --slave-parallel-workers=2 diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk.test b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk.test index c77e4b49605e5..0ed12b34e1f72 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl_unique_checks%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk-slave.opt index dc139282dc4c3..93a2685e847cd 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=OFF +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk.test index fb42f40bb62d4..bedeb9513be19 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt index 4675b07763d07..9a2fec628f90b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=0 --tokudb-rpl-unique-checks=ON --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=ON +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=0 --loose-tokudb-rpl-unique-checks=ON --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=ON diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1.test index bf5edbd2c1b39..9e9aaede4165e 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1.test @@ -15,7 +15,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml-master.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml-master.opt deleted file mode 100644 index fd3de58d81652..0000000000000 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---tokudb_pk_insert_mode=2 - diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml.test index c27625abd7f4b..6147d321784a7 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml.test @@ -6,4 +6,7 @@ --source include/have_binlog_format_mixed.inc --source include/have_tokudb.inc let $engine_type=TokuDB; + +SET SESSION tokudb_pk_insert_mode = 2; + --source suite/rpl/include/rpl_mixed_dml.inc diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff-slave.opt index b9eb687d8d591..0240c9d6ae489 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff-slave.opt @@ -1 +1 @@ ---read-only=OFF --tokudb-rpl-check-readonly=OFF --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF +--read-only=OFF --loose-tokudb-rpl-check-readonly=OFF --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff.test index c77e4b49605e5..7b3e8f0c0d33b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft-slave.opt index 8283875e8a7dd..e1ee193d4c124 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft-slave.opt @@ -1 +1 @@ ---read-only=OFF --tokudb-rpl-check-readonly=ON --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF +--read-only=OFF --loose-tokudb-rpl-check-readonly=ON --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft.test index c77e4b49605e5..7b3e8f0c0d33b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf-slave.opt index 21e57d27c1798..e60afd0380a59 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-check-readonly=OFF --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF +--read-only=ON --loose-tokudb-rpl-check-readonly=OFF --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf.test index c77e4b49605e5..7b3e8f0c0d33b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt-slave.opt index fd77ee0da9c76..f6658646e6567 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-check-readonly=ON --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF +--read-only=ON --loose-tokudb-rpl-check-readonly=ON --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt.test index c77e4b49605e5..7b3e8f0c0d33b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt index dc139282dc4c3..93a2685e847cd 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=OFF +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test index 998987349c7b5..6dd9b660eedfc 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt index d546dd00669b1..a4ca11044258c 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=ON +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=ON diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test index 998987349c7b5..6dd9b660eedfc 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt index 5cfe5f83a91eb..4b1d21daf5f5b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=ON --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=OFF +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=ON --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test index 998987349c7b5..6dd9b660eedfc 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt index 7cd575c52bb14..239e19ac04081 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=ON --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=ON +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=ON --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=ON diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test index 998987349c7b5..6dd9b660eedfc 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt index dc139282dc4c3..93a2685e847cd 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=OFF +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test index 11401ac0ce024..93fef3699d981 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt index d546dd00669b1..a4ca11044258c 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=OFF --tokudb-rpl-lookup-rows-delay=10000 --tokudb-rpl-lookup-rows=ON +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=OFF --loose-tokudb-rpl-lookup-rows-delay=10000 --loose-tokudb-rpl-lookup-rows=ON diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test index ea77447bc75c0..c8976db8ccde1 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test @@ -13,7 +13,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_%'; +show variables like 'tokudb_rpl_%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk-slave.opt index 9baf0d65ecfab..19b40f86454ae 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk.test index c77e4b49605e5..0ed12b34e1f72 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl_unique_checks%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1-slave.opt index b1df0b6daf017..646a99917532b 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=10000 --tokudb-rpl-unique-checks=ON +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=10000 --loose-tokudb-rpl-unique-checks=ON diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test index c77e4b49605e5..0ed12b34e1f72 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl_unique_checks%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique-slave.opt index 9baf0d65ecfab..19b40f86454ae 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=OFF +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=OFF diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique.test index cf6a26b423dae..fc4c9597dac37 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl_unique_checks%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1-slave.opt b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1-slave.opt index 0518efd3da5c1..9139a370e57ec 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1-slave.opt +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1-slave.opt @@ -1 +1 @@ ---read-only=ON --tokudb-rpl-unique-checks-delay=5000 --tokudb-rpl-unique-checks=ON +--read-only=ON --loose-tokudb-rpl-unique-checks-delay=5000 --loose-tokudb-rpl-unique-checks=ON diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1.test b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1.test index cf6a26b423dae..fc4c9597dac37 100644 --- a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1.test +++ b/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1.test @@ -14,7 +14,7 @@ enable_warnings; connection slave; # show variables like 'read_only'; -# show variables like 'tokudb_rpl_unique_checks%'; +show variables like 'tokudb_rpl_unique_checks%'; # insert some rows connection master; diff --git a/mysql-test/suite/tokudb.rpl/t/suite.opt b/mysql-test/suite/tokudb.rpl/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb.rpl/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_delete_fraction.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_delete_fraction.result new file mode 100644 index 0000000000000..41918883dd673 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_delete_fraction.result @@ -0,0 +1,73 @@ +SET @orig_global = @@global.tokudb_analyze_delete_fraction; +SELECT @orig_global; +@orig_global +1 +SET @orig_session = @@session.tokudb_analyze_delete_fraction; +SELECT @orig_session; +@orig_session +1 +SET GLOBAL tokudb_analyze_delete_fraction = .5; +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +0.500000 +SET GLOBAL tokudb_analyze_delete_fraction = 0; +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +0.000000 +SET GLOBAL tokudb_analyze_delete_fraction = DEFAULT; +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +1.000000 +SET GLOBAL tokudb_analyze_delete_fraction = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_delete_fraction' +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +1.000000 +SET GLOBAL tokudb_analyze_delete_fraction = 3.75; +Warnings: +Warning 1292 Truncated incorrect tokudb_analyze_delete_fraction value: '3.75' +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +1.000000 +SET SESSION tokudb_analyze_delete_fraction = .5; +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +0.500000 +SET SESSION tokudb_analyze_delete_fraction = 0; +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +0.000000 +SET SESSION tokudb_analyze_delete_fraction = DEFAULT; +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +1.000000 +SET SESSION tokudb_analyze_delete_fraction = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_delete_fraction' +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +1.000000 +SET SESSION tokudb_analyze_delete_fraction = 3.75; +Warnings: +Warning 1292 Truncated incorrect tokudb_analyze_delete_fraction value: '3.75' +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +1.000000 +SET GLOBAL tokudb_analyze_delete_fraction = .2; +SET SESSION tokudb_analyze_delete_fraction = .3; +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +0.200000 +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +0.300000 +SHOW VARIABLES LIKE 'tokudb_analyze_delete_fraction'; +Variable_name Value +tokudb_analyze_delete_fraction 0.300000 +SET SESSION tokudb_analyze_delete_fraction = @orig_session; +SELECT @@session.tokudb_analyze_delete_fraction; +@@session.tokudb_analyze_delete_fraction +1.000000 +SET GLOBAL tokudb_analyze_delete_fraction = @orig_global; +SELECT @@global.tokudb_analyze_delete_fraction; +@@global.tokudb_analyze_delete_fraction +1.000000 diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_in_background_basic.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_in_background_basic.result new file mode 100644 index 0000000000000..53e96810eda24 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_in_background_basic.result @@ -0,0 +1,99 @@ +SET @orig_global = @@global.tokudb_analyze_in_background; +SELECT @orig_global; +@orig_global +0 +SET @orig_session = @@session.tokudb_analyze_in_background; +SELECT @orig_session; +@orig_session +0 +SET GLOBAL tokudb_analyze_in_background = 0; +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +0 +SET GLOBAL tokudb_analyze_in_background = 1; +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +1 +SET GLOBAL tokudb_analyze_in_background = DEFAULT; +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +0 +SET GLOBAL tokudb_analyze_in_background = -6; +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +1 +SET GLOBAL tokudb_analyze_in_background = 1.6; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_in_background' +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +1 +SET GLOBAL tokudb_analyze_in_background = "T"; +ERROR 42000: Variable 'tokudb_analyze_in_background' can't be set to the value of 'T' +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +1 +SET GLOBAL tokudb_analyze_in_background = "Y"; +ERROR 42000: Variable 'tokudb_analyze_in_background' can't be set to the value of 'Y' +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +1 +SET GLOBAL tokudb_analyze_in_background = 'foobar'; +ERROR 42000: Variable 'tokudb_analyze_in_background' can't be set to the value of 'foobar' +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = 0; +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +0 +SET SESSION tokudb_analyze_in_background = 1; +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = DEFAULT; +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = -6; +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = 1.6; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_in_background' +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = "T"; +ERROR 42000: Variable 'tokudb_analyze_in_background' can't be set to the value of 'T' +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = "Y"; +ERROR 42000: Variable 'tokudb_analyze_in_background' can't be set to the value of 'Y' +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET SESSION tokudb_analyze_in_background = 'foobar'; +ERROR 42000: Variable 'tokudb_analyze_in_background' can't be set to the value of 'foobar' +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SET GLOBAL tokudb_analyze_in_background = 0; +SET SESSION tokudb_analyze_in_background = 1; +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +0 +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +1 +SHOW VARIABLES LIKE 'tokudb_analyze_in_background'; +Variable_name Value +tokudb_analyze_in_background ON +SET SESSION tokudb_analyze_in_background = @orig_session; +SELECT @@session.tokudb_analyze_in_background; +@@session.tokudb_analyze_in_background +0 +SET GLOBAL tokudb_analyze_in_background = @orig_global; +SELECT @@global.tokudb_analyze_in_background; +@@global.tokudb_analyze_in_background +0 diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_mode_basic.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_mode_basic.result new file mode 100644 index 0000000000000..e2a3059a5aa72 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_mode_basic.result @@ -0,0 +1,89 @@ +SET @orig_global = @@global.tokudb_analyze_mode; +SELECT @orig_global; +@orig_global +TOKUDB_ANALYZE_STANDARD +SET @orig_session = @@session.tokudb_analyze_mode; +SELECT @orig_session; +@orig_session +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_standard'; +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_recount_rows'; +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_RECOUNT_ROWS +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_cancel'; +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_CANCEL +SET GLOBAL tokudb_analyze_mode = DEFAULT; +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = ''; +ERROR 42000: Variable 'tokudb_analyze_mode' can't be set to the value of '' +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = 'foobar'; +ERROR 42000: Variable 'tokudb_analyze_mode' can't be set to the value of 'foobar' +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = 123; +ERROR 42000: Variable 'tokudb_analyze_mode' can't be set to the value of '123' +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_standard'; +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_recount_rows'; +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_RECOUNT_ROWS +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_cancel'; +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_CANCEL +SET SESSION tokudb_analyze_mode = DEFAULT; +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET SESSION tokudb_analyze_mode = ''; +ERROR 42000: Variable 'tokudb_analyze_mode' can't be set to the value of '' +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET SESSION tokudb_analyze_mode = 'foobar'; +ERROR 42000: Variable 'tokudb_analyze_mode' can't be set to the value of 'foobar' +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET SESSION tokudb_analyze_mode = 123; +ERROR 42000: Variable 'tokudb_analyze_mode' can't be set to the value of '123' +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_standard'; +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_recount_rows'; +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_RECOUNT_ROWS +SHOW VARIABLES LIKE 'tokudb_analyze_mode'; +Variable_name Value +tokudb_analyze_mode TOKUDB_ANALYZE_RECOUNT_ROWS +SET SESSION tokudb_analyze_mode = @orig_session; +SELECT @@session.tokudb_analyze_mode; +@@session.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD +SET GLOBAL tokudb_analyze_mode = @orig_global; +SELECT @@global.tokudb_analyze_mode; +@@global.tokudb_analyze_mode +TOKUDB_ANALYZE_STANDARD diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_throttle_basic.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_throttle_basic.result new file mode 100644 index 0000000000000..34317c7cb7bb3 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_throttle_basic.result @@ -0,0 +1,61 @@ +SET @orig_global = @@global.tokudb_analyze_throttle; +SELECT @orig_global; +@orig_global +0 +SET @orig_session = @@session.tokudb_analyze_throttle; +SELECT @orig_session; +@orig_session +0 +SET GLOBAL tokudb_analyze_throttle = 10; +SELECT @@global.tokudb_analyze_throttle; +@@global.tokudb_analyze_throttle +10 +SET GLOBAL tokudb_analyze_throttle = 0; +SELECT @@global.tokudb_analyze_throttle; +@@global.tokudb_analyze_throttle +0 +SET GLOBAL tokudb_analyze_throttle = DEFAULT; +SELECT @@global.tokudb_analyze_throttle; +@@global.tokudb_analyze_throttle +0 +SET GLOBAL tokudb_analyze_throttle = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_throttle' +SELECT @@global.tokudb_analyze_throttle; +@@global.tokudb_analyze_throttle +0 +SET SESSION tokudb_analyze_throttle = 10; +SELECT @@session.tokudb_analyze_throttle; +@@session.tokudb_analyze_throttle +10 +SET SESSION tokudb_analyze_throttle = 0; +SELECT @@session.tokudb_analyze_throttle; +@@session.tokudb_analyze_throttle +0 +SET SESSION tokudb_analyze_throttle = DEFAULT; +SELECT @@session.tokudb_analyze_throttle; +@@session.tokudb_analyze_throttle +0 +SET SESSION tokudb_analyze_throttle = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_throttle' +SELECT @@session.tokudb_analyze_throttle; +@@session.tokudb_analyze_throttle +0 +SET GLOBAL tokudb_analyze_throttle = 12; +SET SESSION tokudb_analyze_throttle = 13; +SELECT @@global.tokudb_analyze_throttle; +@@global.tokudb_analyze_throttle +12 +SELECT @@session.tokudb_analyze_throttle; +@@session.tokudb_analyze_throttle +13 +SHOW VARIABLES LIKE 'tokudb_analyze_throttle'; +Variable_name Value +tokudb_analyze_throttle 13 +SET SESSION tokudb_analyze_throttle = @orig_session; +SELECT @@session.tokudb_analyze_throttle; +@@session.tokudb_analyze_throttle +0 +SET GLOBAL tokudb_analyze_throttle = @orig_global; +SELECT @@global.tokudb_analyze_throttle; +@@global.tokudb_analyze_throttle +0 diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_time_basic.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_time_basic.result new file mode 100644 index 0000000000000..2eac1fcc3a1f6 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_time_basic.result @@ -0,0 +1,61 @@ +SET @orig_global = @@global.tokudb_analyze_time; +SELECT @orig_global; +@orig_global +5 +SET @orig_session = @@session.tokudb_analyze_time; +SELECT @orig_session; +@orig_session +5 +SET GLOBAL tokudb_analyze_time = 10; +SELECT @@global.tokudb_analyze_time; +@@global.tokudb_analyze_time +10 +SET GLOBAL tokudb_analyze_time = 0; +SELECT @@global.tokudb_analyze_time; +@@global.tokudb_analyze_time +0 +SET GLOBAL tokudb_analyze_time = DEFAULT; +SELECT @@global.tokudb_analyze_time; +@@global.tokudb_analyze_time +5 +SET GLOBAL tokudb_analyze_time = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_time' +SELECT @@global.tokudb_analyze_time; +@@global.tokudb_analyze_time +5 +SET SESSION tokudb_analyze_time = 10; +SELECT @@session.tokudb_analyze_time; +@@session.tokudb_analyze_time +10 +SET SESSION tokudb_analyze_time = 0; +SELECT @@session.tokudb_analyze_time; +@@session.tokudb_analyze_time +0 +SET SESSION tokudb_analyze_time = DEFAULT; +SELECT @@session.tokudb_analyze_time; +@@session.tokudb_analyze_time +5 +SET SESSION tokudb_analyze_time = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_analyze_time' +SELECT @@session.tokudb_analyze_time; +@@session.tokudb_analyze_time +5 +SET GLOBAL tokudb_analyze_time = 12; +SET SESSION tokudb_analyze_time = 13; +SELECT @@global.tokudb_analyze_time; +@@global.tokudb_analyze_time +12 +SELECT @@session.tokudb_analyze_time; +@@session.tokudb_analyze_time +13 +SHOW VARIABLES LIKE 'tokudb_analyze_time'; +Variable_name Value +tokudb_analyze_time 13 +SET SESSION tokudb_analyze_time = @orig_session; +SELECT @@session.tokudb_analyze_time; +@@session.tokudb_analyze_time +5 +SET GLOBAL tokudb_analyze_time = @orig_global; +SELECT @@global.tokudb_analyze_time; +@@global.tokudb_analyze_time +5 diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_auto_analyze.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_auto_analyze.result new file mode 100644 index 0000000000000..5e22bc489cbd0 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_auto_analyze.result @@ -0,0 +1,61 @@ +SET @orig_global = @@global.tokudb_auto_analyze; +SELECT @orig_global; +@orig_global +0 +SET @orig_session = @@session.tokudb_auto_analyze; +SELECT @orig_session; +@orig_session +0 +SET GLOBAL tokudb_auto_analyze = 10; +SELECT @@global.tokudb_auto_analyze; +@@global.tokudb_auto_analyze +10 +SET GLOBAL tokudb_auto_analyze = 0; +SELECT @@global.tokudb_auto_analyze; +@@global.tokudb_auto_analyze +0 +SET GLOBAL tokudb_auto_analyze = DEFAULT; +SELECT @@global.tokudb_auto_analyze; +@@global.tokudb_auto_analyze +0 +SET GLOBAL tokudb_auto_analyze = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_auto_analyze' +SELECT @@global.tokudb_auto_analyze; +@@global.tokudb_auto_analyze +0 +SET SESSION tokudb_auto_analyze = 10; +SELECT @@session.tokudb_auto_analyze; +@@session.tokudb_auto_analyze +10 +SET SESSION tokudb_auto_analyze = 0; +SELECT @@session.tokudb_auto_analyze; +@@session.tokudb_auto_analyze +0 +SET SESSION tokudb_auto_analyze = DEFAULT; +SELECT @@session.tokudb_auto_analyze; +@@session.tokudb_auto_analyze +0 +SET SESSION tokudb_auto_analyze = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_auto_analyze' +SELECT @@session.tokudb_auto_analyze; +@@session.tokudb_auto_analyze +0 +SET GLOBAL tokudb_auto_analyze = 12; +SET SESSION tokudb_auto_analyze = 13; +SELECT @@global.tokudb_auto_analyze; +@@global.tokudb_auto_analyze +12 +SELECT @@session.tokudb_auto_analyze; +@@session.tokudb_auto_analyze +13 +SHOW VARIABLES LIKE 'tokudb_auto_analyze'; +Variable_name Value +tokudb_auto_analyze 13 +SET SESSION tokudb_auto_analyze = @orig_session; +SELECT @@session.tokudb_auto_analyze; +@@session.tokudb_auto_analyze +0 +SET GLOBAL tokudb_auto_analyze = @orig_global; +SELECT @@global.tokudb_auto_analyze; +@@global.tokudb_auto_analyze +0 diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_cardinality_scale_percent_basic.result b/mysql-test/suite/tokudb.sys_vars/r/tokudb_cardinality_scale_percent_basic.result new file mode 100644 index 0000000000000..cac5d8b0dc758 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/r/tokudb_cardinality_scale_percent_basic.result @@ -0,0 +1,36 @@ +SET @orig_global = @@global.tokudb_cardinality_scale_percent; +SELECT @orig_global; +@orig_global +50 +SET GLOBAL tokudb_cardinality_scale_percent = 10; +SELECT @@global.tokudb_cardinality_scale_percent; +@@global.tokudb_cardinality_scale_percent +10 +SET GLOBAL tokudb_cardinality_scale_percent = 0; +SELECT @@global.tokudb_cardinality_scale_percent; +@@global.tokudb_cardinality_scale_percent +0 +SET GLOBAL tokudb_cardinality_scale_percent = DEFAULT; +SELECT @@global.tokudb_cardinality_scale_percent; +@@global.tokudb_cardinality_scale_percent +50 +SET GLOBAL tokudb_cardinality_scale_percent = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_cardinality_scale_percent' +SELECT @@global.tokudb_cardinality_scale_percent; +@@global.tokudb_cardinality_scale_percent +50 +SET GLOBAL tokudb_cardinality_scale_percent = 12; +SET SESSION tokudb_cardinality_scale_percent = 13; +ERROR HY000: Variable 'tokudb_cardinality_scale_percent' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@global.tokudb_cardinality_scale_percent; +@@global.tokudb_cardinality_scale_percent +12 +SELECT @@session.tokudb_cardinality_scale_percent; +ERROR HY000: Variable 'tokudb_cardinality_scale_percent' is a GLOBAL variable +SHOW VARIABLES LIKE 'tokudb_cardinality_scale_percent'; +Variable_name Value +tokudb_cardinality_scale_percent 12 +SET GLOBAL tokudb_cardinality_scale_percent = @orig_global; +SELECT @@global.tokudb_cardinality_scale_percent; +@@global.tokudb_cardinality_scale_percent +50 diff --git a/mysql-test/suite/tokudb.sys_vars/t/suite.opt b/mysql-test/suite/tokudb.sys_vars/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_delete_fraction.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_delete_fraction.test new file mode 100644 index 0000000000000..d5bd382740fe5 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_delete_fraction.test @@ -0,0 +1,56 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_analyze_delete_fraction; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_analyze_delete_fraction; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_analyze_delete_fraction = .5; +SELECT @@global.tokudb_analyze_delete_fraction; + +SET GLOBAL tokudb_analyze_delete_fraction = 0; +SELECT @@global.tokudb_analyze_delete_fraction; + +SET GLOBAL tokudb_analyze_delete_fraction = DEFAULT; +SELECT @@global.tokudb_analyze_delete_fraction; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_analyze_delete_fraction = 'foobar'; +SELECT @@global.tokudb_analyze_delete_fraction; + +SET GLOBAL tokudb_analyze_delete_fraction = 3.75; +SELECT @@global.tokudb_analyze_delete_fraction; + +# Test session +SET SESSION tokudb_analyze_delete_fraction = .5; +SELECT @@session.tokudb_analyze_delete_fraction; + +SET SESSION tokudb_analyze_delete_fraction = 0; +SELECT @@session.tokudb_analyze_delete_fraction; + +SET SESSION tokudb_analyze_delete_fraction = DEFAULT; +SELECT @@session.tokudb_analyze_delete_fraction; + +-- error ER_WRONG_TYPE_FOR_VAR +SET SESSION tokudb_analyze_delete_fraction = 'foobar'; +SELECT @@session.tokudb_analyze_delete_fraction; + +SET SESSION tokudb_analyze_delete_fraction = 3.75; +SELECT @@session.tokudb_analyze_delete_fraction; + +# both +SET GLOBAL tokudb_analyze_delete_fraction = .2; +SET SESSION tokudb_analyze_delete_fraction = .3; +SELECT @@global.tokudb_analyze_delete_fraction; +SELECT @@session.tokudb_analyze_delete_fraction; +SHOW VARIABLES LIKE 'tokudb_analyze_delete_fraction'; + +# Clean up +SET SESSION tokudb_analyze_delete_fraction = @orig_session; +SELECT @@session.tokudb_analyze_delete_fraction; + +SET GLOBAL tokudb_analyze_delete_fraction = @orig_global; +SELECT @@global.tokudb_analyze_delete_fraction; diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_in_background_basic.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_in_background_basic.test new file mode 100644 index 0000000000000..dfb2a0e416dbe --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_in_background_basic.test @@ -0,0 +1,80 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_analyze_in_background; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_analyze_in_background; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_analyze_in_background = 0; +SELECT @@global.tokudb_analyze_in_background; + +SET GLOBAL tokudb_analyze_in_background = 1; +SELECT @@global.tokudb_analyze_in_background; + +SET GLOBAL tokudb_analyze_in_background = DEFAULT; +SELECT @@global.tokudb_analyze_in_background; + +SET GLOBAL tokudb_analyze_in_background = -6; +SELECT @@global.tokudb_analyze_in_background; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_analyze_in_background = 1.6; +SELECT @@global.tokudb_analyze_in_background; + +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL tokudb_analyze_in_background = "T"; +SELECT @@global.tokudb_analyze_in_background; + +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL tokudb_analyze_in_background = "Y"; +SELECT @@global.tokudb_analyze_in_background; + +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL tokudb_analyze_in_background = 'foobar'; +SELECT @@global.tokudb_analyze_in_background; + +# Test session +SET SESSION tokudb_analyze_in_background = 0; +SELECT @@session.tokudb_analyze_in_background; + +SET SESSION tokudb_analyze_in_background = 1; +SELECT @@session.tokudb_analyze_in_background; + +SET SESSION tokudb_analyze_in_background = DEFAULT; +SELECT @@session.tokudb_analyze_in_background; + +SET SESSION tokudb_analyze_in_background = -6; +SELECT @@session.tokudb_analyze_in_background; + +-- error ER_WRONG_TYPE_FOR_VAR +SET SESSION tokudb_analyze_in_background = 1.6; +SELECT @@session.tokudb_analyze_in_background; + +-- error ER_WRONG_VALUE_FOR_VAR +SET SESSION tokudb_analyze_in_background = "T"; +SELECT @@session.tokudb_analyze_in_background; + +-- error ER_WRONG_VALUE_FOR_VAR +SET SESSION tokudb_analyze_in_background = "Y"; +SELECT @@session.tokudb_analyze_in_background; + +-- error ER_WRONG_VALUE_FOR_VAR +SET SESSION tokudb_analyze_in_background = 'foobar'; +SELECT @@session.tokudb_analyze_in_background; + +# both +SET GLOBAL tokudb_analyze_in_background = 0; +SET SESSION tokudb_analyze_in_background = 1; +SELECT @@global.tokudb_analyze_in_background; +SELECT @@session.tokudb_analyze_in_background; +SHOW VARIABLES LIKE 'tokudb_analyze_in_background'; + +# Clean up +SET SESSION tokudb_analyze_in_background = @orig_session; +SELECT @@session.tokudb_analyze_in_background; + +SET GLOBAL tokudb_analyze_in_background = @orig_global; +SELECT @@global.tokudb_analyze_in_background; diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_mode_basic.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_mode_basic.test new file mode 100644 index 0000000000000..69def75bd3de4 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_mode_basic.test @@ -0,0 +1,72 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_analyze_mode; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_analyze_mode; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_standard'; +SELECT @@global.tokudb_analyze_mode; + +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_recount_rows'; +SELECT @@global.tokudb_analyze_mode; + +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_cancel'; +SELECT @@global.tokudb_analyze_mode; + +SET GLOBAL tokudb_analyze_mode = DEFAULT; +SELECT @@global.tokudb_analyze_mode; + +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL tokudb_analyze_mode = ''; +SELECT @@global.tokudb_analyze_mode; + +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL tokudb_analyze_mode = 'foobar'; +SELECT @@global.tokudb_analyze_mode; + +-- error ER_WRONG_VALUE_FOR_VAR +SET GLOBAL tokudb_analyze_mode = 123; +SELECT @@global.tokudb_analyze_mode; + +# Test session +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_standard'; +SELECT @@session.tokudb_analyze_mode; + +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_recount_rows'; +SELECT @@session.tokudb_analyze_mode; + +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_cancel'; +SELECT @@session.tokudb_analyze_mode; + +SET SESSION tokudb_analyze_mode = DEFAULT; +SELECT @@session.tokudb_analyze_mode; + +-- error ER_WRONG_VALUE_FOR_VAR +SET SESSION tokudb_analyze_mode = ''; +SELECT @@session.tokudb_analyze_mode; + +-- error ER_WRONG_VALUE_FOR_VAR +SET SESSION tokudb_analyze_mode = 'foobar'; +SELECT @@session.tokudb_analyze_mode; + +-- error ER_WRONG_VALUE_FOR_VAR +SET SESSION tokudb_analyze_mode = 123; +SELECT @@session.tokudb_analyze_mode; + +# both +SET GLOBAL tokudb_analyze_mode = 'tokudb_analyze_standard'; +SET SESSION tokudb_analyze_mode = 'tokudb_analyze_recount_rows'; +SELECT @@global.tokudb_analyze_mode; +SELECT @@session.tokudb_analyze_mode; +SHOW VARIABLES LIKE 'tokudb_analyze_mode'; + +# Clean up +SET SESSION tokudb_analyze_mode = @orig_session; +SELECT @@session.tokudb_analyze_mode; + +SET GLOBAL tokudb_analyze_mode = @orig_global; +SELECT @@global.tokudb_analyze_mode; diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_throttle_basic.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_throttle_basic.test new file mode 100644 index 0000000000000..a3660b0626a2a --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_throttle_basic.test @@ -0,0 +1,50 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_analyze_throttle; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_analyze_throttle; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_analyze_throttle = 10; +SELECT @@global.tokudb_analyze_throttle; + +SET GLOBAL tokudb_analyze_throttle = 0; +SELECT @@global.tokudb_analyze_throttle; + +SET GLOBAL tokudb_analyze_throttle = DEFAULT; +SELECT @@global.tokudb_analyze_throttle; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_analyze_throttle = 'foobar'; +SELECT @@global.tokudb_analyze_throttle; + +# Test session +SET SESSION tokudb_analyze_throttle = 10; +SELECT @@session.tokudb_analyze_throttle; + +SET SESSION tokudb_analyze_throttle = 0; +SELECT @@session.tokudb_analyze_throttle; + +SET SESSION tokudb_analyze_throttle = DEFAULT; +SELECT @@session.tokudb_analyze_throttle; + +-- error ER_WRONG_TYPE_FOR_VAR +SET SESSION tokudb_analyze_throttle = 'foobar'; +SELECT @@session.tokudb_analyze_throttle; + +# both +SET GLOBAL tokudb_analyze_throttle = 12; +SET SESSION tokudb_analyze_throttle = 13; +SELECT @@global.tokudb_analyze_throttle; +SELECT @@session.tokudb_analyze_throttle; +SHOW VARIABLES LIKE 'tokudb_analyze_throttle'; + +# Clean up +SET SESSION tokudb_analyze_throttle = @orig_session; +SELECT @@session.tokudb_analyze_throttle; + +SET GLOBAL tokudb_analyze_throttle = @orig_global; +SELECT @@global.tokudb_analyze_throttle; diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_time_basic.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_time_basic.test new file mode 100644 index 0000000000000..3098934ee8cae --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_time_basic.test @@ -0,0 +1,50 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_analyze_time; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_analyze_time; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_analyze_time = 10; +SELECT @@global.tokudb_analyze_time; + +SET GLOBAL tokudb_analyze_time = 0; +SELECT @@global.tokudb_analyze_time; + +SET GLOBAL tokudb_analyze_time = DEFAULT; +SELECT @@global.tokudb_analyze_time; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_analyze_time = 'foobar'; +SELECT @@global.tokudb_analyze_time; + +# Test session +SET SESSION tokudb_analyze_time = 10; +SELECT @@session.tokudb_analyze_time; + +SET SESSION tokudb_analyze_time = 0; +SELECT @@session.tokudb_analyze_time; + +SET SESSION tokudb_analyze_time = DEFAULT; +SELECT @@session.tokudb_analyze_time; + +-- error ER_WRONG_TYPE_FOR_VAR +SET SESSION tokudb_analyze_time = 'foobar'; +SELECT @@session.tokudb_analyze_time; + +# both +SET GLOBAL tokudb_analyze_time = 12; +SET SESSION tokudb_analyze_time = 13; +SELECT @@global.tokudb_analyze_time; +SELECT @@session.tokudb_analyze_time; +SHOW VARIABLES LIKE 'tokudb_analyze_time'; + +# Clean up +SET SESSION tokudb_analyze_time = @orig_session; +SELECT @@session.tokudb_analyze_time; + +SET GLOBAL tokudb_analyze_time = @orig_global; +SELECT @@global.tokudb_analyze_time; diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_auto_analyze.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_auto_analyze.test new file mode 100644 index 0000000000000..d9998508ae18d --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_auto_analyze.test @@ -0,0 +1,50 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_auto_analyze; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_auto_analyze; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_auto_analyze = 10; +SELECT @@global.tokudb_auto_analyze; + +SET GLOBAL tokudb_auto_analyze = 0; +SELECT @@global.tokudb_auto_analyze; + +SET GLOBAL tokudb_auto_analyze = DEFAULT; +SELECT @@global.tokudb_auto_analyze; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_auto_analyze = 'foobar'; +SELECT @@global.tokudb_auto_analyze; + +# Test session +SET SESSION tokudb_auto_analyze = 10; +SELECT @@session.tokudb_auto_analyze; + +SET SESSION tokudb_auto_analyze = 0; +SELECT @@session.tokudb_auto_analyze; + +SET SESSION tokudb_auto_analyze = DEFAULT; +SELECT @@session.tokudb_auto_analyze; + +-- error ER_WRONG_TYPE_FOR_VAR +SET SESSION tokudb_auto_analyze = 'foobar'; +SELECT @@session.tokudb_auto_analyze; + +# both +SET GLOBAL tokudb_auto_analyze = 12; +SET SESSION tokudb_auto_analyze = 13; +SELECT @@global.tokudb_auto_analyze; +SELECT @@session.tokudb_auto_analyze; +SHOW VARIABLES LIKE 'tokudb_auto_analyze'; + +# Clean up +SET SESSION tokudb_auto_analyze = @orig_session; +SELECT @@session.tokudb_auto_analyze; + +SET GLOBAL tokudb_auto_analyze = @orig_global; +SELECT @@global.tokudb_auto_analyze; diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_cardinality_scale_percent_basic.test b/mysql-test/suite/tokudb.sys_vars/t/tokudb_cardinality_scale_percent_basic.test new file mode 100644 index 0000000000000..83063f0424882 --- /dev/null +++ b/mysql-test/suite/tokudb.sys_vars/t/tokudb_cardinality_scale_percent_basic.test @@ -0,0 +1,32 @@ +--source include/have_tokudb.inc + +# Check the default value +SET @orig_global = @@global.tokudb_cardinality_scale_percent; +SELECT @orig_global; + +# Test global +SET GLOBAL tokudb_cardinality_scale_percent = 10; +SELECT @@global.tokudb_cardinality_scale_percent; + +SET GLOBAL tokudb_cardinality_scale_percent = 0; +SELECT @@global.tokudb_cardinality_scale_percent; + +SET GLOBAL tokudb_cardinality_scale_percent = DEFAULT; +SELECT @@global.tokudb_cardinality_scale_percent; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_cardinality_scale_percent = 'foobar'; +SELECT @@global.tokudb_cardinality_scale_percent; + +# both +SET GLOBAL tokudb_cardinality_scale_percent = 12; +-- error ER_GLOBAL_VARIABLE +SET SESSION tokudb_cardinality_scale_percent = 13; +SELECT @@global.tokudb_cardinality_scale_percent; +-- error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.tokudb_cardinality_scale_percent; +SHOW VARIABLES LIKE 'tokudb_cardinality_scale_percent'; + +# Clean up +SET GLOBAL tokudb_cardinality_scale_percent = @orig_global; +SELECT @@global.tokudb_cardinality_scale_percent; diff --git a/mysql-test/suite/tokudb/r/background_job_manager.result b/mysql-test/suite/tokudb/r/background_job_manager.result new file mode 100644 index 0000000000000000000000000000000000000000..c66872d7b0f088068bc403113e9c87abd416d33f GIT binary patch literal 6893 zcmeHLZI7ci5WcVQEBtL)iLOYpt*S;y%Oz}YbxEj*qw4yF7;v&QyhO(In*REZdD#HV zW|OGu-nNN|u$dRzGtZ32PANxs2@BQ^$#~+Bn1s8(DALj0T}sn5Na7owY%c6fQdhDiSxReW zc79J>Cjw`!DeIV+Pu*>p${|c}0wO$QT%BP&f zKG^!;AeF;)?JyhoxMC^1iOSJl^rk*G?~TO-7kZmQuUlHj_QC|w$K)&W7$uw{PFw(Q z5U&yz5e^{+=y{|Osc^Lqr`*r5e4eF484EFKROrY%GKSC`e{2Jz5RgW;X3s4E!Z>0{|*lv}-i8Fq$nU6I2=kU1?XUVDkwqg#a>R64534 zgD~%rFs1+f4_!iqOuqP21O(LiZhNeL!M-JoMCp+e61MlVkg`4hp#SpxD|X-E0Hq}Y z8&J{evXZ80-{lX|w4d^)umL!Tar#U{WnN+H+`fe)_w&jPTj!FmkvaSMVP@)6b83N$ zE8^&rVb4vhXMFXe+<+bLA%y_=IEoYaXJLr)%pb(S7D1v@kt@h5@`~4%1rcF8w4pnN zT&v=ZHm>4UO;7QvCUHH5sIFT3Ao>*j0^n<;=TMUpeM{|s%WYP{7O&l ziC16ki`PIMfK*CD>TzN5J?hjVnsPv?sKQFoDqx_Z%4H0#SQ5dgCk9?)Kxq$PsTwYC z6r)K`gUOtxT;e?mTb~yYq{hsceEH3ErqAf4k z5d4Oyr3F7sO~_-KWD zSzBqEuJa%*8uU+|ul@#BUkXWOQnFw>&2t`FkszeL+)~=F^4tNX{bx!)x77@eP&0U4 z&Fv9tZadUmkh;hF(MT=grQZ&Te=S}XbJPA%M(yC6n8ocI&q5UWC)Ydo#$+xEo^xc2 zTB(&1AXlA{XP%{mOJ>Qdod4GzSdZyTX4&Vrx6Uji_q2@3H{A6g>jICjy624=z5r!;-IXNAnMr zE*JQmbbhGs@^8Jf9Xj>f=Ez#iuwz@l&fBFuuASVA^_&PqIAFhiOWL@D7x$noz@B?< newTp#??A<8$@Zz58p`!9>|pgSIJn-03yyc@y0gxe<(c$vR|D>( literal 0 HcmV?d00001 diff --git a/mysql-test/suite/tokudb/r/card_add_drop.result b/mysql-test/suite/tokudb/r/card_add_drop.result index 431f0200a7a1f..71a39eb1f3eb1 100644 --- a/mysql-test/suite/tokudb/r/card_add_drop.result +++ b/mysql-test/suite/tokudb/r/card_add_drop.result @@ -4,35 +4,35 @@ create table tt (a int, b int, c int, d int, key(a), key(b), key(c)); insert into tt values (0,0,0,0),(1,0,0,0),(2,0,1,0),(3,0,1,0); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 a 1 a A NULL NULL NULL YES BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 a 1 a A 4 NULL NULL YES BTREE +tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 1 a 1 a A 4 NULL NULL YES BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE alter table tt drop key b, add key (d); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 1 a 1 a A 4 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE -tt 1 d 1 d A NULL NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE +tt 1 d 1 d A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 1 a 1 a A 4 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE -tt 1 d 1 d A 1 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE +tt 1 d 1 d A 2 NULL NULL YES BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 1 a 1 a A 4 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE -tt 1 d 1 d A 1 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE +tt 1 d 1 d A 2 NULL NULL YES BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/card_add_index.result b/mysql-test/suite/tokudb/r/card_add_index.result index f5ba5b58bed2d..9a929b19a80f7 100644 --- a/mysql-test/suite/tokudb/r/card_add_index.result +++ b/mysql-test/suite/tokudb/r/card_add_index.result @@ -15,32 +15,32 @@ alter table tt add key (b); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE alter table tt add key (c); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/card_auto_analyze_lots.result b/mysql-test/suite/tokudb/r/card_auto_analyze_lots.result new file mode 100644 index 0000000000000..c665ef758a459 --- /dev/null +++ b/mysql-test/suite/tokudb/r/card_auto_analyze_lots.result @@ -0,0 +1,800 @@ +SHOW INDEX FROM ar_200; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_200 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_200 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_199; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_199 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_199 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_198; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_198 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_198 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_197; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_197 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_197 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_196; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_196 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_196 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_195; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_195 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_195 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_194; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_194 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_194 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_193; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_193 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_193 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_192; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_192 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_192 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_191; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_191 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_191 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_190; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_190 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_190 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_189; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_189 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_189 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_188; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_188 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_188 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_187; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_187 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_187 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_186; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_186 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_186 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_185; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_185 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_185 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_184; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_184 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_184 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_183; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_183 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_183 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_182; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_182 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_182 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_181; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_181 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_181 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_180; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_180 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_180 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_179; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_179 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_179 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_178; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_178 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_178 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_177; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_177 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_177 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_176; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_176 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_176 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_175; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_175 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_175 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_174; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_174 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_174 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_173; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_173 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_173 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_172; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_172 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_172 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_171; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_171 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_171 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_170; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_170 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_170 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_169; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_169 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_169 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_168; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_168 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_168 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_167; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_167 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_167 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_166; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_166 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_166 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_165; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_165 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_165 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_164; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_164 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_164 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_163; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_163 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_163 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_162; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_162 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_162 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_161; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_161 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_161 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_160; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_160 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_160 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_159; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_159 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_159 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_158; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_158 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_158 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_157; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_157 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_157 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_156; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_156 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_156 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_155; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_155 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_155 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_154; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_154 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_154 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_153; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_153 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_153 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_152; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_152 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_152 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_151; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_151 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_151 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_150; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_150 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_150 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_149; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_149 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_149 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_148; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_148 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_148 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_147; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_147 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_147 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_146; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_146 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_146 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_145; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_145 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_145 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_144; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_144 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_144 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_143; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_143 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_143 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_142; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_142 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_142 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_141; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_141 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_141 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_140; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_140 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_140 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_139; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_139 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_139 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_138; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_138 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_138 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_137; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_137 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_137 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_136; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_136 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_136 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_135; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_135 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_135 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_134; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_134 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_134 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_133; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_133 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_133 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_132; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_132 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_132 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_131; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_131 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_131 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_130; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_130 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_130 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_129; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_129 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_129 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_128; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_128 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_128 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_127; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_127 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_127 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_126; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_126 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_126 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_125; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_125 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_125 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_124; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_124 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_124 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_123; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_123 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_123 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_122; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_122 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_122 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_121; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_121 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_121 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_120; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_120 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_120 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_119; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_119 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_119 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_118; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_118 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_118 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_117; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_117 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_117 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_116; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_116 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_116 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_115; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_115 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_115 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_114; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_114 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_114 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_113; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_113 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_113 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_112; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_112 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_112 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_111; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_111 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_111 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_110; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_110 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_110 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_109; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_109 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_109 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_108; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_108 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_108 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_107; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_107 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_107 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_106; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_106 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_106 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_105; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_105 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_105 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_104; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_104 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_104 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_103; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_103 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_103 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_102; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_102 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_102 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_101; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_101 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_101 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_100; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_100 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_100 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_99; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_99 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_99 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_98; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_98 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_98 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_97; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_97 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_97 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_96; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_96 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_96 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_95; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_95 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_95 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_94; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_94 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_94 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_93; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_93 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_93 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_92; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_92 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_92 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_91; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_91 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_91 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_90; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_90 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_90 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_89; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_89 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_89 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_88; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_88 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_88 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_87; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_87 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_87 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_86; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_86 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_86 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_85; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_85 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_85 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_84; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_84 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_84 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_83; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_83 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_83 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_82; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_82 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_82 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_81; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_81 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_81 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_80; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_80 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_80 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_79; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_79 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_79 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_78; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_78 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_78 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_77; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_77 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_77 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_76; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_76 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_76 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_75; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_75 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_75 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_74; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_74 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_74 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_73; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_73 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_73 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_72; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_72 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_72 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_71; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_71 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_71 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_70; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_70 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_70 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_69; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_69 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_69 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_68; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_68 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_68 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_67; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_67 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_67 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_66; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_66 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_66 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_65; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_65 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_65 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_64; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_64 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_64 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_63; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_63 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_63 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_62; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_62 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_62 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_61; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_61 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_61 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_60; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_60 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_60 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_59; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_59 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_59 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_58; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_58 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_58 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_57; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_57 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_57 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_56; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_56 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_56 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_55; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_55 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_55 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_54; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_54 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_54 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_53; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_53 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_53 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_52; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_52 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_52 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_51; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_51 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_51 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_50; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_50 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_50 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_49; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_49 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_49 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_48; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_48 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_48 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_47; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_47 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_47 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_46; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_46 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_46 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_45; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_45 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_45 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_44; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_44 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_44 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_43; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_43 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_43 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_42; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_42 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_42 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_41; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_41 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_41 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_40; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_40 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_40 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_39; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_39 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_39 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_38; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_38 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_38 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_37; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_37 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_37 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_36; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_36 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_36 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_35; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_35 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_35 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_34; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_34 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_34 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_33; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_33 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_33 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_32; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_32 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_32 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_31; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_31 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_31 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_30; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_30 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_30 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_29; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_29 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_29 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_28; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_28 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_28 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_27; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_27 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_27 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_26; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_26 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_26 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_25; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_25 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_25 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_24; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_24 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_24 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_23; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_23 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_23 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_22; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_22 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_22 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_21; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_21 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_21 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_20; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_20 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_20 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_19; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_19 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_19 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_18; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_18 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_18 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_17; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_17 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_17 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_16; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_16 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_16 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_15; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_15 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_15 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_14; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_14 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_14 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_13; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_13 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_13 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_12; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_12 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_12 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_11; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_11 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_11 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_10; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_10 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_10 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_9; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_9 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_9 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_8; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_8 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_8 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_7; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_7 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_7 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_6; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_6 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_6 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_5; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_5 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_5 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_4; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_4 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_4 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_3; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_3 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_3 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_2 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_2 1 bkey 1 b A 1 NULL NULL YES BTREE +SHOW INDEX FROM ar_1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +ar_1 0 PRIMARY 1 a A 1 NULL NULL BTREE +ar_1 1 bkey 1 b A 1 NULL NULL YES BTREE diff --git a/mysql-test/suite/tokudb/r/card_drop_index.result b/mysql-test/suite/tokudb/r/card_drop_index.result index 9fc8fb6a6b8b4..2cfdfe11296e4 100644 --- a/mysql-test/suite/tokudb/r/card_drop_index.result +++ b/mysql-test/suite/tokudb/r/card_drop_index.result @@ -5,21 +5,21 @@ insert into tt values (1,0,0),(2,0,0),(3,0,1),(4,0,1); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE alter table tt drop key b; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE alter table tt drop key c; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment diff --git a/mysql-test/suite/tokudb/r/card_drop_index_2.result b/mysql-test/suite/tokudb/r/card_drop_index_2.result index 4103a37a6ed63..ed28d2a322626 100644 --- a/mysql-test/suite/tokudb/r/card_drop_index_2.result +++ b/mysql-test/suite/tokudb/r/card_drop_index_2.result @@ -132,21 +132,21 @@ count(*) show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 500 NULL NULL BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 b 1 b A 500 NULL NULL YES BTREE +tt 1 c 1 c A 500 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 500 NULL NULL BTREE -tt 1 b 1 b A 125 NULL NULL YES BTREE -tt 1 c 1 c A 1 NULL NULL YES BTREE +tt 1 b 1 b A 250 NULL NULL YES BTREE +tt 1 c 1 c A 2 NULL NULL YES BTREE alter table tt drop key b; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 500 NULL NULL BTREE -tt 1 c 1 c A 1 NULL NULL YES BTREE +tt 1 c 1 c A 2 NULL NULL YES BTREE alter table tt drop key c; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment diff --git a/mysql-test/suite/tokudb/r/card_drop_pk.result b/mysql-test/suite/tokudb/r/card_drop_pk.result index bdbd9a3f09722..2369d88c27492 100644 --- a/mysql-test/suite/tokudb/r/card_drop_pk.result +++ b/mysql-test/suite/tokudb/r/card_drop_pk.result @@ -5,24 +5,24 @@ insert into tt values (1,0,0),(2,0,0),(3,0,1),(4,0,1); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE -tt 1 c 1 c A 2 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE alter table tt drop primary key; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 b 1 b A NULL NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 b 1 b A NULL NULL NULL YES BTREE -tt 1 c 1 c A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 c 1 c A 4 NULL NULL YES BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/card_pk_2.result b/mysql-test/suite/tokudb/r/card_pk_2.result index dd850df9a8977..3c1b652db15f5 100644 --- a/mysql-test/suite/tokudb/r/card_pk_2.result +++ b/mysql-test/suite/tokudb/r/card_pk_2.result @@ -4,18 +4,18 @@ create table tt (a int, b int, primary key(a,b)); insert into tt values (0,0),(0,1),(1,0),(1,1); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 0 PRIMARY 1 a A NULL NULL NULL BTREE +tt 0 PRIMARY 1 a A 4 NULL NULL BTREE tt 0 PRIMARY 2 b A 4 NULL NULL BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 0 PRIMARY 1 a A 2 NULL NULL BTREE +tt 0 PRIMARY 1 a A 4 NULL NULL BTREE tt 0 PRIMARY 2 b A 4 NULL NULL BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 0 PRIMARY 1 a A 2 NULL NULL BTREE +tt 0 PRIMARY 1 a A 4 NULL NULL BTREE tt 0 PRIMARY 2 b A 4 NULL NULL BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/card_pk_sk.result b/mysql-test/suite/tokudb/r/card_pk_sk.result index 5458f19de3202..02c8d1f821826 100644 --- a/mysql-test/suite/tokudb/r/card_pk_sk.result +++ b/mysql-test/suite/tokudb/r/card_pk_sk.result @@ -1004,7 +1004,7 @@ insert into tt values (4*999,4*999+1),(4*999+1,4*999+2),(4*999+2,4*999+3),(4*999 show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4000 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK @@ -2022,17 +2022,17 @@ insert into tt values (4*999,0),(4*999+1,0),(4*999+2,0),(4*999+3,0); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE -tt 1 b 1 b A NULL NULL NULL YES BTREE +tt 1 b 1 b A 4000 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE -tt 1 b 1 b A 1 NULL NULL YES BTREE +tt 1 b 1 b A 2 NULL NULL YES BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/card_scale_percent.result b/mysql-test/suite/tokudb/r/card_scale_percent.result new file mode 100644 index 0000000000000..cfd7e38179cbe --- /dev/null +++ b/mysql-test/suite/tokudb/r/card_scale_percent.result @@ -0,0 +1,42 @@ +set global tokudb_cardinality_scale_percent = 10; +analyze table tt; +Table Op Msg_type Msg_text +test.tt analyze status OK +show indexes from tt; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE +tt 1 b 1 b A 4000 NULL NULL YES BTREE +tt 1 c 1 c A 4000 NULL NULL YES BTREE +tt 1 d 1 d A 4000 NULL NULL YES BTREE +set global tokudb_cardinality_scale_percent = 50; +analyze table tt; +Table Op Msg_type Msg_text +test.tt analyze status OK +show indexes from tt; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE +tt 1 b 1 b A 4000 NULL NULL YES BTREE +tt 1 c 1 c A 4000 NULL NULL YES BTREE +tt 1 d 1 d A 2000 NULL NULL YES BTREE +set global tokudb_cardinality_scale_percent = 100; +analyze table tt; +Table Op Msg_type Msg_text +test.tt analyze status OK +show indexes from tt; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE +tt 1 b 1 b A 4000 NULL NULL YES BTREE +tt 1 c 1 c A 2000 NULL NULL YES BTREE +tt 1 d 1 d A 1000 NULL NULL YES BTREE +set global tokudb_cardinality_scale_percent = 200; +Warnings: +Warning 1292 Truncated incorrect tokudb_cardinality_scale_percent value: '200' +analyze table tt; +Table Op Msg_type Msg_text +test.tt analyze status OK +show indexes from tt; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment +tt 0 PRIMARY 1 a A 4000 NULL NULL BTREE +tt 1 b 1 b A 4000 NULL NULL YES BTREE +tt 1 c 1 c A 2000 NULL NULL YES BTREE +tt 1 d 1 d A 1000 NULL NULL YES BTREE diff --git a/mysql-test/suite/tokudb/r/card_sk.result b/mysql-test/suite/tokudb/r/card_sk.result index 1846b4e82bc98..310fc863a9b0e 100644 --- a/mysql-test/suite/tokudb/r/card_sk.result +++ b/mysql-test/suite/tokudb/r/card_sk.result @@ -5,15 +5,15 @@ insert into tt values (1,0),(2,1),(3,2),(4,3); insert into tt values (5,0),(6,1),(7,2),(8,3); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 b 1 b A NULL NULL NULL YES BTREE +tt 1 b 1 b A 8 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 b 1 b A 8 NULL NULL YES BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 b 1 b A 4 NULL NULL YES BTREE +tt 1 b 1 b A 8 NULL NULL YES BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/card_sk_2.result b/mysql-test/suite/tokudb/r/card_sk_2.result index c087bad3b185f..8ff57b63e5d47 100644 --- a/mysql-test/suite/tokudb/r/card_sk_2.result +++ b/mysql-test/suite/tokudb/r/card_sk_2.result @@ -4,18 +4,18 @@ create table tt (a int, b int, key(a,b)); insert into tt values (0,0),(0,1),(1,0),(1,1); show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 a 1 a A NULL NULL NULL YES BTREE -tt 1 a 2 b A NULL NULL NULL YES BTREE +tt 1 a 1 a A 4 NULL NULL YES BTREE +tt 1 a 2 b A 4 NULL NULL YES BTREE analyze table tt; Table Op Msg_type Msg_text test.tt analyze status OK show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 a 1 a A 2 NULL NULL YES BTREE +tt 1 a 1 a A 4 NULL NULL YES BTREE tt 1 a 2 b A 4 NULL NULL YES BTREE flush tables; show indexes from tt; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -tt 1 a 1 a A 2 NULL NULL YES BTREE +tt 1 a 1 a A 4 NULL NULL YES BTREE tt 1 a 2 b A 4 NULL NULL YES BTREE drop table tt; diff --git a/mysql-test/suite/tokudb/r/cluster_2968-0.result b/mysql-test/suite/tokudb/r/cluster_2968-0.result index 954d93b5f7310..e1effd0aba890 100644 --- a/mysql-test/suite/tokudb/r/cluster_2968-0.result +++ b/mysql-test/suite/tokudb/r/cluster_2968-0.result @@ -1042,5 +1042,5 @@ t CREATE TABLE `t` ( explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b b 5 NULL 1000 Using where -1 SIMPLE t ref b b 5 test.s.b 11 NULL +1 SIMPLE t ref b b 5 test.s.b 1 NULL drop table s,t; diff --git a/mysql-test/suite/tokudb/r/cluster_2968-1.result b/mysql-test/suite/tokudb/r/cluster_2968-1.result index 903504db389b5..8c0b64217ca62 100644 --- a/mysql-test/suite/tokudb/r/cluster_2968-1.result +++ b/mysql-test/suite/tokudb/r/cluster_2968-1.result @@ -1042,7 +1042,7 @@ t CREATE TABLE `t` ( explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b NULL NULL NULL 1000 Using where -1 SIMPLE t ref b b 5 test.s.b 11 NULL +1 SIMPLE t ref b b 5 test.s.b 1 NULL alter table s add clustering key(b); alter table t add clustering key(b); show create table s; @@ -1066,7 +1066,7 @@ t CREATE TABLE `t` ( explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2 b_2 5 NULL 1000 Using where -1 SIMPLE t ref b,b_2 b_2 5 test.s.b 11 NULL +1 SIMPLE t ref b,b_2 b 5 test.s.b 1 NULL alter table s drop key b; alter table t drop key b; show create table s; @@ -1088,7 +1088,7 @@ t CREATE TABLE `t` ( explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b_2 b_2 5 NULL 1000 Using where -1 SIMPLE t ref b_2 b_2 5 test.s.b 11 NULL +1 SIMPLE t ref b_2 b_2 5 test.s.b 1 NULL alter table s add key(b); alter table t add key(b); show create table s; @@ -1112,5 +1112,5 @@ t CREATE TABLE `t` ( explain select straight_join * from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b_2,b b_2 5 NULL 1000 Using where -1 SIMPLE t ref b_2,b b_2 5 test.s.b 11 NULL +1 SIMPLE t ref b_2,b b 5 test.s.b 1 NULL drop table s,t; diff --git a/mysql-test/suite/tokudb/r/cluster_2968-2.result b/mysql-test/suite/tokudb/r/cluster_2968-2.result index 854226a14f88d..63718aa2fdaf3 100644 --- a/mysql-test/suite/tokudb/r/cluster_2968-2.result +++ b/mysql-test/suite/tokudb/r/cluster_2968-2.result @@ -1042,7 +1042,7 @@ t CREATE TABLE `t` ( explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b NULL NULL NULL 1000 Using where -1 SIMPLE t ref b b 5 test.s.b 11 NULL +1 SIMPLE t ref b b 5 test.s.b 1 NULL alter table s add key(b,a); alter table t add key(b,a); show create table s; @@ -1066,7 +1066,7 @@ t CREATE TABLE `t` ( explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2 b_2 10 NULL 1000 Using where; Using index -1 SIMPLE t ref b,b_2 b_2 5 test.s.b 11 Using index +1 SIMPLE t ref b,b_2 b 5 test.s.b 1 NULL alter table s add clustering key(b); alter table t add clustering key(b); show create table s; @@ -1092,7 +1092,7 @@ t CREATE TABLE `t` ( explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2,b_3 b_2 10 NULL 1000 Using where; Using index -1 SIMPLE t ref b,b_2,b_3 b_2 5 test.s.b 11 Using index +1 SIMPLE t ref b,b_2,b_3 b 5 test.s.b 1 NULL alter table s drop key b_2; alter table t drop key b_2; show create table s; @@ -1116,5 +1116,5 @@ t CREATE TABLE `t` ( explain select straight_join s.a,t.a from s,t where s.b = t.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_3 b_3 5 NULL 1000 Using where -1 SIMPLE t ref b,b_3 b_3 5 test.s.b 11 NULL +1 SIMPLE t ref b,b_3 b 5 test.s.b 1 NULL drop table s,t; diff --git a/mysql-test/suite/tokudb/r/cluster_2968-3.result b/mysql-test/suite/tokudb/r/cluster_2968-3.result index 5a2fbf2ccc28d..adc542cd14b32 100644 --- a/mysql-test/suite/tokudb/r/cluster_2968-3.result +++ b/mysql-test/suite/tokudb/r/cluster_2968-3.result @@ -1062,8 +1062,8 @@ u CREATE TABLE `u` ( explain select straight_join * from s,t,u where s.b = t.b and s.c = u.c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s ALL b NULL NULL NULL 1000 Using where -1 SIMPLE t ref b b 5 test.s.b 11 NULL -1 SIMPLE u ref c c 5 test.s.c 11 NULL +1 SIMPLE t ref b b 5 test.s.b 1 NULL +1 SIMPLE u ref c c 5 test.s.c 1 NULL alter table s add clustering key (b); alter table t add clustering key (b); alter table u add clustering key (c); @@ -1097,6 +1097,6 @@ u CREATE TABLE `u` ( explain select straight_join * from s,t,u where s.b = t.b and s.c = u.c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE s index b,b_2 b_2 5 NULL 1000 Using where -1 SIMPLE t ref b,b_2 b_2 5 test.s.b 11 NULL -1 SIMPLE u ref c,c_2 c_2 5 test.s.c 11 NULL +1 SIMPLE t ref b,b_2 b 5 test.s.b 1 NULL +1 SIMPLE u ref c,c_2 c 5 test.s.c 1 NULL drop table s,t,u; diff --git a/mysql-test/suite/tokudb/r/type_bit.result b/mysql-test/suite/tokudb/r/type_bit.result index d6a82e4cf29b0..f3285b8c3e58c 100644 --- a/mysql-test/suite/tokudb/r/type_bit.result +++ b/mysql-test/suite/tokudb/r/type_bit.result @@ -675,7 +675,7 @@ INSERT INTO t1(a) VALUES (65535),(65525),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535); EXPLAIN SELECT 1 FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 3 NULL 6 Using index for group-by +1 SIMPLE t1 index a a 3 NULL 10 Using index SELECT 1 FROM t1 GROUP BY a; 1 1 diff --git a/mysql-test/suite/tokudb/t/background_job_manager.test b/mysql-test/suite/tokudb/t/background_job_manager.test new file mode 100644 index 0000000000000..933814442e042 --- /dev/null +++ b/mysql-test/suite/tokudb/t/background_job_manager.test @@ -0,0 +1,139 @@ +# This is a comprehensive test for the background job manager and +# the information_schema.tokudb_background_job_status table +# +# This test validates that analyze table in various modes operate as expected +# for both foreground and background jobs. +# +# This test is NOT intended to test the actual results of an analysis. +# +# This test makes use of a global, debug only tokudb variable +# tokudb_debug_pause_background_job_manager in order to control the bjm and +# prevent it from acting on any queued jobs. +# This variable was necessary since the debug_sync facility requires any thread +# that is syncing to have a valid THD associated with it, which a background +# thread would not have. This variable is compiled out of release builds. + +-- source include/have_tokudb.inc +-- source include/have_debug.inc + +-- enable_query_log + +set @orig_auto_analyze = @@session.tokudb_auto_analyze; +set @orig_in_background = @@session.tokudb_analyze_in_background; +set @orig_mode = @@session.tokudb_analyze_mode; +set @orig_throttle = @@session.tokudb_analyze_throttle; +set @orig_time = @@session.tokudb_analyze_time; +set @orig_scale_percent = @@global.tokudb_cardinality_scale_percent; +set @orig_default_storage_engine = @@session.default_storage_engine; +set @orig_pause_background_job_manager = @@global.tokudb_debug_pause_background_job_manager; + +# first, lets set up to auto analyze in the background with about any activity +set session default_storage_engine='tokudb'; +set session tokudb_auto_analyze=1; +set session tokudb_analyze_in_background=1; +set session tokudb_analyze_mode=tokudb_analyze_standard; +set session tokudb_analyze_throttle=0; +set session tokudb_analyze_time=0; +set global tokudb_cardinality_scale_percent=DEFAULT; + +# in debug build, we can prevent the background job manager from running, +# let's do it so we can see that there was an analyze scheduled on the first +# insert +set global tokudb_debug_pause_background_job_manager=TRUE; + +# let's see what the i_s table is laid out like +show create table information_schema.tokudb_background_job_status; + +create table t1 (a int not null auto_increment, b int, c int, primary key(a), key kb(b), key kc(c), key kabc(a,b,c), key kab(a,b), key kbc(b,c)); + +insert into t1(b,c) values(0,0), (1,1), (2,2), (3,3); + +# insert above should have triggered an analyze, but since the bjm is paused, +# we will see it sitting in the queue +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# some more tables +create table t2 like t1; +create table t3 like t1; +create table t4 like t1; + +# manually analyze, the t1 should be rejected because there is already a job +# pending. t2, t3 and t4 should get queued. +analyze table t1; +analyze table t2; +analyze table t3; +analyze table t4; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# let the bjm go to clear the jobs +set global tokudb_debug_pause_background_job_manager=FALSE; + +# wait for the bjm queue to empty +-- disable_query_log +let $wait_condition=select count(*)=0 from information_schema.tokudb_background_job_status; +-- source include/wait_condition.inc +-- enable_query_log + +# pause the bjm again +set global tokudb_debug_pause_background_job_manager=TRUE; + +# add some new jobs +analyze table t1; +analyze table t2; +analyze table t3; +analyze table t4; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# alter a table, should kill the job for t1 +alter table t1 add column d int; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# try an explicit cancel on t2 +set session tokudb_analyze_mode=tokudb_analyze_cancel; +analyze table t2; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# try a recount on t1, should reschedule a new job +set session tokudb_analyze_mode=tokudb_analyze_recount_rows; +analyze table t1; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# do a foreground analysis that clashes with a background job, it should +# kill the background job for t3 and perform the analysis immediately +set session tokudb_analyze_mode=tokudb_analyze_standard; +set session tokudb_analyze_in_background=0; +analyze table t3; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# drop the tables, should kill the remaining jobs for t1, and t4 +drop table t1; +drop table t2; +drop table t3; +drop table t4; + +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# let the bjm go +set global tokudb_debug_pause_background_job_manager=FALSE; + +#cleanup +-- disable_query_log +let $wait_condition=select count(*)=0 from information_schema.tokudb_background_job_status; +-- source include/wait_condition.inc + +set session tokudb_auto_analyze = @orig_auto_analyze; +set session tokudb_analyze_in_background = @orig_in_background; +set session tokudb_analyze_mode = @orig_mode; +set session tokudb_analyze_throttle = @orig_throttle; +set session tokudb_analyze_time = @orig_time; +set global tokudb_cardinality_scale_percent = @orig_scale_percent; +set session default_storage_engine = @orig_default_storage_engine; +set global tokudb_debug_pause_background_job_manager = @orig_pause_background_job_manager; + +-- enable_query_log diff --git a/mysql-test/suite/tokudb/t/card_auto_analyze_lots.test b/mysql-test/suite/tokudb/t/card_auto_analyze_lots.test new file mode 100644 index 0000000000000..ec74a4a28bc68 --- /dev/null +++ b/mysql-test/suite/tokudb/t/card_auto_analyze_lots.test @@ -0,0 +1,82 @@ +# Test the auto analyze on lots of tables +-- source include/have_tokudb.inc + +-- disable_query_log +let $max = 200; + +SET @orig_auto_analyze = @@session.tokudb_auto_analyze; +SET @orig_in_background = @@session.tokudb_analyze_in_background; +SET @orig_mode = @@session.tokudb_analyze_mode; +SET @orig_throttle = @@session.tokudb_analyze_throttle; +SET @orig_time = @@session.tokudb_analyze_time; + +SET SESSION tokudb_auto_analyze = 1; +SET SESSION tokudb_analyze_in_background = 0; +SET SESSION tokudb_analyze_mode = TOKUDB_ANALYZE_STANDARD; +SET SESSION tokudb_analyze_throttle = 0; +SET SESSION tokudb_analyze_time = 0; + +let $i = $max; +while ($i > 0) { + eval CREATE TABLE ar_$i (a INT, b INT, PRIMARY KEY (a), KEY bkey (b)) ENGINE=TOKUDB; + dec $i; +} + +# check that the one row insertion triggered auto analyze within the calling +# client context, the cardinality should go from NULL to 1 +let $i = $max; +while ($i > 0) { + eval INSERT INTO ar_$i VALUES (0, 0); + dec $i; +} +-- enable_query_log +let $i = $max; +while ($i > 0) { + eval SHOW INDEX FROM ar_$i; + dec $i; +} + + +-- disable_query_log +# check that lots of background analysis get scheduled and run +# cleanly and serially in the background +SET SESSION tokudb_auto_analyze = 1; +SET SESSION tokudb_analyze_in_background = 1; +SET SESSION tokudb_analyze_mode = TOKUDB_ANALYZE_STANDARD; +SET SESSION tokudb_analyze_throttle = 0; +SET SESSION tokudb_analyze_time = 0; + +let $i = $max; +while ($i > 0) { + eval INSERT INTO ar_$i VALUES (1, 1), (2, 1), (3, 2), (4, 2); + dec $i; +} + +let $i = $max; +while ($i > 0) { + eval INSERT INTO ar_$i VALUES (5, 3), (6, 3), (7, 4), (8, 4); + dec $i; +} + +# would be too long to wait for stats to become up to date here and +# checking is quite non-deterministic, InnoDB test does same thing + +# dropping tables should cancel any running background jobs +let $i = $max; +while ($i > 0) { + eval DROP TABLE ar_$i; + dec $i; +} + +# wait for the bjm queue to empty +-- disable_query_log +let $wait_condition=select count(*)=0 from information_schema.tokudb_background_job_status; +-- source include/wait_condition.inc + +SET SESSION tokudb_auto_analyze = @orig_auto_analyze; +SET SESSION tokudb_analyze_in_background = @orig_in_background; +SET SESSION tokudb_analyze_mode = @orig_mode; +SET SESSION tokudb_analyze_throttle = @orig_throttle; +SET SESSION tokudb_analyze_time = @orig_time; + +-- enable_query_log diff --git a/mysql-test/suite/tokudb/t/card_scale_percent.test b/mysql-test/suite/tokudb/t/card_scale_percent.test new file mode 100644 index 0000000000000..47f1eb3798929 --- /dev/null +++ b/mysql-test/suite/tokudb/t/card_scale_percent.test @@ -0,0 +1,56 @@ +-- source include/have_tokudb.inc + +-- disable_query_log + +set @orig_throttle = @@session.tokudb_analyze_throttle; +set @orig_time = @@session.tokudb_analyze_time; +set @orig_scale_percent = @@global.tokudb_cardinality_scale_percent; + +create table tt (a int, b int, c int, d int, primary key(a), key(b), key(c), key(d)) engine=tokudb; +let $i=0; +while ($i < 1000) { + eval insert into tt values ($i, $i, $i, $i); + inc $i; +} +while ($i < 2000) { + eval insert into tt values ($i, $i, $i, 0); + inc $i; +} +while ($i < 3000) { + eval insert into tt values ($i, $i, 0, 0); + inc $i; +} +while ($i < 4000) { + eval insert into tt values ($i, 0, 0, 0); + inc $i; +} + +set session tokudb_analyze_time=0; +set session tokudb_analyze_throttle=0; + +-- enable_query_log + +set global tokudb_cardinality_scale_percent = 10; +analyze table tt; +show indexes from tt; + +set global tokudb_cardinality_scale_percent = 50; +analyze table tt; +show indexes from tt; + +set global tokudb_cardinality_scale_percent = 100; +analyze table tt; +show indexes from tt; + +set global tokudb_cardinality_scale_percent = 200; +analyze table tt; +show indexes from tt; + +-- disable_query_log + +drop table tt; +set session tokudb_analyze_throttle = @orig_throttle; +set session tokudb_analyze_time = @orig_time; +set global tokudb_cardinality_scale_percent = @orig_scale_percent; + +-- enable_query_log diff --git a/mysql-test/suite/tokudb/t/disabled.def b/mysql-test/suite/tokudb/t/disabled.def index 751794ac690ea..f65151ecd547a 100644 --- a/mysql-test/suite/tokudb/t/disabled.def +++ b/mysql-test/suite/tokudb/t/disabled.def @@ -2,3 +2,26 @@ mvcc-19: tokutek mvcc-20: tokutek mvcc-27: tokutek storage_engine_default: tokudb is not the default storage engine +cluster_key_part : https://tokutek.atlassian.net/browse/DB-720 +fast_update_blobs : https://tokutek.atlassian.net/browse/DB-871 +fast_update_blobs_fixed_varchar : https://tokutek.atlassian.net/browse/DB-871 +fast_update_blobs_with_varchar : https://tokutek.atlassian.net/browse/DB-871 +fast_update_char : https://tokutek.atlassian.net/browse/DB-871 +fast_update_decr_floor : https://tokutek.atlassian.net/browse/DB-871 +fast_update_int : https://tokutek.atlassian.net/browse/DB-871 +fast_update_int_bounds : https://tokutek.atlassian.net/browse/DB-871 +fast_update_uint_bounds : https://tokutek.atlassian.net/browse/DB-871 +fast_update_varchar : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_char : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_int : https://tokutek.atlassian.net/browse/DB-871 +fast_update_binlog_statement : https://tokutek.atlassian.net/browse/DB-871 +fast_update_deadlock : https://tokutek.atlassian.net/browse/DB-871 +fast_update_error : https://tokutek.atlassian.net/browse/DB-871 +fast_update_disable_slow_update : https://tokutek.atlassian.net/browse/DB-871 +fast_update_key : https://tokutek.atlassian.net/browse/DB-871 +fast_update_sqlmode : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_bin_pad : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_deadlock : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_key : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_sqlmode : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_values : https://tokutek.atlassian.net/browse/DB-871 diff --git a/mysql-test/suite/tokudb/t/rows-32m-seq-insert.test b/mysql-test/suite/tokudb/t/rows-32m-seq-insert.test index 5b1f54404523c..7ee84c69ecab4 100644 --- a/mysql-test/suite/tokudb/t/rows-32m-seq-insert.test +++ b/mysql-test/suite/tokudb/t/rows-32m-seq-insert.test @@ -1,3 +1,4 @@ +source include/big_test.inc; source include/have_tokudb.inc; # do a lot of longblob insertions up to 32MB-4 in size with seq primary key @@ -34,4 +35,4 @@ optimize table t; check table t; -drop table t; \ No newline at end of file +drop table t; diff --git a/mysql-test/suite/tokudb/t/suite.opt b/mysql-test/suite/tokudb/t/suite.opt new file mode 100644 index 0000000000000..23511b05020a4 --- /dev/null +++ b/mysql-test/suite/tokudb/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 7b6a024f63ef3..37de19c3c1985 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -1,8 +1,7 @@ -SET(TOKUDB_VERSION 5.6.26-74.0) +SET(TOKUDB_VERSION 5.6.27-76.0) # PerconaFT only supports x86-64 and cmake-2.8.9+ IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND - NOT CMAKE_VERSION VERSION_LESS "2.8.9" AND - NOT WITHOUT_TOKUDB AND NOT WITHOUT_TOKUDB_STORAGE_ENGINE) + NOT CMAKE_VERSION VERSION_LESS "2.8.9") CHECK_CXX_SOURCE_COMPILES( " struct a {int b; int c; }; @@ -11,14 +10,30 @@ int main() { return 0; } " TOKUDB_OK) ENDIF() -IF(NOT TOKUDB_OK) +IF(NOT TOKUDB_OK OR WITHOUT_TOKUDB OR WITHOUT_TOKUDB_STORAGE_ENGINE) RETURN() ENDIF() +## adds a compiler flag if the compiler supports it +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) + +# pick language dialect +check_cxx_compiler_flag(-std=c++11 HAVE_STDCXX11) +if (HAVE_STDCXX11) + set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") +else () + message(FATAL_ERROR "${CMAKE_CXX_COMPILER} doesn't support -std=c++11, you need one that does.") +endif () + + SET(BUILD_TESTING OFF CACHE BOOL "") SET(USE_VALGRIND OFF CACHE BOOL "") SET(TOKU_DEBUG_PARANOID OFF CACHE BOOL "") +# Enable TokuDB's TOKUDB_DEBUG in debug builds +SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTOKUDB_DEBUG") + IF(NOT DEFINED TOKUDB_VERSION) IF(DEFINED ENV{TOKUDB_VERSION}) SET(TOKUDB_VERSION $ENV{TOKUDB_VERSION}) @@ -41,10 +56,6 @@ IF(DEFINED TOKUDB_CHECK_JEMALLOC) ADD_DEFINITIONS("-DTOKUDB_CHECK_JEMALLOC=${TOKUDB_CHECK_JEMALLOC}") ENDIF() -## adds a compiler flag if the compiler supports it -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) - macro(set_cflags_if_supported) foreach(flag ${ARGN}) string(REGEX REPLACE "-" "_" temp_flag ${flag}) @@ -99,8 +110,13 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/${TOKU_FT_DIR_NAME}/portability) SET(TOKUDB_PLUGIN_DYNAMIC "ha_tokudb") -SET(TOKUDB_SOURCES ha_tokudb.cc) +SET(TOKUDB_SOURCES + ha_tokudb.cc + tokudb_background.cc + tokudb_information_schema.cc + tokudb_sysvars.cc + tokudb_thread.cc) MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY LINK_LIBRARIES tokufractaltree_static tokuportability_static ${ZLIB_LIBRARY} stdc++) -SET_PROPERTY(TARGET tokudb APPEND PROPERTY LINK_FLAGS_RELEASE "-flto -fuse-linker-plugin") -SET_PROPERTY(TARGET tokudb APPEND PROPERTY LINK_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin") +SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin") +SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin") diff --git a/storage/tokudb/PerconaFT/CMakeLists.txt b/storage/tokudb/PerconaFT/CMakeLists.txt index 788b3ef3d9d45..59e0d145ce05d 100644 --- a/storage/tokudb/PerconaFT/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/CMakeLists.txt @@ -1,4 +1,6 @@ -cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR) +if (CMAKE_PROJECT_NAME STREQUAL TokuDB) + cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR) +endif() set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake_modules") project(TokuDB) diff --git a/storage/tokudb/PerconaFT/CTestCustom.cmake b/storage/tokudb/PerconaFT/CTestCustom.cmake.in similarity index 100% rename from storage/tokudb/PerconaFT/CTestCustom.cmake rename to storage/tokudb/PerconaFT/CTestCustom.cmake.in diff --git a/storage/tokudb/PerconaFT/buildheader/CMakeLists.txt b/storage/tokudb/PerconaFT/buildheader/CMakeLists.txt index d9629f2cc6863..5da3c98ff4812 100644 --- a/storage/tokudb/PerconaFT/buildheader/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/buildheader/CMakeLists.txt @@ -4,7 +4,7 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/runcat.sh" "#!/bin/bash out=$1; shift exec \"$@\" >$out") -add_executable(make_tdb make_tdb) +add_executable(make_tdb make_tdb.cc) set_property(TARGET make_tdb APPEND PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE) add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/db.h" @@ -26,4 +26,4 @@ if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING) DESTINATION include COMPONENT tokukv_headers ) -endif () \ No newline at end of file +endif () diff --git a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc index 958f00a870615..5c29209e19d52 100644 --- a/storage/tokudb/PerconaFT/buildheader/make_tdb.cc +++ b/storage/tokudb/PerconaFT/buildheader/make_tdb.cc @@ -510,8 +510,9 @@ static void print_db_struct (void) { "int (*update_broadcast)(DB *, DB_TXN*, const DBT *extra, uint32_t flags)", "int (*get_fractal_tree_info64)(DB*,uint64_t*,uint64_t*,uint64_t*,uint64_t*)", "int (*iterate_fractal_tree_block_map)(DB*,int(*)(uint64_t,int64_t,int64_t,int64_t,int64_t,void*),void*)", - "const char *(*get_dname)(DB *db)", - "int (*get_last_key)(DB *db, YDB_CALLBACK_FUNCTION func, void* extra)", + "const char *(*get_dname)(DB *db)", + "int (*get_last_key)(DB *db, YDB_CALLBACK_FUNCTION func, void* extra)", + "int (*recount_rows)(DB* db, int (*progress_callback)(uint64_t count, uint64_t deleted, void* progress_extra), void* progress_extra)", NULL}; sort_and_dump_fields("db", true, extra); } diff --git a/storage/tokudb/PerconaFT/cmake_modules/FindValgrind.cmake b/storage/tokudb/PerconaFT/cmake_modules/FindValgrind.cmake index 03335c5bbe846..73841723ce90a 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/FindValgrind.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/FindValgrind.cmake @@ -11,7 +11,7 @@ find_path(VALGRIND_INCLUDE_DIR valgrind/memcheck.h) find_program(VALGRIND_PROGRAM NAMES valgrind) -find_package_handle_standard_args(VALGRIND DEFAULT_MSG +find_package_handle_standard_args(Valgrind DEFAULT_MSG VALGRIND_INCLUDE_DIR VALGRIND_PROGRAM) diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuMergeLibs.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuMergeLibs.cmake index 9dc1c49351352..e1da095fc0070 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuMergeLibs.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuMergeLibs.cmake @@ -48,7 +48,8 @@ MACRO(TOKU_MERGE_STATIC_LIBS TARGET OUTPUT_NAME LIBS_TO_MERGE) ENDIF() ENDFOREACH() IF(OSLIBS) - LIST(REMOVE_DUPLICATES OSLIBS) + # REMOVE_DUPLICATES destroys the order of the libs so disabled + # LIST(REMOVE_DUPLICATES OSLIBS) TARGET_LINK_LIBRARIES(${TARGET} LINK_PUBLIC ${OSLIBS}) ENDIF() diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCTest.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCTest.cmake index 1912dd33a077d..5b6882cc4a162 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCTest.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCTest.cmake @@ -9,6 +9,7 @@ macro(real_executable_name filename_input out) execute_process( COMMAND which ${filename} RESULT_VARIABLE res + ERROR_QUIET OUTPUT_VARIABLE full_filename OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT(res)) @@ -59,7 +60,7 @@ macro(hostname out) COMMAND hostname OUTPUT_VARIABLE fullhostname OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REGEX REPLACE "\\.tokutek\\.com$" "" ${out} ${fullhostname}) + string(REGEX REPLACE "\\.tokutek\\.com$" "" ${out} "${fullhostname}") endmacro(hostname) ## gather machine info @@ -150,5 +151,5 @@ if (BUILD_TESTING OR BUILD_FT_TESTS OR BUILD_SRC_TESTS) option(RUN_STRESS_TESTS "If set, run the stress tests." OFF) option(RUN_PERF_TESTS "If set, run the perf tests." OFF) - configure_file(CTestCustom.cmake . @ONLY) + configure_file(CTestCustom.cmake.in CTestCustom.cmake @ONLY) endif (BUILD_TESTING OR BUILD_FT_TESTS OR BUILD_SRC_TESTS) diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake index c011349c714c1..87947bb47d233 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake @@ -24,12 +24,12 @@ endif () ## add TOKU_PTHREAD_DEBUG for debug builds if (CMAKE_VERSION VERSION_LESS 3.0) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG TOKU_PTHREAD_DEBUG=1) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DRD TOKU_PTHREAD_DEBUG=1) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DEBUG TOKU_PTHREAD_DEBUG=1 TOKU_DEBUG_TXN_SYNC=1) + set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DRD TOKU_PTHREAD_DEBUG=1 TOKU_DEBUG_TXN_SYNC=1) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_DRD _FORTIFY_SOURCE=2) else () set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS - $<$,$>:TOKU_PTHREAD_DEBUG=1> + $<$,$>:TOKU_PTHREAD_DEBUG=1 TOKU_DEBUG_TXN_SYNC=1> $<$:_FORTIFY_SOURCE=2> ) endif () diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuThirdParty.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuThirdParty.cmake index 1e7e47f9bf42e..db94b19f08cc2 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuThirdParty.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuThirdParty.cmake @@ -41,7 +41,7 @@ if (APPLE) list(APPEND xz_configure_opts --disable-assembler) endif () -list(APPEND xz_configure_opts CC=${CMAKE_C_COMPILER}) +list(APPEND xz_configure_opts "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}") if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL drd) list(APPEND xz_configure_opts --enable-debug) endif () @@ -68,6 +68,7 @@ ExternalProject_Add(build_lzma CONFIGURE_COMMAND "/configure" ${xz_configure_opts} "--prefix=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/xz" + "--libdir=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/xz/lib" BUILD_COMMAND ${SUBMAKE_COMMAND} -C src/liblzma INSTALL_COMMAND diff --git a/storage/tokudb/PerconaFT/ft/CMakeLists.txt b/storage/tokudb/PerconaFT/ft/CMakeLists.txt index 744b9c9a9e16f..11091073ac2a1 100644 --- a/storage/tokudb/PerconaFT/ft/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/ft/CMakeLists.txt @@ -36,6 +36,7 @@ set(FT_SOURCES ft-flusher ft-hot-flusher ft-ops + ft-recount-rows ft-status ft-test-helpers ft-verify diff --git a/storage/tokudb/PerconaFT/ft/ft-flusher.cc b/storage/tokudb/PerconaFT/ft/ft-flusher.cc index 530947fe8689b..fb456ea6a18e3 100644 --- a/storage/tokudb/PerconaFT/ft/ft-flusher.cc +++ b/storage/tokudb/PerconaFT/ft/ft-flusher.cc @@ -1572,6 +1572,7 @@ void toku_bnc_flush_to_child(FT ft, NONLEAF_CHILDINFO bnc, FTNODE child, TXNID p txn_gc_info *gc_info; STAT64INFO_S stats_delta; + int64_t logical_rows_delta = 0; size_t remaining_memsize = bnc->msg_buffer.buffer_size_in_use(); flush_msg_fn(FT t, FTNODE n, NONLEAF_CHILDINFO nl, txn_gc_info *g) : @@ -1599,8 +1600,8 @@ void toku_bnc_flush_to_child(FT ft, NONLEAF_CHILDINFO bnc, FTNODE child, TXNID p is_fresh, gc_info, flow_deltas, - &stats_delta - ); + &stats_delta, + &logical_rows_delta); remaining_memsize -= memsize_in_buffer; return 0; } @@ -1613,6 +1614,7 @@ void toku_bnc_flush_to_child(FT ft, NONLEAF_CHILDINFO bnc, FTNODE child, TXNID p if (flush_fn.stats_delta.numbytes || flush_fn.stats_delta.numrows) { toku_ft_update_stats(&ft->in_memory_stats, flush_fn.stats_delta); } + toku_ft_adjust_logical_row_count(ft, flush_fn.logical_rows_delta); if (do_garbage_collection) { size_t buffsize = bnc->msg_buffer.buffer_size_in_use(); // may be misleading if there's a broadcast message in there diff --git a/storage/tokudb/PerconaFT/ft/ft-internal.h b/storage/tokudb/PerconaFT/ft/ft-internal.h index 6bf7029245b67..eec591d174402 100644 --- a/storage/tokudb/PerconaFT/ft/ft-internal.h +++ b/storage/tokudb/PerconaFT/ft/ft-internal.h @@ -143,6 +143,10 @@ struct ft_header { MSN msn_at_start_of_last_completed_optimize; STAT64INFO_S on_disk_stats; + + // This represents the balance of inserts - deletes and should be + // closer to a logical representation of the number of records in an index + uint64_t on_disk_logical_rows; }; typedef struct ft_header *FT_HEADER; @@ -176,6 +180,7 @@ struct ft { // protected by atomic builtins STAT64INFO_S in_memory_stats; + uint64_t in_memory_logical_rows; // transient, not serialized to disk. updated when we do write to // disk. tells us whether we can do partial eviction (we can't if diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc index f5da82ee00062..8f61bc67339fa 100644 --- a/storage/tokudb/PerconaFT/ft/ft-ops.cc +++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc @@ -1371,7 +1371,8 @@ static void inject_message_in_locked_node( ft_msg msg_with_msn(msg.kdbt(), msg.vdbt(), msg.type(), msg_msn, msg.xids()); paranoid_invariant(msg_with_msn.msn().msn > node->max_msn_applied_to_node_on_disk.msn); - STAT64INFO_S stats_delta = {0,0}; + STAT64INFO_S stats_delta = { 0,0 }; + int64_t logical_rows_delta = 0; toku_ftnode_put_msg( ft->cmp, ft->update_fun, @@ -1381,11 +1382,12 @@ static void inject_message_in_locked_node( true, gc_info, flow_deltas, - &stats_delta - ); + &stats_delta, + &logical_rows_delta); if (stats_delta.numbytes || stats_delta.numrows) { toku_ft_update_stats(&ft->in_memory_stats, stats_delta); } + toku_ft_adjust_logical_row_count(ft, logical_rows_delta); // // assumption is that toku_ftnode_put_msg will // mark the node as dirty. @@ -2169,6 +2171,7 @@ int toku_ft_insert_unique(FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool if (r == 0) { ft_txn_log_insert(ft_h->ft, key, val, txn, do_logging, FT_INSERT); + toku_ft_adjust_logical_row_count(ft_h->ft, 1); } return r; } @@ -2344,6 +2347,7 @@ void toku_ft_maybe_insert (FT_HANDLE ft_h, DBT *key, DBT *val, TOKUTXN txn, bool if (r != 0) { toku_ft_send_insert(ft_h, key, val, message_xids, type, &gc_info); } + toku_ft_adjust_logical_row_count(ft_h->ft, 1); } } @@ -2513,6 +2517,7 @@ void toku_ft_maybe_delete(FT_HANDLE ft_h, DBT *key, TOKUTXN txn, bool oplsn_vali oldest_referenced_xid_estimate, txn != nullptr ? !txn->for_recovery : false); toku_ft_send_delete(ft_h, key, message_xids, &gc_info); + toku_ft_adjust_logical_row_count(ft_h->ft, -1); } } diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.h b/storage/tokudb/PerconaFT/ft/ft-ops.h index 7d0b165b70ce0..313a74628ea17 100644 --- a/storage/tokudb/PerconaFT/ft/ft-ops.h +++ b/storage/tokudb/PerconaFT/ft/ft-ops.h @@ -207,6 +207,15 @@ extern int toku_ft_debug_mode; int toku_verify_ft (FT_HANDLE ft_h) __attribute__ ((warn_unused_result)); int toku_verify_ft_with_progress (FT_HANDLE ft_h, int (*progress_callback)(void *extra, float progress), void *extra, int verbose, int keep_going) __attribute__ ((warn_unused_result)); +int toku_ft_recount_rows( + FT_HANDLE ft, + int (*progress_callback)( + uint64_t count, + uint64_t deleted, + void* progress_extra), + void* progress_extra); + + DICTIONARY_ID toku_ft_get_dictionary_id(FT_HANDLE); enum ft_flags { diff --git a/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc b/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc new file mode 100644 index 0000000000000..adac96f488213 --- /dev/null +++ b/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc @@ -0,0 +1,115 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +#ident "$Id$" +/*====== +This file is part of PerconaFT. + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + PerconaFT 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 PerconaFT. If not, see . + +---------------------------------------- + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License, version 3, + as published by the Free Software Foundation. + + PerconaFT 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with PerconaFT. If not, see . +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "ft/serialize/block_table.h" +#include "ft/ft.h" +#include "ft/ft-internal.h" +#include "ft/cursor.h" + +struct recount_rows_extra_t { + int (*_progress_callback)( + uint64_t count, + uint64_t deleted, + void* progress_extra); + void* _progress_extra; + uint64_t _keys; + bool _cancelled; +}; + +static int recount_rows_found( + uint32_t UU(keylen), + const void* key, + uint32_t UU(vallen), + const void* UU(val), + void* extra, + bool UU(lock_only)) { + + recount_rows_extra_t* rre = (recount_rows_extra_t*)extra; + + if (FT_LIKELY(key != nullptr)) { + rre->_keys++; + } + return rre->_cancelled + = rre->_progress_callback(rre->_keys, 0, rre->_progress_extra); +} +static bool recount_rows_interrupt(void* extra, uint64_t deleted_rows) { + recount_rows_extra_t* rre = (recount_rows_extra_t*)extra; + + return rre->_cancelled = + rre->_progress_callback(rre->_keys, deleted_rows, rre->_progress_extra); +} +int toku_ft_recount_rows( + FT_HANDLE ft, + int (*progress_callback)( + uint64_t count, + uint64_t deleted, + void* progress_extra), + void* progress_extra) { + + int ret = 0; + recount_rows_extra_t rre = { + progress_callback, + progress_extra, + 0, + false + }; + + ft_cursor c; + ret = toku_ft_cursor_create(ft, &c, nullptr, C_READ_ANY, false, false); + if (ret) return ret; + + toku_ft_cursor_set_check_interrupt_cb( + &c, + recount_rows_interrupt, + &rre); + + ret = toku_ft_cursor_first(&c, recount_rows_found, &rre); + while (FT_LIKELY(ret == 0)) { + ret = toku_ft_cursor_next(&c, recount_rows_found, &rre); + } + + toku_ft_cursor_destroy(&c); + + if (rre._cancelled == false) { + // update ft count + toku_unsafe_set(&ft->ft->in_memory_logical_rows, rre._keys); + ret = 0; + } + + return ret; +} diff --git a/storage/tokudb/PerconaFT/ft/ft-status.cc b/storage/tokudb/PerconaFT/ft/ft-status.cc index 982df1822c43e..19a378c22bf53 100644 --- a/storage/tokudb/PerconaFT/ft/ft-status.cc +++ b/storage/tokudb/PerconaFT/ft/ft-status.cc @@ -128,24 +128,24 @@ void CACHETABLE_STATUS_S::init() { CT_STATUS_INIT(CT_LONG_WAIT_PRESSURE_COUNT, CACHETABLE_LONG_WAIT_PRESSURE_COUNT, UINT64, "number of long waits on cache pressure"); CT_STATUS_INIT(CT_LONG_WAIT_PRESSURE_TIME, CACHETABLE_LONG_WAIT_PRESSURE_TIME, UINT64, "long time waiting on cache pressure"); - CT_STATUS_INIT(CT_POOL_CLIENT_NUM_THREADS, CACHETABLE_POOL_CLIENT_NUM_THREADS, UINT64, "number of threads in pool"); - CT_STATUS_INIT(CT_POOL_CLIENT_NUM_THREADS_ACTIVE, CACHETABLE_POOL_CLIENT_NUM_THREADS_ACTIVE, UINT64, "number of currently active threads in pool"); - CT_STATUS_INIT(CT_POOL_CLIENT_QUEUE_SIZE, CACHETABLE_POOL_CLIENT_QUEUE_SIZE, UINT64, "number of currently queued work items"); - CT_STATUS_INIT(CT_POOL_CLIENT_MAX_QUEUE_SIZE, CACHETABLE_POOL_CLIENT_MAX_QUEUE_SIZE, UINT64, "largest number of queued work items"); - CT_STATUS_INIT(CT_POOL_CLIENT_TOTAL_ITEMS_PROCESSED, CACHETABLE_POOL_CLIENT_TOTAL_ITEMS_PROCESSED, UINT64, "total number of work items processed"); - CT_STATUS_INIT(CT_POOL_CLIENT_TOTAL_EXECUTION_TIME, CACHETABLE_POOL_CLIENT_TOTAL_EXECUTION_TIME, UINT64, "total execution time of processing work items"); - CT_STATUS_INIT(CT_POOL_CACHETABLE_NUM_THREADS, CACHETABLE_POOL_CACHETABLE_NUM_THREADS, UINT64, "number of threads in pool"); - CT_STATUS_INIT(CT_POOL_CACHETABLE_NUM_THREADS_ACTIVE, CACHETABLE_POOL_CACHETABLE_NUM_THREADS_ACTIVE, UINT64, "number of currently active threads in pool"); - CT_STATUS_INIT(CT_POOL_CACHETABLE_QUEUE_SIZE, CACHETABLE_POOL_CACHETABLE_QUEUE_SIZE, UINT64, "number of currently queued work items"); - CT_STATUS_INIT(CT_POOL_CACHETABLE_MAX_QUEUE_SIZE, CACHETABLE_POOL_CACHETABLE_MAX_QUEUE_SIZE, UINT64, "largest number of queued work items"); - CT_STATUS_INIT(CT_POOL_CACHETABLE_TOTAL_ITEMS_PROCESSED, CACHETABLE_POOL_CACHETABLE_TOTAL_ITEMS_PROCESSED, UINT64, "total number of work items processed"); - CT_STATUS_INIT(CT_POOL_CACHETABLE_TOTAL_EXECUTION_TIME, CACHETABLE_POOL_CACHETABLE_TOTAL_EXECUTION_TIME, UINT64, "total execution time of processing work items"); - CT_STATUS_INIT(CT_POOL_CHECKPOINT_NUM_THREADS, CACHETABLE_POOL_CHECKPOINT_NUM_THREADS, UINT64, "number of threads in pool"); - CT_STATUS_INIT(CT_POOL_CHECKPOINT_NUM_THREADS_ACTIVE, CACHETABLE_POOL_CHECKPOINT_NUM_THREADS_ACTIVE, UINT64, "number of currently active threads in pool"); - CT_STATUS_INIT(CT_POOL_CHECKPOINT_QUEUE_SIZE, CACHETABLE_POOL_CHECKPOINT_QUEUE_SIZE, UINT64, "number of currently queued work items"); - CT_STATUS_INIT(CT_POOL_CHECKPOINT_MAX_QUEUE_SIZE, CACHETABLE_POOL_CHECKPOINT_MAX_QUEUE_SIZE, UINT64, "largest number of queued work items"); - CT_STATUS_INIT(CT_POOL_CHECKPOINT_TOTAL_ITEMS_PROCESSED, CACHETABLE_POOL_CHECKPOINT_TOTAL_ITEMS_PROCESSED, UINT64, "total number of work items processed"); - CT_STATUS_INIT(CT_POOL_CHECKPOINT_TOTAL_EXECUTION_TIME, CACHETABLE_POOL_CHECKPOINT_TOTAL_EXECUTION_TIME, UINT64, "total execution time of processing work items"); + CT_STATUS_INIT(CT_POOL_CLIENT_NUM_THREADS, CACHETABLE_POOL_CLIENT_NUM_THREADS, UINT64, "client pool: number of threads in pool"); + CT_STATUS_INIT(CT_POOL_CLIENT_NUM_THREADS_ACTIVE, CACHETABLE_POOL_CLIENT_NUM_THREADS_ACTIVE, UINT64, "client pool: number of currently active threads in pool"); + CT_STATUS_INIT(CT_POOL_CLIENT_QUEUE_SIZE, CACHETABLE_POOL_CLIENT_QUEUE_SIZE, UINT64, "client pool: number of currently queued work items"); + CT_STATUS_INIT(CT_POOL_CLIENT_MAX_QUEUE_SIZE, CACHETABLE_POOL_CLIENT_MAX_QUEUE_SIZE, UINT64, "client pool: largest number of queued work items"); + CT_STATUS_INIT(CT_POOL_CLIENT_TOTAL_ITEMS_PROCESSED, CACHETABLE_POOL_CLIENT_TOTAL_ITEMS_PROCESSED, UINT64, "client pool: total number of work items processed"); + CT_STATUS_INIT(CT_POOL_CLIENT_TOTAL_EXECUTION_TIME, CACHETABLE_POOL_CLIENT_TOTAL_EXECUTION_TIME, UINT64, "client pool: total execution time of processing work items"); + CT_STATUS_INIT(CT_POOL_CACHETABLE_NUM_THREADS, CACHETABLE_POOL_CACHETABLE_NUM_THREADS, UINT64, "cachetable pool: number of threads in pool"); + CT_STATUS_INIT(CT_POOL_CACHETABLE_NUM_THREADS_ACTIVE, CACHETABLE_POOL_CACHETABLE_NUM_THREADS_ACTIVE, UINT64, "cachetable pool: number of currently active threads in pool"); + CT_STATUS_INIT(CT_POOL_CACHETABLE_QUEUE_SIZE, CACHETABLE_POOL_CACHETABLE_QUEUE_SIZE, UINT64, "cachetable pool: number of currently queued work items"); + CT_STATUS_INIT(CT_POOL_CACHETABLE_MAX_QUEUE_SIZE, CACHETABLE_POOL_CACHETABLE_MAX_QUEUE_SIZE, UINT64, "cachetable pool: largest number of queued work items"); + CT_STATUS_INIT(CT_POOL_CACHETABLE_TOTAL_ITEMS_PROCESSED, CACHETABLE_POOL_CACHETABLE_TOTAL_ITEMS_PROCESSED, UINT64, "cachetable pool: total number of work items processed"); + CT_STATUS_INIT(CT_POOL_CACHETABLE_TOTAL_EXECUTION_TIME, CACHETABLE_POOL_CACHETABLE_TOTAL_EXECUTION_TIME, UINT64, "cachetable pool: total execution time of processing work items"); + CT_STATUS_INIT(CT_POOL_CHECKPOINT_NUM_THREADS, CACHETABLE_POOL_CHECKPOINT_NUM_THREADS, UINT64, "checkpoint pool: number of threads in pool"); + CT_STATUS_INIT(CT_POOL_CHECKPOINT_NUM_THREADS_ACTIVE, CACHETABLE_POOL_CHECKPOINT_NUM_THREADS_ACTIVE, UINT64, "checkpoint pool: number of currently active threads in pool"); + CT_STATUS_INIT(CT_POOL_CHECKPOINT_QUEUE_SIZE, CACHETABLE_POOL_CHECKPOINT_QUEUE_SIZE, UINT64, "checkpoint pool: number of currently queued work items"); + CT_STATUS_INIT(CT_POOL_CHECKPOINT_MAX_QUEUE_SIZE, CACHETABLE_POOL_CHECKPOINT_MAX_QUEUE_SIZE, UINT64, "checkpoint pool: largest number of queued work items"); + CT_STATUS_INIT(CT_POOL_CHECKPOINT_TOTAL_ITEMS_PROCESSED, CACHETABLE_POOL_CHECKPOINT_TOTAL_ITEMS_PROCESSED, UINT64, "checkpoint pool: total number of work items processed"); + CT_STATUS_INIT(CT_POOL_CHECKPOINT_TOTAL_EXECUTION_TIME, CACHETABLE_POOL_CHECKPOINT_TOTAL_EXECUTION_TIME, UINT64, "checkpoint pool: total execution time of processing work items"); m_initialized = true; #undef CT_STATUS_INIT diff --git a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc index 7ca36c237804d..6fcdbbdc9e341 100644 --- a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc +++ b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc @@ -172,21 +172,26 @@ int toku_testsetup_insert_to_leaf (FT_HANDLE ft_handle, BLOCKNUM blocknum, const assert(node->height==0); DBT kdbt, vdbt; - ft_msg msg(toku_fill_dbt(&kdbt, key, keylen), toku_fill_dbt(&vdbt, val, vallen), - FT_INSERT, next_dummymsn(), toku_xids_get_root_xids()); + ft_msg msg( + toku_fill_dbt(&kdbt, key, keylen), + toku_fill_dbt(&vdbt, val, vallen), + FT_INSERT, + next_dummymsn(), + toku_xids_get_root_xids()); static size_t zero_flow_deltas[] = { 0, 0 }; txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, true); - toku_ftnode_put_msg(ft_handle->ft->cmp, - ft_handle->ft->update_fun, - node, - -1, - msg, - true, - &gc_info, - zero_flow_deltas, - NULL - ); + toku_ftnode_put_msg( + ft_handle->ft->cmp, + ft_handle->ft->update_fun, + node, + -1, + msg, + true, + &gc_info, + zero_flow_deltas, + NULL, + NULL); toku_verify_or_set_counts(node); diff --git a/storage/tokudb/PerconaFT/ft/ft.cc b/storage/tokudb/PerconaFT/ft/ft.cc index 2a0fb6f6800f7..93d21233bf73d 100644 --- a/storage/tokudb/PerconaFT/ft/ft.cc +++ b/storage/tokudb/PerconaFT/ft/ft.cc @@ -198,6 +198,8 @@ static void ft_checkpoint (CACHEFILE cf, int fd, void *header_v) { ch->time_of_last_modification = now; ch->checkpoint_count++; ft_hack_highest_unused_msn_for_upgrade_for_checkpoint(ft); + ch->on_disk_logical_rows = + ft->h->on_disk_logical_rows = ft->in_memory_logical_rows; // write translation and header to disk (or at least to OS internal buffer) toku_serialize_ft_to(fd, ch, &ft->blocktable, ft->cf); @@ -383,7 +385,8 @@ ft_header_create(FT_OPTIONS options, BLOCKNUM root_blocknum, TXNID root_xid_that .count_of_optimize_in_progress = 0, .count_of_optimize_in_progress_read_from_disk = 0, .msn_at_start_of_last_completed_optimize = ZERO_MSN, - .on_disk_stats = ZEROSTATS + .on_disk_stats = ZEROSTATS, + .on_disk_logical_rows = 0 }; return (FT_HEADER) toku_xmemdup(&h, sizeof h); } @@ -802,7 +805,14 @@ toku_ft_stat64 (FT ft, struct ftstat64_s *s) { s->fsize = toku_cachefile_size(ft->cf); // just use the in memory stats from the header // prevent appearance of negative numbers for numrows, numbytes - int64_t n = ft->in_memory_stats.numrows; + // if the logical count was never properly re-counted on an upgrade, + // return the existing physical count instead. + int64_t n; + if (ft->in_memory_logical_rows == (uint64_t)-1) { + n = ft->in_memory_stats.numrows; + } else { + n = ft->in_memory_logical_rows; + } if (n < 0) { n = 0; } @@ -871,20 +881,38 @@ DESCRIPTOR toku_ft_get_cmp_descriptor(FT_HANDLE ft_handle) { return &ft_handle->ft->cmp_descriptor; } -void -toku_ft_update_stats(STAT64INFO headerstats, STAT64INFO_S delta) { +void toku_ft_update_stats(STAT64INFO headerstats, STAT64INFO_S delta) { (void) toku_sync_fetch_and_add(&(headerstats->numrows), delta.numrows); (void) toku_sync_fetch_and_add(&(headerstats->numbytes), delta.numbytes); } -void -toku_ft_decrease_stats(STAT64INFO headerstats, STAT64INFO_S delta) { +void toku_ft_decrease_stats(STAT64INFO headerstats, STAT64INFO_S delta) { (void) toku_sync_fetch_and_sub(&(headerstats->numrows), delta.numrows); (void) toku_sync_fetch_and_sub(&(headerstats->numbytes), delta.numbytes); } -void -toku_ft_remove_reference(FT ft, bool oplsn_valid, LSN oplsn, remove_ft_ref_callback remove_ref, void *extra) { +void toku_ft_adjust_logical_row_count(FT ft, int64_t delta) { + // In order to make sure that the correct count is returned from + // toku_ft_stat64, the ft->(in_memory|on_disk)_logical_rows _MUST_NOT_ be + // modified from anywhere else from here with the exceptions of + // serializing in a header, initializing a new header and analyzing + // an index for a logical_row count. + // The gist is that on an index upgrade, all logical_rows values + // in the ft header are set to -1 until an analyze can reset it to an + // accurate value. Until then, the physical count from in_memory_stats + // must be returned in toku_ft_stat64. + if (delta != 0 && ft->in_memory_logical_rows != (uint64_t)-1) { + toku_sync_fetch_and_add(&(ft->in_memory_logical_rows), delta); + } +} + +void toku_ft_remove_reference( + FT ft, + bool oplsn_valid, + LSN oplsn, + remove_ft_ref_callback remove_ref, + void *extra) { + toku_ft_grab_reflock(ft); if (toku_ft_has_one_reference_unlocked(ft)) { toku_ft_release_reflock(ft); diff --git a/storage/tokudb/PerconaFT/ft/ft.h b/storage/tokudb/PerconaFT/ft/ft.h index cc64bdfc6d399..d600e093bdcf0 100644 --- a/storage/tokudb/PerconaFT/ft/ft.h +++ b/storage/tokudb/PerconaFT/ft/ft.h @@ -127,13 +127,17 @@ DESCRIPTOR toku_ft_get_cmp_descriptor(FT_HANDLE ft_handle); typedef struct { // delta versions in basements could be negative + // These represent the physical leaf entries and do not account + // for pending deletes or other in-flight messages that have not been + // applied to a leaf entry. int64_t numrows; int64_t numbytes; } STAT64INFO_S, *STAT64INFO; -static const STAT64INFO_S ZEROSTATS = { .numrows = 0, .numbytes = 0}; +static const STAT64INFO_S ZEROSTATS = { .numrows = 0, .numbytes = 0 }; void toku_ft_update_stats(STAT64INFO headerstats, STAT64INFO_S delta); void toku_ft_decrease_stats(STAT64INFO headerstats, STAT64INFO_S delta); +void toku_ft_adjust_logical_row_count(FT ft, int64_t delta); typedef void (*remove_ft_ref_callback)(FT ft, void *extra); void toku_ft_remove_reference(FT ft, diff --git a/storage/tokudb/PerconaFT/ft/leafentry.h b/storage/tokudb/PerconaFT/ft/leafentry.h index 9cb81ef7cd62c..7274a1480e24f 100644 --- a/storage/tokudb/PerconaFT/ft/leafentry.h +++ b/storage/tokudb/PerconaFT/ft/leafentry.h @@ -180,43 +180,57 @@ uint64_t le_outermost_uncommitted_xid (LEAFENTRY le); // r|r!=0&&r!=TOKUDB_ACCEPT: Quit early, return r, because something unexpected went wrong (error case) typedef int(*LE_ITERATE_CALLBACK)(TXNID id, TOKUTXN context, bool is_provisional); -int le_iterate_val(LEAFENTRY le, LE_ITERATE_CALLBACK f, void** valpp, uint32_t *vallenp, TOKUTXN context); - -void le_extract_val(LEAFENTRY le, - // should we return the entire leafentry as the val? - bool is_leaf_mode, enum cursor_read_type read_type, - TOKUTXN ttxn, uint32_t *vallen, void **val); - -size_t -leafentry_disksize_13(LEAFENTRY_13 le); - -int -toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, // NULL if there was no stored data. - void** keyp, - uint32_t* keylen, - size_t *new_leafentry_memorysize, - LEAFENTRY *new_leafentry_p); +int le_iterate_val( + LEAFENTRY le, + LE_ITERATE_CALLBACK f, + void** valpp, + uint32_t* vallenp, + TOKUTXN context); + +void le_extract_val( + LEAFENTRY le, + // should we return the entire leafentry as the val? + bool is_leaf_mode, + enum cursor_read_type read_type, + TOKUTXN ttxn, + uint32_t* vallen, + void** val); + +size_t leafentry_disksize_13(LEAFENTRY_13 le); + +int toku_le_upgrade_13_14( + // NULL if there was no stored data. + LEAFENTRY_13 old_leafentry, + void** keyp, + uint32_t* keylen, + size_t* new_leafentry_memorysize, + LEAFENTRY *new_leafentry_p); class bn_data; -void -toku_le_apply_msg(const ft_msg &msg, - LEAFENTRY old_leafentry, // NULL if there was no stored data. - bn_data* data_buffer, // bn_data storing leafentry, if NULL, means there is no bn_data - uint32_t idx, // index in data_buffer where leafentry is stored (and should be replaced - uint32_t old_keylen, - txn_gc_info *gc_info, - LEAFENTRY *new_leafentry_p, - int64_t * numbytes_delta_p); - -bool toku_le_worth_running_garbage_collection(LEAFENTRY le, txn_gc_info *gc_info); - -void -toku_le_garbage_collect(LEAFENTRY old_leaf_entry, - bn_data* data_buffer, - uint32_t idx, - void* keyp, - uint32_t keylen, - txn_gc_info *gc_info, - LEAFENTRY *new_leaf_entry, - int64_t * numbytes_delta_p); +int64_t toku_le_apply_msg( + const ft_msg &msg, + // NULL if there was no stored data. + LEAFENTRY old_leafentry, + // bn_data storing leafentry, if NULL, means there is no bn_data + bn_data* data_buffer, + // index in data_buffer where leafentry is stored (and should be replaced + uint32_t idx, + uint32_t old_keylen, + txn_gc_info* gc_info, + LEAFENTRY *new_leafentry_p, + int64_t* numbytes_delta_p); + +bool toku_le_worth_running_garbage_collection( + LEAFENTRY le, + txn_gc_info* gc_info); + +void toku_le_garbage_collect( + LEAFENTRY old_leaf_entry, + bn_data* data_buffer, + uint32_t idx, + void* keyp, + uint32_t keylen, + txn_gc_info* gc_info, + LEAFENTRY* new_leaf_entry, + int64_t* numbytes_delta_p); diff --git a/storage/tokudb/PerconaFT/ft/loader/loader.cc b/storage/tokudb/PerconaFT/ft/loader/loader.cc index 5ff0d69af4643..20f9363da1efa 100644 --- a/storage/tokudb/PerconaFT/ft/loader/loader.cc +++ b/storage/tokudb/PerconaFT/ft/loader/loader.cc @@ -2312,11 +2312,42 @@ static struct leaf_buf *start_leaf (struct dbout *out, const DESCRIPTOR UU(desc) return lbuf; } -static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progress_allocation, FTLOADER bl, uint32_t target_basementnodesize, enum toku_compression_method target_compression_method); -static int write_nonleaves (FTLOADER bl, FIDX pivots_fidx, struct dbout *out, struct subtrees_info *sts, const DESCRIPTOR descriptor, uint32_t target_nodesize, uint32_t target_basementnodesize, enum toku_compression_method target_compression_method); -static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int keylen, unsigned char *val, int vallen, int this_leafentry_size, STAT64INFO stats_to_update); -static int write_translation_table (struct dbout *out, long long *off_of_translation_p); -static int write_header (struct dbout *out, long long translation_location_on_disk, long long translation_size_on_disk); +static void finish_leafnode( + struct dbout* out, + struct leaf_buf* lbuf, + int progress_allocation, + FTLOADER bl, + uint32_t target_basementnodesize, + enum toku_compression_method target_compression_method); + +static int write_nonleaves( + FTLOADER bl, + FIDX pivots_fidx, + struct dbout* out, + struct subtrees_info* sts, + const DESCRIPTOR descriptor, + uint32_t target_nodesize, + uint32_t target_basementnodesize, + enum toku_compression_method target_compression_method); + +static void add_pair_to_leafnode( + struct leaf_buf* lbuf, + unsigned char* key, + int keylen, + unsigned char* val, + int vallen, + int this_leafentry_size, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta); + +static int write_translation_table( + struct dbout* out, + long long* off_of_translation_p); + +static int write_header( + struct dbout* out, + long long translation_location_on_disk, + long long translation_size_on_disk); static void drain_writer_q(QUEUE q) { void *item; @@ -2448,6 +2479,12 @@ static int toku_loader_write_ft_from_q (FTLOADER bl, DBT maxkey = make_dbt(0, 0); // keep track of the max key of the current node STAT64INFO_S deltas = ZEROSTATS; + // This is just a placeholder and not used in the loader, the real/accurate + // stats will come out of 'deltas' because this loader is not pushing + // messages down into the top of a fractal tree where the logical row count + // is done, it is directly creating leaf entries so it must also take on + // performing the logical row counting on its own + int64_t logical_rows_delta = 0; while (result == 0) { void *item; { @@ -2506,7 +2543,15 @@ static int toku_loader_write_ft_from_q (FTLOADER bl, lbuf = start_leaf(&out, descriptor, lblock, le_xid, target_nodesize); } - add_pair_to_leafnode(lbuf, (unsigned char *) key.data, key.size, (unsigned char *) val.data, val.size, this_leafentry_size, &deltas); + add_pair_to_leafnode( + lbuf, + (unsigned char*)key.data, + key.size, + (unsigned char*)val.data, + val.size, + this_leafentry_size, + &deltas, + &logical_rows_delta); n_rows_remaining--; update_maxkey(&maxkey, &key); // set the new maxkey to the current key @@ -2526,6 +2571,13 @@ static int toku_loader_write_ft_from_q (FTLOADER bl, toku_ft_update_stats(&ft.in_memory_stats, deltas); } + // As noted above, the loader directly creates a tree structure without + // going through the higher level ft API and tus bypasses the logical row + // counting performed at that level. So, we must manually update the logical + // row count with the info we have from the physical delta that comes out of + // add_pair_to_leafnode. + toku_ft_adjust_logical_row_count(&ft, deltas.numrows); + cleanup_maxkey(&maxkey); if (lbuf) { @@ -2878,7 +2930,16 @@ int toku_ft_loader_get_error(FTLOADER bl, int *error) { return 0; } -static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int keylen, unsigned char *val, int vallen, int this_leafentry_size, STAT64INFO stats_to_update) { +static void add_pair_to_leafnode( + struct leaf_buf* lbuf, + unsigned char* key, + int keylen, + unsigned char* val, + int vallen, + int this_leafentry_size, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta) { + lbuf->nkeys++; lbuf->ndata++; lbuf->dsize += keylen + vallen; @@ -2890,11 +2951,25 @@ static void add_pair_to_leafnode (struct leaf_buf *lbuf, unsigned char *key, int FTNODE leafnode = lbuf->node; uint32_t idx = BLB_DATA(leafnode, 0)->num_klpairs(); DBT kdbt, vdbt; - ft_msg msg(toku_fill_dbt(&kdbt, key, keylen), toku_fill_dbt(&vdbt, val, vallen), FT_INSERT, ZERO_MSN, lbuf->xids); + ft_msg msg( + toku_fill_dbt(&kdbt, key, keylen), + toku_fill_dbt(&vdbt, val, vallen), + FT_INSERT, + ZERO_MSN, + lbuf->xids); uint64_t workdone = 0; // there's no mvcc garbage in a bulk-loaded FT, so there's no need to pass useful gc info txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, true); - toku_ft_bn_apply_msg_once(BLB(leafnode,0), msg, idx, keylen, NULL, &gc_info, &workdone, stats_to_update); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + &workdone, + stats_to_update, + logical_rows_delta); } static int write_literal(struct dbout *out, void*data, size_t len) { @@ -2905,7 +2980,14 @@ static int write_literal(struct dbout *out, void*data, size_t len) { return result; } -static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progress_allocation, FTLOADER bl, uint32_t target_basementnodesize, enum toku_compression_method target_compression_method) { +static void finish_leafnode( + struct dbout* out, + struct leaf_buf* lbuf, + int progress_allocation, + FTLOADER bl, + uint32_t target_basementnodesize, + enum toku_compression_method target_compression_method) { + int result = 0; // serialize leaf to buffer @@ -2913,7 +2995,16 @@ static void finish_leafnode (struct dbout *out, struct leaf_buf *lbuf, int progr size_t uncompressed_serialized_leaf_size = 0; char *serialized_leaf = NULL; FTNODE_DISK_DATA ndd = NULL; - result = toku_serialize_ftnode_to_memory(lbuf->node, &ndd, target_basementnodesize, target_compression_method, true, true, &serialized_leaf_size, &uncompressed_serialized_leaf_size, &serialized_leaf); + result = toku_serialize_ftnode_to_memory( + lbuf->node, + &ndd, + target_basementnodesize, + target_compression_method, + true, + true, + &serialized_leaf_size, + &uncompressed_serialized_leaf_size, + &serialized_leaf); // write it out if (result == 0) { @@ -2979,8 +3070,11 @@ static int write_translation_table (struct dbout *out, long long *off_of_transla return result; } -static int -write_header (struct dbout *out, long long translation_location_on_disk, long long translation_size_on_disk) { +static int write_header( + struct dbout* out, + long long translation_location_on_disk, + long long translation_size_on_disk) { + int result = 0; size_t size = toku_serialize_ft_size(out->ft->h); size_t alloced_size = roundup_to_multiple(512, size); @@ -2991,6 +3085,7 @@ write_header (struct dbout *out, long long translation_location_on_disk, long lo } else { wbuf_init(&wbuf, buf, size); out->ft->h->on_disk_stats = out->ft->in_memory_stats; + out->ft->h->on_disk_logical_rows = out->ft->in_memory_logical_rows; toku_serialize_ft_to_wbuf(&wbuf, out->ft->h, translation_location_on_disk, translation_size_on_disk); for (size_t i=size; iget_message(offset, &k, &v); @@ -227,16 +235,17 @@ do_bn_apply_msg(FT_HANDLE ft_handle, BASEMENTNODE bn, message_buffer *msg_buffer msg, gc_info, workdone, - stats_to_update - ); + stats_to_update, + logical_rows_delta); } else { toku_ft_status_note_msn_discard(); } // We must always mark message as stale since it has been marked // (using omt::iterate_and_mark_range) - // It is possible to call do_bn_apply_msg even when it won't apply the message because - // the node containing it could have been evicted and brought back in. + // It is possible to call do_bn_apply_msg even when it won't apply the + // message because the node containing it could have been evicted and + // brought back in. msg_buffer->set_freshness(offset, false); } @@ -248,12 +257,29 @@ struct iterate_do_bn_apply_msg_extra { txn_gc_info *gc_info; uint64_t *workdone; STAT64INFO stats_to_update; + int64_t *logical_rows_delta; }; -int iterate_do_bn_apply_msg(const int32_t &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_msg_extra *const e) __attribute__((nonnull(3))); -int iterate_do_bn_apply_msg(const int32_t &offset, const uint32_t UU(idx), struct iterate_do_bn_apply_msg_extra *const e) +int iterate_do_bn_apply_msg( + const int32_t &offset, + const uint32_t UU(idx), + struct iterate_do_bn_apply_msg_extra* const e) + __attribute__((nonnull(3))); + +int iterate_do_bn_apply_msg( + const int32_t &offset, + const uint32_t UU(idx), + struct iterate_do_bn_apply_msg_extra* const e) { - do_bn_apply_msg(e->t, e->bn, &e->bnc->msg_buffer, offset, e->gc_info, e->workdone, e->stats_to_update); + do_bn_apply_msg( + e->t, + e->bn, + &e->bnc->msg_buffer, + offset, + e->gc_info, + e->workdone, + e->stats_to_update, + e->logical_rows_delta); return 0; } @@ -354,17 +380,15 @@ find_bounds_within_message_tree( * or plus infinity respectively if they are NULL. Do not mark the node * as dirty (preserve previous state of 'dirty' bit). */ -static void -bnc_apply_messages_to_basement_node( +static void bnc_apply_messages_to_basement_node( FT_HANDLE t, // used for comparison function BASEMENTNODE bn, // where to apply messages FTNODE ancestor, // the ancestor node where we can find messages to apply int childnum, // which child buffer of ancestor contains messages we want const pivot_bounds &bounds, // contains pivot key bounds of this basement node - txn_gc_info *gc_info, - bool* msgs_applied - ) -{ + txn_gc_info* gc_info, + bool* msgs_applied) { + int r; NONLEAF_CHILDINFO bnc = BNC(ancestor, childnum); @@ -372,16 +396,29 @@ bnc_apply_messages_to_basement_node( // apply messages from this buffer STAT64INFO_S stats_delta = {0,0}; uint64_t workdone_this_ancestor = 0; + int64_t logical_rows_delta = 0; uint32_t stale_lbi, stale_ube; if (!bn->stale_ancestor_messages_applied) { - find_bounds_within_message_tree(t->ft->cmp, bnc->stale_message_tree, &bnc->msg_buffer, bounds, &stale_lbi, &stale_ube); + find_bounds_within_message_tree( + t->ft->cmp, + bnc->stale_message_tree, + &bnc->msg_buffer, + bounds, + &stale_lbi, + &stale_ube); } else { stale_lbi = 0; stale_ube = 0; } uint32_t fresh_lbi, fresh_ube; - find_bounds_within_message_tree(t->ft->cmp, bnc->fresh_message_tree, &bnc->msg_buffer, bounds, &fresh_lbi, &fresh_ube); + find_bounds_within_message_tree( + t->ft->cmp, + bnc->fresh_message_tree, + &bnc->msg_buffer, + bounds, + &fresh_lbi, + &fresh_ube); // We now know where all the messages we must apply are, so one of the // following 4 cases will do the application, depending on which of @@ -395,7 +432,9 @@ bnc_apply_messages_to_basement_node( // We have messages in multiple trees, so we grab all // the relevant messages' offsets and sort them by MSN, then apply // them in MSN order. - const int buffer_size = ((stale_ube - stale_lbi) + (fresh_ube - fresh_lbi) + bnc->broadcast_list.size()); + const int buffer_size = ((stale_ube - stale_lbi) + + (fresh_ube - fresh_lbi) + + bnc->broadcast_list.size()); toku::scoped_malloc offsets_buf(buffer_size * sizeof(int32_t)); int32_t *offsets = reinterpret_cast(offsets_buf.get()); struct store_msg_buffer_offset_extra sfo_extra = { .offsets = offsets, .i = 0 }; @@ -419,11 +458,27 @@ bnc_apply_messages_to_basement_node( // Apply the messages in MSN order. for (int i = 0; i < buffer_size; ++i) { *msgs_applied = true; - do_bn_apply_msg(t, bn, &bnc->msg_buffer, offsets[i], gc_info, &workdone_this_ancestor, &stats_delta); + do_bn_apply_msg( + t, + bn, + &bnc->msg_buffer, + offsets[i], + gc_info, + &workdone_this_ancestor, + &stats_delta, + &logical_rows_delta); } } else if (stale_lbi == stale_ube) { // No stale messages to apply, we just apply fresh messages, and mark them to be moved to stale later. - struct iterate_do_bn_apply_msg_extra iter_extra = { .t = t, .bn = bn, .bnc = bnc, .gc_info = gc_info, .workdone = &workdone_this_ancestor, .stats_to_update = &stats_delta }; + struct iterate_do_bn_apply_msg_extra iter_extra = { + .t = t, + .bn = bn, + .bnc = bnc, + .gc_info = gc_info, + .workdone = &workdone_this_ancestor, + .stats_to_update = &stats_delta, + .logical_rows_delta = &logical_rows_delta + }; if (fresh_ube - fresh_lbi > 0) *msgs_applied = true; r = bnc->fresh_message_tree.iterate_and_mark_range(fresh_lbi, fresh_ube, &iter_extra); assert_zero(r); @@ -432,7 +487,15 @@ bnc_apply_messages_to_basement_node( // No fresh messages to apply, we just apply stale messages. if (stale_ube - stale_lbi > 0) *msgs_applied = true; - struct iterate_do_bn_apply_msg_extra iter_extra = { .t = t, .bn = bn, .bnc = bnc, .gc_info = gc_info, .workdone = &workdone_this_ancestor, .stats_to_update = &stats_delta }; + struct iterate_do_bn_apply_msg_extra iter_extra = { + .t = t, + .bn = bn, + .bnc = bnc, + .gc_info = gc_info, + .workdone = &workdone_this_ancestor, + .stats_to_update = &stats_delta, + .logical_rows_delta = &logical_rows_delta + }; r = bnc->stale_message_tree.iterate_on_range(stale_lbi, stale_ube, &iter_extra); assert_zero(r); @@ -446,6 +509,7 @@ bnc_apply_messages_to_basement_node( if (stats_delta.numbytes || stats_delta.numrows) { toku_ft_update_stats(&t->ft->in_memory_stats, stats_delta); } + toku_ft_adjust_logical_row_count(t->ft, logical_rows_delta); } static void @@ -1073,7 +1137,8 @@ toku_ft_bn_apply_msg_once ( LEAFENTRY le, txn_gc_info *gc_info, uint64_t *workdone, - STAT64INFO stats_to_update + STAT64INFO stats_to_update, + int64_t *logical_rows_delta ) // Effect: Apply msg to leafentry (msn is ignored) // Calculate work done by message on leafentry and add it to caller's workdone counter. @@ -1082,26 +1147,34 @@ toku_ft_bn_apply_msg_once ( { size_t newsize=0, oldsize=0, workdone_this_le=0; LEAFENTRY new_le=0; - int64_t numbytes_delta = 0; // how many bytes of user data (not including overhead) were added or deleted from this row - int64_t numrows_delta = 0; // will be +1 or -1 or 0 (if row was added or deleted or not) + // how many bytes of user data (not including overhead) were added or + // deleted from this row + int64_t numbytes_delta = 0; + // will be +1 or -1 or 0 (if row was added or deleted or not) + int64_t numrows_delta = 0; + // will be +1, -1 or 0 if a message that was accounted for logically has + // changed in meaning such as an insert changed to an update or a delete + // changed to a noop + int64_t logical_rows_delta_le = 0; uint32_t key_storage_size = msg.kdbt()->size + sizeof(uint32_t); if (le) { oldsize = leafentry_memsize(le) + key_storage_size; } - // toku_le_apply_msg() may call bn_data::mempool_malloc_and_update_dmt() to allocate more space. - // That means le is guaranteed to not cause a sigsegv but it may point to a mempool that is - // no longer in use. We'll have to release the old mempool later. - toku_le_apply_msg( - msg, + // toku_le_apply_msg() may call bn_data::mempool_malloc_and_update_dmt() + // to allocate more space. That means le is guaranteed to not cause a + // sigsegv but it may point to a mempool that is no longer in use. + // We'll have to release the old mempool later. + logical_rows_delta_le = toku_le_apply_msg( + msg, le, &bn->data_buffer, idx, le_keylen, - gc_info, - &new_le, - &numbytes_delta - ); + gc_info, + &new_le, + &numbytes_delta); + // at this point, we cannot trust cmd->u.id.key to be valid. // The dmt may have realloced its mempool and freed the one containing key. @@ -1121,37 +1194,42 @@ toku_ft_bn_apply_msg_once ( numrows_delta = 1; } } - if (workdone) { // test programs may call with NULL + if (FT_LIKELY(workdone != NULL)) { // test programs may call with NULL *workdone += workdone_this_le; } + if (FT_LIKELY(logical_rows_delta != NULL)) { + *logical_rows_delta += logical_rows_delta_le; + } // now update stat64 statistics bn->stat64_delta.numrows += numrows_delta; bn->stat64_delta.numbytes += numbytes_delta; // the only reason stats_to_update may be null is for tests - if (stats_to_update) { + if (FT_LIKELY(stats_to_update != NULL)) { stats_to_update->numrows += numrows_delta; stats_to_update->numbytes += numbytes_delta; } - } static const uint32_t setval_tag = 0xee0ccb99; // this was gotten by doing "cat /dev/random|head -c4|od -x" to get a random number. We want to make sure that the user actually passes us the setval_extra_s that we passed in. struct setval_extra_s { uint32_t tag; bool did_set_val; - int setval_r; // any error code that setval_fun wants to return goes here. + // any error code that setval_fun wants to return goes here. + int setval_r; // need arguments for toku_ft_bn_apply_msg_once BASEMENTNODE bn; - MSN msn; // captured from original message, not currently used + // captured from original message, not currently used + MSN msn; XIDS xids; - const DBT *key; + const DBT* key; uint32_t idx; uint32_t le_keylen; LEAFENTRY le; - txn_gc_info *gc_info; - uint64_t * workdone; // set by toku_ft_bn_apply_msg_once() + txn_gc_info* gc_info; + uint64_t* workdone; // set by toku_ft_bn_apply_msg_once() STAT64INFO stats_to_update; + int64_t* logical_rows_delta; }; /* @@ -1170,29 +1248,45 @@ static void setval_fun (const DBT *new_val, void *svextra_v) { // can't leave scope until toku_ft_bn_apply_msg_once if // this is a delete DBT val; - ft_msg msg(svextra->key, - new_val ? new_val : toku_init_dbt(&val), - new_val ? FT_INSERT : FT_DELETE_ANY, - svextra->msn, svextra->xids); - toku_ft_bn_apply_msg_once(svextra->bn, msg, - svextra->idx, svextra->le_keylen, svextra->le, - svextra->gc_info, - svextra->workdone, svextra->stats_to_update); + ft_msg msg( + svextra->key, + new_val ? new_val : toku_init_dbt(&val), + new_val ? FT_INSERT : FT_DELETE_ANY, + svextra->msn, + svextra->xids); + toku_ft_bn_apply_msg_once( + svextra->bn, + msg, + svextra->idx, + svextra->le_keylen, + svextra->le, + svextra->gc_info, + svextra->workdone, + svextra->stats_to_update, + svextra->logical_rows_delta); svextra->setval_r = 0; } } -// We are already past the msn filter (in toku_ft_bn_apply_msg(), which calls do_update()), -// so capturing the msn in the setval_extra_s is not strictly required. The alternative -// would be to put a dummy msn in the messages created by setval_fun(), but preserving -// the original msn seems cleaner and it preserves accountability at a lower layer. -static int do_update(ft_update_func update_fun, const DESCRIPTOR_S *desc, BASEMENTNODE bn, const ft_msg &msg, uint32_t idx, - LEAFENTRY le, - void* keydata, - uint32_t keylen, - txn_gc_info *gc_info, - uint64_t * workdone, - STAT64INFO stats_to_update) { +// We are already past the msn filter (in toku_ft_bn_apply_msg(), which calls +// do_update()), so capturing the msn in the setval_extra_s is not strictly +// required. The alternative would be to put a dummy msn in the messages +// created by setval_fun(), but preserving the original msn seems cleaner and +// it preserves accountability at a lower layer. +static int do_update( + ft_update_func update_fun, + const DESCRIPTOR_S* desc, + BASEMENTNODE bn, + const ft_msg &msg, + uint32_t idx, + LEAFENTRY le, + void* keydata, + uint32_t keylen, + txn_gc_info* gc_info, + uint64_t* workdone, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta) { + LEAFENTRY le_for_update; DBT key; const DBT *keyp; @@ -1232,39 +1326,52 @@ static int do_update(ft_update_func update_fun, const DESCRIPTOR_S *desc, BASEME } le_for_update = le; - struct setval_extra_s setval_extra = {setval_tag, false, 0, bn, msg.msn(), msg.xids(), - keyp, idx, keylen, le_for_update, gc_info, - workdone, stats_to_update}; - // call handlerton's ft->update_fun(), which passes setval_extra to setval_fun() + struct setval_extra_s setval_extra = { + setval_tag, + false, + 0, + bn, + msg.msn(), + msg.xids(), + keyp, + idx, + keylen, + le_for_update, + gc_info, + workdone, + stats_to_update, + logical_rows_delta + }; + // call handlerton's ft->update_fun(), which passes setval_extra + // to setval_fun() FAKE_DB(db, desc); int r = update_fun( &db, keyp, vdbtp, update_function_extra, - setval_fun, &setval_extra - ); + setval_fun, + &setval_extra); if (r == 0) { r = setval_extra.setval_r; } return r; } // Should be renamed as something like "apply_msg_to_basement()." -void -toku_ft_bn_apply_msg ( - const toku::comparator &cmp, +void toku_ft_bn_apply_msg( + const toku::comparator& cmp, ft_update_func update_fun, BASEMENTNODE bn, - const ft_msg &msg, - txn_gc_info *gc_info, - uint64_t *workdone, - STAT64INFO stats_to_update - ) + const ft_msg& msg, + txn_gc_info* gc_info, + uint64_t* workdone, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta) { // Effect: // Put a msg into a leaf. -// Calculate work done by message on leafnode and add it to caller's workdone counter. +// Calculate work done by message on leafnode and add it to caller's +// workdone counter. // The leaf could end up "too big" or "too small". The caller must fix that up. -{ LEAFENTRY storeddata; void* key = NULL; uint32_t keylen = 0; @@ -1303,7 +1410,16 @@ toku_ft_bn_apply_msg ( } else { assert_zero(r); } - toku_ft_bn_apply_msg_once(bn, msg, idx, keylen, storeddata, gc_info, workdone, stats_to_update); + toku_ft_bn_apply_msg_once( + bn, + msg, + idx, + keylen, + storeddata, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); // if the insertion point is within a window of the right edge of // the leaf then it is sequential @@ -1331,12 +1447,19 @@ toku_ft_bn_apply_msg ( &storeddata, &key, &keylen, - &idx - ); + &idx); if (r == DB_NOTFOUND) break; assert_zero(r); - toku_ft_bn_apply_msg_once(bn, msg, idx, keylen, storeddata, gc_info, workdone, stats_to_update); - + toku_ft_bn_apply_msg_once( + bn, + msg, + idx, + keylen, + storeddata, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); break; } case FT_OPTIMIZE_FOR_UPGRADE: @@ -1352,13 +1475,27 @@ toku_ft_bn_apply_msg ( assert_zero(r); int deleted = 0; if (!le_is_clean(storeddata)) { //If already clean, nothing to do. - // message application code needs a key in order to determine how much - // work was done by this message. since this is a broadcast message, - // we have to create a new message whose key is the current le's key. + // message application code needs a key in order to determine + // how much work was done by this message. since this is a + // broadcast message, we have to create a new message whose + // key is the current le's key. DBT curr_keydbt; - ft_msg curr_msg(toku_fill_dbt(&curr_keydbt, curr_keyp, curr_keylen), - msg.vdbt(), msg.type(), msg.msn(), msg.xids()); - toku_ft_bn_apply_msg_once(bn, curr_msg, idx, curr_keylen, storeddata, gc_info, workdone, stats_to_update); + ft_msg curr_msg( + toku_fill_dbt(&curr_keydbt, curr_keyp, curr_keylen), + msg.vdbt(), + msg.type(), + msg.msn(), + msg.xids()); + toku_ft_bn_apply_msg_once( + bn, + curr_msg, + idx, + curr_keylen, + storeddata, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); // at this point, we cannot trust msg.kdbt to be valid. uint32_t new_dmt_size = bn->data_buffer.num_klpairs(); if (new_dmt_size != num_klpairs) { @@ -1386,13 +1523,27 @@ toku_ft_bn_apply_msg ( assert_zero(r); int deleted = 0; if (le_has_xids(storeddata, msg.xids())) { - // message application code needs a key in order to determine how much - // work was done by this message. since this is a broadcast message, - // we have to create a new message whose key is the current le's key. + // message application code needs a key in order to determine + // how much work was done by this message. since this is a + // broadcast message, we have to create a new message whose key + // is the current le's key. DBT curr_keydbt; - ft_msg curr_msg(toku_fill_dbt(&curr_keydbt, curr_keyp, curr_keylen), - msg.vdbt(), msg.type(), msg.msn(), msg.xids()); - toku_ft_bn_apply_msg_once(bn, curr_msg, idx, curr_keylen, storeddata, gc_info, workdone, stats_to_update); + ft_msg curr_msg( + toku_fill_dbt(&curr_keydbt, curr_keyp, curr_keylen), + msg.vdbt(), + msg.type(), + msg.msn(), + msg.xids()); + toku_ft_bn_apply_msg_once( + bn, + curr_msg, + idx, + curr_keylen, + storeddata, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); uint32_t new_dmt_size = bn->data_buffer.num_klpairs(); if (new_dmt_size != num_klpairs) { paranoid_invariant(new_dmt_size + 1 == num_klpairs); @@ -1424,9 +1575,33 @@ toku_ft_bn_apply_msg ( key = msg.kdbt()->data; keylen = msg.kdbt()->size; } - r = do_update(update_fun, cmp.get_descriptor(), bn, msg, idx, NULL, NULL, 0, gc_info, workdone, stats_to_update); + r = do_update( + update_fun, + cmp.get_descriptor(), + bn, + msg, + idx, + NULL, + NULL, + 0, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); } else if (r==0) { - r = do_update(update_fun, cmp.get_descriptor(), bn, msg, idx, storeddata, key, keylen, gc_info, workdone, stats_to_update); + r = do_update( + update_fun, + cmp.get_descriptor(), + bn, + msg, + idx, + storeddata, + key, + keylen, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); } // otherwise, a worse error, just return it break; } @@ -1434,6 +1609,12 @@ toku_ft_bn_apply_msg ( // apply to all leafentries. uint32_t idx = 0; uint32_t num_leafentries_before; + // This is used to avoid having the logical row count changed on apply + // of this message since it will return a negative number of the number + // of leaf entries visited and cause the ft header value to go to 0; + // This message will not change the number of rows, so just use the + // bogus value. + int64_t temp_logical_rows_delta = 0; while (idx < (num_leafentries_before = bn->data_buffer.num_klpairs())) { void* curr_key = nullptr; uint32_t curr_keylen = 0; @@ -1449,7 +1630,19 @@ toku_ft_bn_apply_msg ( // This is broken below. Have a compilation error checked // in as a reminder - r = do_update(update_fun, cmp.get_descriptor(), bn, msg, idx, storeddata, curr_key, curr_keylen, gc_info, workdone, stats_to_update); + r = do_update( + update_fun, + cmp.get_descriptor(), + bn, + msg, + idx, + storeddata, + curr_key, + curr_keylen, + gc_info, + workdone, + stats_to_update, + &temp_logical_rows_delta); assert_zero(r); if (num_leafentries_before == bn->data_buffer.num_klpairs()) { @@ -1810,24 +2003,22 @@ void toku_ftnode_leaf_run_gc(FT ft, FTNODE node) { } } -void -toku_ftnode_put_msg ( +void toku_ftnode_put_msg( const toku::comparator &cmp, ft_update_func update_fun, FTNODE node, int target_childnum, const ft_msg &msg, bool is_fresh, - txn_gc_info *gc_info, + txn_gc_info* gc_info, size_t flow_deltas[], - STAT64INFO stats_to_update - ) + STAT64INFO stats_to_update, + int64_t* logical_rows_delta) { // Effect: Push message into the subtree rooted at NODE. // If NODE is a leaf, then // put message into leaf, applying it to the leafentries // If NODE is a nonleaf, then push the message into the message buffer(s) of the relevent child(ren). // The node may become overfull. That's not our problem. -{ toku_ftnode_assert_fully_in_memory(node); // // see comments in toku_ft_leaf_apply_msg @@ -1836,26 +2027,40 @@ toku_ftnode_put_msg ( // and instead defer to these functions // if (node->height==0) { - toku_ft_leaf_apply_msg(cmp, update_fun, node, target_childnum, msg, gc_info, nullptr, stats_to_update); + toku_ft_leaf_apply_msg( + cmp, + update_fun, + node, + target_childnum, msg, + gc_info, + nullptr, + stats_to_update, + logical_rows_delta); } else { - ft_nonleaf_put_msg(cmp, node, target_childnum, msg, is_fresh, flow_deltas); + ft_nonleaf_put_msg( + cmp, + node, + target_childnum, + msg, + is_fresh, + flow_deltas); } } -// Effect: applies the message to the leaf if the appropriate basement node is in memory. -// This function is called during message injection and/or flushing, so the entire -// node MUST be in memory. +// Effect: applies the message to the leaf if the appropriate basement node is +// in memory. This function is called during message injection and/or +// flushing, so the entire node MUST be in memory. void toku_ft_leaf_apply_msg( - const toku::comparator &cmp, + const toku::comparator& cmp, ft_update_func update_fun, FTNODE node, int target_childnum, // which child to inject to, or -1 if unknown - const ft_msg &msg, - txn_gc_info *gc_info, - uint64_t *workdone, - STAT64INFO stats_to_update - ) -{ + const ft_msg& msg, + txn_gc_info* gc_info, + uint64_t* workdone, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta) { + VERIFY_NODE(t, node); toku_ftnode_assert_fully_in_memory(node); @@ -1891,34 +2096,36 @@ void toku_ft_leaf_apply_msg( BASEMENTNODE bn = BLB(node, childnum); if (msg.msn().msn > bn->max_msn_applied.msn) { bn->max_msn_applied = msg.msn(); - toku_ft_bn_apply_msg(cmp, - update_fun, - bn, - msg, - gc_info, - workdone, - stats_to_update); + toku_ft_bn_apply_msg( + cmp, + update_fun, + bn, + msg, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); } else { toku_ft_status_note_msn_discard(); } - } - else if (ft_msg_type_applies_all(msg.type())) { + } else if (ft_msg_type_applies_all(msg.type())) { for (int childnum=0; childnumn_children; childnum++) { if (msg.msn().msn > BLB(node, childnum)->max_msn_applied.msn) { BLB(node, childnum)->max_msn_applied = msg.msn(); - toku_ft_bn_apply_msg(cmp, - update_fun, - BLB(node, childnum), - msg, - gc_info, - workdone, - stats_to_update); + toku_ft_bn_apply_msg( + cmp, + update_fun, + BLB(node, childnum), + msg, + gc_info, + workdone, + stats_to_update, + logical_rows_delta); } else { toku_ft_status_note_msn_discard(); } } - } - else if (!ft_msg_type_does_nothing(msg.type())) { + } else if (!ft_msg_type_does_nothing(msg.type())) { invariant(ft_msg_type_does_nothing(msg.type())); } VERIFY_NODE(t, node); diff --git a/storage/tokudb/PerconaFT/ft/node.h b/storage/tokudb/PerconaFT/ft/node.h index 9d91049168281..ad0298e81c5de 100644 --- a/storage/tokudb/PerconaFT/ft/node.h +++ b/storage/tokudb/PerconaFT/ft/node.h @@ -382,25 +382,54 @@ enum reactivity toku_ftnode_get_leaf_reactivity(FTNODE node, uint32_t nodesize); * If k is equal to some pivot, then we return the next (to the right) * childnum. */ -int toku_ftnode_hot_next_child(FTNODE node, const DBT *k, const toku::comparator &cmp); - -void toku_ftnode_put_msg(const toku::comparator &cmp, ft_update_func update_fun, - FTNODE node, int target_childnum, - const ft_msg &msg, bool is_fresh, txn_gc_info *gc_info, - size_t flow_deltas[], STAT64INFO stats_to_update); - -void toku_ft_bn_apply_msg_once(BASEMENTNODE bn, const ft_msg &msg, uint32_t idx, - uint32_t le_keylen, LEAFENTRY le, txn_gc_info *gc_info, - uint64_t *workdonep, STAT64INFO stats_to_update); - -void toku_ft_bn_apply_msg(const toku::comparator &cmp, ft_update_func update_fun, - BASEMENTNODE bn, const ft_msg &msg, txn_gc_info *gc_info, - uint64_t *workdone, STAT64INFO stats_to_update); - -void toku_ft_leaf_apply_msg(const toku::comparator &cmp, ft_update_func update_fun, - FTNODE node, int target_childnum, - const ft_msg &msg, txn_gc_info *gc_info, - uint64_t *workdone, STAT64INFO stats_to_update); +int toku_ftnode_hot_next_child( + FTNODE node, + const DBT* k, + const toku::comparator &cmp); + +void toku_ftnode_put_msg( + const toku::comparator& cmp, + ft_update_func update_fun, + FTNODE node, + int target_childnum, + const ft_msg& msg, + bool is_fresh, + txn_gc_info* gc_info, + size_t flow_deltas[], + STAT64INFO stats_to_update, + int64_t* logical_rows_delta); + +void toku_ft_bn_apply_msg_once( + BASEMENTNODE bn, + const ft_msg& msg, + uint32_t idx, + uint32_t le_keylen, + LEAFENTRY le, + txn_gc_info* gc_info, + uint64_t* workdonep, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta); + +void toku_ft_bn_apply_msg( + const toku::comparator& cmp, + ft_update_func update_fun, + BASEMENTNODE bn, + const ft_msg& msg, + txn_gc_info* gc_info, + uint64_t* workdone, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta); + +void toku_ft_leaf_apply_msg( + const toku::comparator& cmp, + ft_update_func update_fun, + FTNODE node, + int target_childnum, + const ft_msg& msg, + txn_gc_info* gc_info, + uint64_t* workdone, + STAT64INFO stats_to_update, + int64_t* logical_rows_delta); // // Message management for orthopush diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc index a7bc29492768c..49d4368a3ab83 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc +++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc @@ -323,6 +323,13 @@ int deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version) fanout = rbuf_int(rb); } + uint64_t on_disk_logical_rows; + on_disk_logical_rows = (uint64_t)-1; + if (ft->layout_version_read_from_disk >= FT_LAYOUT_VERSION_29) { + on_disk_logical_rows = rbuf_ulonglong(rb); + } + ft->in_memory_logical_rows = on_disk_logical_rows; + (void) rbuf_int(rb); //Read in checksum and ignore (already verified). if (rb->ndone != rb->size) { fprintf(stderr, "Header size did not match contents.\n"); @@ -357,7 +364,8 @@ int deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version) .count_of_optimize_in_progress = count_of_optimize_in_progress, .count_of_optimize_in_progress_read_from_disk = count_of_optimize_in_progress, .msn_at_start_of_last_completed_optimize = msn_at_start_of_last_completed_optimize, - .on_disk_stats = on_disk_stats + .on_disk_stats = on_disk_stats, + .on_disk_logical_rows = on_disk_logical_rows }; XMEMDUP(ft->h, &h); } @@ -408,6 +416,8 @@ serialize_ft_min_size (uint32_t version) { size_t size = 0; switch(version) { + case FT_LAYOUT_VERSION_29: + size += sizeof(uint64_t); // logrows in ft case FT_LAYOUT_VERSION_28: size += sizeof(uint32_t); // fanout in ft case FT_LAYOUT_VERSION_27: @@ -754,6 +764,7 @@ void toku_serialize_ft_to_wbuf ( wbuf_MSN(wbuf, h->highest_unused_msn_for_upgrade); wbuf_MSN(wbuf, h->max_msn_in_ft); wbuf_int(wbuf, h->fanout); + wbuf_ulonglong(wbuf, h->on_disk_logical_rows); uint32_t checksum = toku_x1764_finish(&wbuf->checksum); wbuf_int(wbuf, checksum); lazy_assert(wbuf->ndone == wbuf->size); diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft_layout_version.h b/storage/tokudb/PerconaFT/ft/serialize/ft_layout_version.h index 72b6882bc06c1..9407a5683374d 100644 --- a/storage/tokudb/PerconaFT/ft/serialize/ft_layout_version.h +++ b/storage/tokudb/PerconaFT/ft/serialize/ft_layout_version.h @@ -68,6 +68,7 @@ enum ft_layout_version_e { FT_LAYOUT_VERSION_26 = 26, // Hojo: basements store key/vals separately on disk for fixed klpair length BNs FT_LAYOUT_VERSION_27 = 27, // serialize message trees with nonleaf buffers to avoid key, msn sort on deserialize FT_LAYOUT_VERSION_28 = 28, // Add fanout to ft_header + FT_LAYOUT_VERSION_29 = 29, // Add logrows to ft_header FT_NEXT_VERSION, // the version after the current version FT_LAYOUT_VERSION = FT_NEXT_VERSION-1, // A hack so I don't have to change this line. FT_LAYOUT_MIN_SUPPORTED_VERSION = FT_LAYOUT_VERSION_13, // Minimum version supported diff --git a/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt index d9f0da6a1b0a8..0098b6091be6c 100644 --- a/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt @@ -29,7 +29,7 @@ if(BUILD_TESTING OR BUILD_FT_TESTS) add_test(ft/logcursor-bw echo "logcursor-bw must be run manually (needs logs to iterate over).") foreach(test ${tests}) - add_executable(${test} ${test}) + add_executable(${test} ${test}.cc) target_link_libraries(${test} ft ${LIBTOKUPORTABILITY}) set_target_properties(${test} PROPERTIES POSITION_INDEPENDENT_CODE ON) add_space_separated_property(TARGET ${test} COMPILE_FLAGS -fvisibility=hidden) diff --git a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc index 663bbf3beb29c..c83517b5f64ca 100644 --- a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc +++ b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc @@ -74,7 +74,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) // apply an insert to the leaf node txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); - toku_ft_bn_apply_msg_once(BLB(leafnode,0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); leafnode->max_msn_applied_to_node_on_disk = msn; diff --git a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc index 737c3556ad6fb..d960825805469 100644 --- a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc +++ b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc @@ -82,46 +82,82 @@ append_leaf(FT_HANDLE ft, FTNODE leafnode, void *key, uint32_t keylen, void *val ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_leaf_apply_msg(ft->ft->cmp, ft->ft->update_fun, leafnode, -1, msg, &gc_info, nullptr, nullptr); + toku_ft_leaf_apply_msg( + ft->ft->cmp, + ft->ft->update_fun, + leafnode, + -1, + msg, + &gc_info, + nullptr, + nullptr, + nullptr); { - int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair); - assert(r==0); - assert(pair.call_count==1); + int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair); + assert(r==0); + assert(pair.call_count==1); } ft_msg badmsg(&thekey, &badval, FT_INSERT, msn, toku_xids_get_root_xids()); - toku_ft_leaf_apply_msg(ft->ft->cmp, ft->ft->update_fun, leafnode, -1, badmsg, &gc_info, nullptr, nullptr); + toku_ft_leaf_apply_msg( + ft->ft->cmp, + ft->ft->update_fun, + leafnode, + -1, + badmsg, + &gc_info, + nullptr, + nullptr, + nullptr); // message should be rejected for duplicate msn, row should still have original val { - int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair); - assert(r==0); - assert(pair.call_count==2); + int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair); + assert(r==0); + assert(pair.call_count==2); } // now verify that message with proper msn gets through msn = next_dummymsn(); ft->ft->h->max_msn_in_ft = msn; ft_msg msg2(&thekey, &val2, FT_INSERT, msn, toku_xids_get_root_xids()); - toku_ft_leaf_apply_msg(ft->ft->cmp, ft->ft->update_fun, leafnode, -1, msg2, &gc_info, nullptr, nullptr); + toku_ft_leaf_apply_msg( + ft->ft->cmp, + ft->ft->update_fun, + leafnode, + -1, + msg2, + &gc_info, + nullptr, + nullptr, + nullptr); // message should be accepted, val should have new value { - int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair2); - assert(r==0); - assert(pair2.call_count==1); + int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair2); + assert(r==0); + assert(pair2.call_count==1); } // now verify that message with lesser (older) msn is rejected msn.msn = msn.msn - 10; ft_msg msg3(&thekey, &badval, FT_INSERT, msn, toku_xids_get_root_xids()); - toku_ft_leaf_apply_msg(ft->ft->cmp, ft->ft->update_fun, leafnode, -1, msg3, &gc_info, nullptr, nullptr); + toku_ft_leaf_apply_msg( + ft->ft->cmp, + ft->ft->update_fun, + leafnode, + -1, + msg3, + &gc_info, + nullptr, + nullptr, + nullptr); // message should be rejected, val should still have value in pair2 { - int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair2); - assert(r==0); - assert(pair2.call_count==2); + int r = toku_ft_lookup(ft, &thekey, lookup_checkf, &pair2); + assert(r==0); + assert(pair2.call_count==2); } // dont forget to dirty the node diff --git a/storage/tokudb/PerconaFT/ft/tests/orthopush-flush.cc b/storage/tokudb/PerconaFT/ft/tests/orthopush-flush.cc index 055a38e5f6d98..393fb88ac2e77 100644 --- a/storage/tokudb/PerconaFT/ft/tests/orthopush-flush.cc +++ b/storage/tokudb/PerconaFT/ft/tests/orthopush-flush.cc @@ -137,8 +137,24 @@ insert_random_message_to_bn( *keyp = toku_xmemdup(keydbt->data, keydbt->size); ft_msg msg(keydbt, valdbt, FT_INSERT, msn, xids); int64_t numbytes; - toku_le_apply_msg(msg, NULL, NULL, 0, keydbt->size, &non_mvcc_gc_info, save, &numbytes); - toku_ft_bn_apply_msg(t->ft->cmp, t->ft->update_fun, blb, msg, &non_mvcc_gc_info, NULL, NULL); + toku_le_apply_msg( + msg, + NULL, + NULL, + 0, + keydbt->size, + &non_mvcc_gc_info, + save, + &numbytes); + toku_ft_bn_apply_msg( + t->ft->cmp, + t->ft->update_fun, + blb, + msg, + &non_mvcc_gc_info, + NULL, + NULL, + NULL); if (msn.msn > blb->max_msn_applied.msn) { blb->max_msn_applied = msn; } @@ -182,12 +198,36 @@ insert_same_message_to_bns( *keyp = toku_xmemdup(keydbt->data, keydbt->size); ft_msg msg(keydbt, valdbt, FT_INSERT, msn, xids); int64_t numbytes; - toku_le_apply_msg(msg, NULL, NULL, 0, keydbt->size, &non_mvcc_gc_info, save, &numbytes); - toku_ft_bn_apply_msg(t->ft->cmp, t->ft->update_fun, blb1, msg, &non_mvcc_gc_info, NULL, NULL); + toku_le_apply_msg( + msg, + NULL, + NULL, + 0, + keydbt->size, + &non_mvcc_gc_info, + save, + &numbytes); + toku_ft_bn_apply_msg( + t->ft->cmp, + t->ft->update_fun, + blb1, + msg, + &non_mvcc_gc_info, + NULL, + NULL, + NULL); if (msn.msn > blb1->max_msn_applied.msn) { blb1->max_msn_applied = msn; } - toku_ft_bn_apply_msg(t->ft->cmp, t->ft->update_fun, blb2, msg, &non_mvcc_gc_info, NULL, NULL); + toku_ft_bn_apply_msg( + t->ft->cmp, + t->ft->update_fun, + blb2, + msg, + &non_mvcc_gc_info, + NULL, + NULL, + NULL); if (msn.msn > blb2->max_msn_applied.msn) { blb2->max_msn_applied = msn; } @@ -619,7 +659,16 @@ flush_to_leaf(FT_HANDLE t, bool make_leaf_up_to_date, bool use_flush) { if (make_leaf_up_to_date) { for (i = 0; i < num_parent_messages; ++i) { if (!parent_messages_is_fresh[i]) { - toku_ft_leaf_apply_msg(t->ft->cmp, t->ft->update_fun, child, -1, *parent_messages[i], &non_mvcc_gc_info, NULL, NULL); + toku_ft_leaf_apply_msg( + t->ft->cmp, + t->ft->update_fun, + child, + -1, + *parent_messages[i], + &non_mvcc_gc_info, + NULL, + NULL, + NULL); } } for (i = 0; i < 8; ++i) { @@ -842,7 +891,16 @@ flush_to_leaf_with_keyrange(FT_HANDLE t, bool make_leaf_up_to_date) { for (i = 0; i < num_parent_messages; ++i) { if (dummy_cmp(parent_messages[i]->kdbt(), &childkeys[7]) <= 0 && !parent_messages_is_fresh[i]) { - toku_ft_leaf_apply_msg(t->ft->cmp, t->ft->update_fun, child, -1, *parent_messages[i], &non_mvcc_gc_info, NULL, NULL); + toku_ft_leaf_apply_msg( + t->ft->cmp, + t->ft->update_fun, + child, + -1, + *parent_messages[i], + &non_mvcc_gc_info, + NULL, + NULL, + NULL); } } for (i = 0; i < 8; ++i) { @@ -1045,8 +1103,26 @@ compare_apply_and_flush(FT_HANDLE t, bool make_leaf_up_to_date) { if (make_leaf_up_to_date) { for (i = 0; i < num_parent_messages; ++i) { if (!parent_messages_is_fresh[i]) { - toku_ft_leaf_apply_msg(t->ft->cmp, t->ft->update_fun, child1, -1, *parent_messages[i], &non_mvcc_gc_info, NULL, NULL); - toku_ft_leaf_apply_msg(t->ft->cmp, t->ft->update_fun, child2, -1, *parent_messages[i], &non_mvcc_gc_info, NULL, NULL); + toku_ft_leaf_apply_msg( + t->ft->cmp, + t->ft->update_fun, + child1, + -1, + *parent_messages[i], + &non_mvcc_gc_info, + NULL, + NULL, + NULL); + toku_ft_leaf_apply_msg( + t->ft->cmp, + t->ft->update_fun, + child2, + -1, + *parent_messages[i], + &non_mvcc_gc_info, + NULL, + NULL, + NULL); } } for (i = 0; i < 8; ++i) { diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc index 68fac0e6a9c1c..40af5dab7ad65 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc @@ -78,7 +78,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) // apply an insert to the leaf node ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode, 0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // Create bad tree (don't do following): // leafnode->max_msn_applied_to_node = msn; diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc index 49b2b8a6c21f9..37054eb119adf 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc @@ -65,7 +65,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) MSN msn = next_dummymsn(); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode, 0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // dont forget to dirty the node leafnode->dirty = 1; diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc index 72c4063f51f1e..42e8288443272 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc @@ -66,7 +66,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) MSN msn = next_dummymsn(); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode, 0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // dont forget to dirty the node leafnode->dirty = 1; diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc index f569f502dc8cf..b3e8663ed3ba3 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc @@ -65,7 +65,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) MSN msn = next_dummymsn(); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode, 0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // dont forget to dirty the node leafnode->dirty = 1; diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc index 3a6db8ee4de1d..df5c21ca64e16 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc @@ -66,7 +66,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) MSN msn = next_dummymsn(); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode,0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // dont forget to dirty the node leafnode->dirty = 1; diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc index 4392887718f11..4eccb06c1f352 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc @@ -68,7 +68,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) MSN msn = next_dummymsn(); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode, 0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // dont forget to dirty the node leafnode->dirty = 1; diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc index e3167bd3dc111..4492ea9364a91 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc @@ -65,7 +65,16 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) MSN msn = next_dummymsn(); ft_msg msg(&thekey, &theval, FT_INSERT, msn, toku_xids_get_root_xids()); txn_gc_info gc_info(nullptr, TXNID_NONE, TXNID_NONE, false); - toku_ft_bn_apply_msg_once(BLB(leafnode, 0), msg, idx, keylen, NULL, &gc_info, NULL, NULL); + toku_ft_bn_apply_msg_once( + BLB(leafnode, 0), + msg, + idx, + keylen, + NULL, + &gc_info, + NULL, + NULL, + NULL); // dont forget to dirty the node leafnode->dirty = 1; diff --git a/storage/tokudb/PerconaFT/ft/txn/rollback-apply.cc b/storage/tokudb/PerconaFT/ft/txn/rollback-apply.cc index 6a8c0d45b4536..df830afd0df68 100644 --- a/storage/tokudb/PerconaFT/ft/txn/rollback-apply.cc +++ b/storage/tokudb/PerconaFT/ft/txn/rollback-apply.cc @@ -186,6 +186,7 @@ int toku_rollback_commit(TOKUTXN txn, LSN lsn) { // Append the list to the front of the parent. if (child_log->oldest_logentry) { // There are some entries, so link them in. + parent_log->dirty = true; child_log->oldest_logentry->prev = parent_log->newest_logentry; if (!parent_log->oldest_logentry) { parent_log->oldest_logentry = child_log->oldest_logentry; diff --git a/storage/tokudb/PerconaFT/ft/txn/txn.cc b/storage/tokudb/PerconaFT/ft/txn/txn.cc index 57f3c10562843..dd03073a3ec4e 100644 --- a/storage/tokudb/PerconaFT/ft/txn/txn.cc +++ b/storage/tokudb/PerconaFT/ft/txn/txn.cc @@ -248,11 +248,24 @@ static txn_child_manager tcm; .xa_xid = {0, 0, 0, ""}, .progress_poll_fun = NULL, .progress_poll_fun_extra = NULL, - .txn_lock = TOKU_MUTEX_INITIALIZER, + + // You cannot initialize txn_lock a TOKU_MUTEX_INITIALIZER, because we + // will initialize it in the code below, and it cannot already + // be initialized at that point. Also, in general, you don't + // get to use PTHREAD_MUTEX_INITALIZER (which is what is inside + // TOKU_MUTEX_INITIALIZER) except in static variables, and this + // is initializing an auto variable. + // + // And we cannot simply avoid initializing these fields + // because, although it avoids -Wmissing-field-initializer + // errors under gcc, it gets other errors about non-trivial + // designated initializers not being supported. + + .txn_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER .open_fts = open_fts, .roll_info = roll_info, - .state_lock = TOKU_MUTEX_INITIALIZER, - .state_cond = TOKU_COND_INITIALIZER, + .state_lock = ZERO_MUTEX_INITIALIZER, // Not TOKU_MUTEX_INITIALIZER + .state_cond = ZERO_COND_INITIALIZER, // Not TOKU_COND_INITIALIZER .state = TOKUTXN_LIVE, .num_pin = 0, .client_id = 0, diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc index 551fd32b8d55f..805c60d30beea 100644 --- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc +++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc @@ -45,7 +45,15 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #include "ft/txn/txn_manager.h" #include "ft/txn/rollback.h" #include "util/omt.h" +//this is only for testing +static void (* test_txn_sync_callback) (uint64_t, void *) = NULL; +static void * test_txn_sync_callback_extra = NULL; + +void set_test_txn_sync_callback(void (*cb) (uint64_t, void *), void *extra) { + test_txn_sync_callback = cb; + test_txn_sync_callback_extra = extra; +} bool garbage_collection_debug = false; static bool txn_records_snapshot(TXN_SNAPSHOT_TYPE snapshot_type, struct tokutxn *parent) { @@ -525,14 +533,19 @@ void toku_txn_manager_handle_snapshot_create_for_child_txn( XMALLOC(txn->live_root_txn_list); txn_manager_lock(txn_manager); txn_manager_create_snapshot_unlocked(txn_manager, txn); - txn_manager_unlock(txn_manager); } else { inherit_snapshot_from_parent(txn); } - if (copies_snapshot) { - setup_live_root_txn_list(&txn_manager->live_root_ids, txn->live_root_txn_list); - } + + toku_debug_txn_sync(pthread_self()); + + if (copies_snapshot) { + if(!records_snapshot) + txn_manager_lock(txn_manager); + setup_live_root_txn_list(&txn_manager->live_root_ids, txn->live_root_txn_list); + txn_manager_unlock(txn_manager); + } } void toku_txn_manager_handle_snapshot_destroy_for_child_txn( diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.h b/storage/tokudb/PerconaFT/ft/txn/txn_manager.h index 658c6f9aecd0b..28fa1ac10b6f9 100644 --- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.h +++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.h @@ -43,6 +43,15 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #include "ft/txn/txn.h" +void set_test_txn_sync_callback(void (*) (uint64_t, void*), void*); +#define toku_test_txn_sync_callback(a) ((test_txn_sync_callback)? test_txn_sync_callback( a,test_txn_sync_callback_extra) : (void) 0) + +#if TOKU_DEBUG_TXN_SYNC +#define toku_debug_txn_sync(a) toku_test_txn_sync_callback(a) +#else +#define toku_debug_txn_sync(a) ((void) 0) +#endif + typedef struct txn_manager *TXN_MANAGER; struct referenced_xid_tuple { diff --git a/storage/tokudb/PerconaFT/ft/ule.cc b/storage/tokudb/PerconaFT/ft/ule.cc index 573c4488f705e..ac393fbf17991 100644 --- a/storage/tokudb/PerconaFT/ft/ule.cc +++ b/storage/tokudb/PerconaFT/ft/ule.cc @@ -73,12 +73,11 @@ void toku_le_get_status(LE_STATUS statp) { *statp = le_status; } -/////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Accessor functions used by outside world (e.g. indexer) // -ULEHANDLE -toku_ule_create(LEAFENTRY le) { +ULEHANDLE toku_ule_create(LEAFENTRY le) { ULE XMALLOC(ule_p); le_unpack(ule_p, le); return (ULEHANDLE) ule_p; @@ -89,7 +88,7 @@ void toku_ule_free(ULEHANDLE ule_p) { toku_free(ule_p); } -/////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // // Question: Can any software outside this file modify or read a leafentry? // If so, is it worthwhile to put it all here? @@ -117,27 +116,43 @@ const UXR_S committed_delete = { // Local functions: -static void msg_init_empty_ule(ULE ule); -static void msg_modify_ule(ULE ule, const ft_msg &msg); -static void ule_init_empty_ule(ULE ule); +static inline void msg_init_empty_ule(ULE ule); +static int64_t msg_modify_ule(ULE ule, const ft_msg &msg); +static inline void ule_init_empty_ule(ULE ule); static void ule_do_implicit_promotions(ULE ule, XIDS xids); -static void ule_try_promote_provisional_outermost(ULE ule, TXNID oldest_possible_live_xid); +static void ule_try_promote_provisional_outermost( + ULE ule, + TXNID oldest_possible_live_xid); static void ule_promote_provisional_innermost_to_index(ULE ule, uint32_t index); static void ule_promote_provisional_innermost_to_committed(ULE ule); -static void ule_apply_insert(ULE ule, XIDS xids, uint32_t vallen, void * valp); -static void ule_apply_delete(ULE ule, XIDS xids); -static void ule_prepare_for_new_uxr(ULE ule, XIDS xids); -static void ule_apply_abort(ULE ule, XIDS xids); +static inline int64_t ule_apply_insert_no_overwrite( + ULE ule, + XIDS xids, + uint32_t vallen, + void* valp); +static inline int64_t ule_apply_insert( + ULE ule, + XIDS xids, + uint32_t vallen, + void* valp); +static inline int64_t ule_apply_delete(ULE ule, XIDS xids); +static inline void ule_prepare_for_new_uxr(ULE ule, XIDS xids); +static inline int64_t ule_apply_abort(ULE ule, XIDS xids); static void ule_apply_broadcast_commit_all (ULE ule); static void ule_apply_commit(ULE ule, XIDS xids); -static void ule_push_insert_uxr(ULE ule, bool is_committed, TXNID xid, uint32_t vallen, void * valp); -static void ule_push_delete_uxr(ULE ule, bool is_committed, TXNID xid); -static void ule_push_placeholder_uxr(ULE ule, TXNID xid); -static UXR ule_get_innermost_uxr(ULE ule); -static UXR ule_get_first_empty_uxr(ULE ule); -static void ule_remove_innermost_uxr(ULE ule); -static TXNID ule_get_innermost_xid(ULE ule); -static TXNID ule_get_xid(ULE ule, uint32_t index); +static inline void ule_push_insert_uxr( + ULE ule, + bool is_committed, + TXNID xid, + uint32_t vallen, + void* valp); +static inline void ule_push_delete_uxr(ULE ule, bool is_committed, TXNID xid); +static inline void ule_push_placeholder_uxr(ULE ule, TXNID xid); +static inline UXR ule_get_innermost_uxr(ULE ule); +static inline UXR ule_get_first_empty_uxr(ULE ule); +static inline void ule_remove_innermost_uxr(ULE ule); +static inline TXNID ule_get_innermost_xid(ULE ule); +static inline TXNID ule_get_xid(ULE ule, uint32_t index); static void ule_remove_innermost_placeholders(ULE ule); static void ule_add_placeholders(ULE ule, XIDS xids); static void ule_optimize(ULE ule, XIDS xids); @@ -153,6 +168,30 @@ static inline size_t uxr_unpack_type_and_length(UXR uxr, uint8_t *p); static inline size_t uxr_unpack_length_and_bit(UXR uxr, uint8_t *p); static inline size_t uxr_unpack_data(UXR uxr, uint8_t *p); +#if 0 +static void ule_print(ULE ule, const char* note) { + fprintf(stderr, "%s : ULE[0x%p]\n", note, ule); + fprintf(stderr, " num_puxrs[%u]\n", ule->num_puxrs); + fprintf(stderr, " num_cuxrs[%u]\n", ule->num_cuxrs); + fprintf(stderr, " innermost[%u]\n", ule->num_cuxrs + ule->num_puxrs - 1); + fprintf(stderr, " first_empty[%u]\n", ule->num_cuxrs + ule->num_puxrs); + + uint32_t num_uxrs = ule->num_cuxrs + ule->num_puxrs - 1; + for (uint32_t uxr_num = 0; uxr_num <= num_uxrs; uxr_num++) { + UXR uxr = &(ule->uxrs[uxr_num]); + fprintf(stderr, " uxr[%u]\n", uxr_num); + switch (uxr->type) { + case 0: fprintf(stderr, " type[NONE]\n"); break; + case 1: fprintf(stderr, " type[INSERT]\n"); break; + case 2: fprintf(stderr, " type[DELETE]\n"); break; + case 3: fprintf(stderr, " type[PLACEHOLDER]\n"); break; + default: fprintf(stderr, " type[WHAT??]\n"); break; + } + fprintf(stderr, " xid[%lu]\n", uxr->xid); + } +} +#endif + static void get_space_for_le( bn_data* data_buffer, uint32_t idx, @@ -162,21 +201,30 @@ static void get_space_for_le( uint32_t old_le_size, size_t size, LEAFENTRY* new_le_space, - void **const maybe_free - ) -{ + void** const maybe_free) { + if (data_buffer == nullptr) { CAST_FROM_VOIDP(*new_le_space, toku_xmalloc(size)); - } - else { + } else if (old_le_size > 0) { // this means we are overwriting something - if (old_le_size > 0) { - data_buffer->get_space_for_overwrite(idx, keyp, keylen, old_keylen, old_le_size, size, new_le_space, maybe_free); - } + data_buffer->get_space_for_overwrite( + idx, + keyp, + keylen, + old_keylen, + old_le_size, + size, + new_le_space, + maybe_free); + } else { // this means we are inserting something new - else { - data_buffer->get_space_for_insert(idx, keyp, keylen, size, new_le_space, maybe_free); - } + data_buffer->get_space_for_insert( + idx, + keyp, + keylen, + size, + new_le_space, + maybe_free); } } @@ -185,15 +233,13 @@ static void get_space_for_le( // Garbage collection related functions // -static TXNID -get_next_older_txnid(TXNID xc, const xid_omt_t &omt) { +static TXNID get_next_older_txnid(TXNID xc, const xid_omt_t &omt) { int r; TXNID xid; r = omt.find(xc, -1, &xid, nullptr); if (r==0) { invariant(xid < xc); //sanity check - } - else { + } else { invariant(r==DB_NOTFOUND); xid = TXNID_NONE; } @@ -201,17 +247,32 @@ get_next_older_txnid(TXNID xc, const xid_omt_t &omt) { } // -// This function returns true if live transaction TL1 is allowed to read a value committed by -// transaction xc, false otherwise. +// This function returns true if live transaction TL1 is allowed to read a +// value committed by transaction xc, false otherwise. // -static bool -xid_reads_committed_xid(TXNID tl1, TXNID xc, const xid_omt_t &snapshot_txnids, const rx_omt_t &referenced_xids) { +static bool xid_reads_committed_xid( + TXNID tl1, + TXNID xc, + const xid_omt_t& snapshot_txnids, + const rx_omt_t& referenced_xids) { + bool rval; - if (tl1 < xc) rval = false; //cannot read a newer txn - else { - TXNID x = toku_get_youngest_live_list_txnid_for(xc, snapshot_txnids, referenced_xids); - if (x == TXNID_NONE) rval = true; //Not in ANY live list, tl1 can read it. - else rval = tl1 > x; //Newer than the 'newest one that has it in live list' + if (tl1 < xc) { + rval = false; //cannot read a newer txn + } else { + TXNID x = + toku_get_youngest_live_list_txnid_for( + xc, + snapshot_txnids, + referenced_xids); + + if (x == TXNID_NONE) { + //Not in ANY live list, tl1 can read it. + rval = true; + } else { + //Newer than the 'newest one that has it in live list' + rval = tl1 > x; + } // we know tl1 > xc // we know x > xc // if tl1 == x, then we do not read, because tl1 is in xc's live list @@ -228,8 +289,7 @@ xid_reads_committed_xid(TXNID tl1, TXNID xc, const xid_omt_t &snapshot_txnids, c // than oldest_referenced_xid. All elements below this entry are garbage, // so we get rid of them. // -static void -ule_simple_garbage_collection(ULE ule, txn_gc_info *gc_info) { +static void ule_simple_garbage_collection(ULE ule, txn_gc_info *gc_info) { if (ule->num_cuxrs == 1) { return; } @@ -240,7 +300,8 @@ ule_simple_garbage_collection(ULE ule, txn_gc_info *gc_info) { // uxr with a txnid that is less than oldest_referenced_xid for (uint32_t i = 0; i < ule->num_cuxrs; i++) { curr_index = ule->num_cuxrs - i - 1; - if (ule->uxrs[curr_index].xid < gc_info->oldest_referenced_xid_for_simple_gc) { + if (ule->uxrs[curr_index].xid < + gc_info->oldest_referenced_xid_for_simple_gc) { break; } } @@ -250,12 +311,15 @@ ule_simple_garbage_collection(ULE ule, txn_gc_info *gc_info) { curr_index = ule->num_cuxrs - 1; } - // curr_index is now set to the youngest uxr older than oldest_referenced_xid - // so if it's not the bottom of the stack.. + // curr_index is now set to the youngest uxr older than + // oldest_referenced_xid so if it's not the bottom of the stack.. if (curr_index != 0) { // ..then we need to get rid of the entries below curr_index uint32_t num_entries = ule->num_cuxrs + ule->num_puxrs - curr_index; - memmove(&ule->uxrs[0], &ule->uxrs[curr_index], num_entries * sizeof(ule->uxrs[0])); + memmove( + &ule->uxrs[0], + &ule->uxrs[curr_index], + num_entries * sizeof(ule->uxrs[0])); ule->uxrs[0].xid = TXNID_NONE; // New 'bottom of stack' loses its TXNID ule->num_cuxrs -= curr_index; } @@ -264,8 +328,12 @@ ule_simple_garbage_collection(ULE ule, txn_gc_info *gc_info) { // TODO: Clean this up extern bool garbage_collection_debug; -static void -ule_garbage_collect(ULE ule, const xid_omt_t &snapshot_xids, const rx_omt_t &referenced_xids, const xid_omt_t &live_root_txns) { +static void ule_garbage_collect( + ULE ule, + const xid_omt_t& snapshot_xids, + const rx_omt_t& referenced_xids, + const xid_omt_t& live_root_txns) { + if (ule->num_cuxrs == 1) { return; } @@ -289,10 +357,12 @@ ule_garbage_collect(ULE ule, const xid_omt_t &snapshot_xids, const rx_omt_t &ref // If we find that the committed transaction is in the live list, // then xc is really in the process of being committed. It has not // been fully committed. As a result, our assumption that transactions - // newer than what is currently in these OMTs will read the top of the stack - // is not necessarily accurate. Transactions may read what is just below xc. - // As a result, we must mark what is just below xc as necessary and move on. - // This issue was found while testing flusher threads, and was fixed for #3979 + // newer than what is currently in these OMTs will read the top of the + // stack is not necessarily accurate. Transactions may read what is + // just below xc. + // As a result, we must mark what is just below xc as necessary and + // move on. This issue was found while testing flusher threads, and was + // fixed for #3979 // bool is_xc_live = toku_is_txn_in_live_root_txn_list(live_root_txns, xc); if (is_xc_live) { @@ -300,13 +370,19 @@ ule_garbage_collect(ULE ule, const xid_omt_t &snapshot_xids, const rx_omt_t &ref continue; } - tl1 = toku_get_youngest_live_list_txnid_for(xc, snapshot_xids, referenced_xids); + tl1 = + toku_get_youngest_live_list_txnid_for( + xc, + snapshot_xids, + referenced_xids); - // if tl1 == xc, that means xc should be live and show up in live_root_txns, which we check above. + // if tl1 == xc, that means xc should be live and show up in + // live_root_txns, which we check above. invariant(tl1 != xc); if (tl1 == TXNID_NONE) { - // set tl1 to youngest live transaction older than ule->uxrs[curr_committed_entry]->xid + // set tl1 to youngest live transaction older than + // ule->uxrs[curr_committed_entry]->xid tl1 = get_next_older_txnid(xc, snapshot_xids); if (tl1 == TXNID_NONE) { // remainder is garbage, we're done @@ -314,8 +390,13 @@ ule_garbage_collect(ULE ule, const xid_omt_t &snapshot_xids, const rx_omt_t &ref } } if (garbage_collection_debug) { - int r = snapshot_xids.find_zero(tl1, nullptr, nullptr); - invariant_zero(r); // make sure that the txn you are claiming is live is actually live + int r = + snapshot_xids.find_zero( + tl1, + nullptr, + nullptr); + // make sure that the txn you are claiming is live is actually live + invariant_zero(r); } // // tl1 should now be set @@ -323,7 +404,11 @@ ule_garbage_collect(ULE ule, const xid_omt_t &snapshot_xids, const rx_omt_t &ref curr_committed_entry--; while (curr_committed_entry > 0) { xc = ule->uxrs[curr_committed_entry].xid; - if (xid_reads_committed_xid(tl1, xc, snapshot_xids, referenced_xids)) { + if (xid_reads_committed_xid( + tl1, + xc, + snapshot_xids, + referenced_xids)) { break; } curr_committed_entry--; @@ -343,7 +428,10 @@ ule_garbage_collect(ULE ule, const xid_omt_t &snapshot_xids, const rx_omt_t &ref ule->uxrs[0].xid = TXNID_NONE; //New 'bottom of stack' loses its TXNID if (first_free != ule->num_cuxrs) { // Shift provisional values - memmove(&ule->uxrs[first_free], &ule->uxrs[ule->num_cuxrs], ule->num_puxrs * sizeof(ule->uxrs[0])); + memmove( + &ule->uxrs[first_free], + &ule->uxrs[ule->num_cuxrs], + ule->num_puxrs * sizeof(ule->uxrs[0])); } ule->num_cuxrs = saved; } @@ -367,29 +455,42 @@ enum { ULE_MIN_MEMSIZE_TO_FORCE_GC = 1024 * 1024 }; -///////////////////////////////////////////////////////////////////////////////// -// This is the big enchilada. (Bring Tums.) Note that this level of abstraction -// has no knowledge of the inner structure of either leafentry or msg. It makes -// calls into the next lower layer (msg_xxx) which handles messages. +//////////////////////////////////////////////////////////////////////////////// +// This is the big enchilada. (Bring Tums.) Note that this level of +// abstraction has no knowledge of the inner structure of either leafentry or +// msg. It makes calls into the next lower layer (msg_xxx) which handles +// messages. // // NOTE: This is the only function (at least in this body of code) that modifies // a leafentry. // NOTE: It is the responsibility of the caller to make sure that the key is set // in the FT_MSG, as it will be used to store the data in the data_buffer // -// Return 0 on success. -// If the leafentry is destroyed it sets *new_leafentry_p to NULL. -// Otehrwise the new_leafentry_p points at the new leaf entry. -// As of October 2011, this function always returns 0. -void -toku_le_apply_msg(const ft_msg &msg, - LEAFENTRY old_leafentry, // NULL if there was no stored data. - bn_data* data_buffer, // bn_data storing leafentry, if NULL, means there is no bn_data - uint32_t idx, // index in data_buffer where leafentry is stored (and should be replaced - uint32_t old_keylen, // length of the any key in data_buffer - txn_gc_info *gc_info, - LEAFENTRY *new_leafentry_p, - int64_t * numbytes_delta_p) { // change in total size of key and val, not including any overhead +// Returns -1, 0, or 1 that identifies the change in logical row count needed +// based on the results of the message application. For example, if a delete +// finds no logical leafentry or if an insert finds a duplicate and is +// converted to an update. +// +// old_leafentry - NULL if there was no stored data. +// data_buffer - bn_data storing leafentry, if NULL, means there is no bn_data +// idx - index in data_buffer where leafentry is stored +// (and should be replaced) +// old_keylen - length of the any key in data_buffer +// new_leafentry_p - If the leafentry is destroyed it sets *new_leafentry_p +// to NULL. Otherwise the new_leafentry_p points at the new +// leaf entry. +// numbytes_delta_p - change in total size of key and val, not including any +// overhead +int64_t toku_le_apply_msg( + const ft_msg& msg, + LEAFENTRY old_leafentry, + bn_data* data_buffer, + uint32_t idx, + uint32_t old_keylen, + txn_gc_info* gc_info, + LEAFENTRY* new_leafentry_p, + int64_t* numbytes_delta_p) { + invariant_notnull(gc_info); paranoid_invariant_notnull(new_leafentry_p); ULE_S ule; @@ -397,6 +498,7 @@ toku_le_apply_msg(const ft_msg &msg, int64_t newnumbytes = 0; uint64_t oldmemsize = 0; uint32_t keylen = msg.kdbt()->size; + int32_t rowcountdelta = 0; if (old_leafentry == NULL) { msg_init_empty_ule(&ule); @@ -405,49 +507,62 @@ toku_le_apply_msg(const ft_msg &msg, le_unpack(&ule, old_leafentry); // otherwise unpack leafentry oldnumbytes = ule_get_innermost_numbytes(&ule, keylen); } - msg_modify_ule(&ule, msg); // modify unpacked leafentry - // - we may be able to immediately promote the newly-apllied outermost provisonal uxr - // - either way, run simple gc first, and then full gc if there are still some committed uxrs. - ule_try_promote_provisional_outermost(&ule, gc_info->oldest_referenced_xid_for_implicit_promotion); + // modify unpacked leafentry + rowcountdelta = msg_modify_ule(&ule, msg); + + // - we may be able to immediately promote the newly-apllied outermost + // provisonal uxr + // - either way, run simple gc first, and then full gc if there are still + // some committed uxrs. + ule_try_promote_provisional_outermost( + &ule, + gc_info->oldest_referenced_xid_for_implicit_promotion); ule_simple_garbage_collection(&ule, gc_info); txn_manager_state *txn_state_for_gc = gc_info->txn_state_for_gc; size_t size_before_gc = 0; - if (ule.num_cuxrs > 1 && txn_state_for_gc != nullptr && // there is garbage to clean, and our caller gave us state.. - // ..and either the state is pre-initialized, or the committed stack is large enough - (txn_state_for_gc->initialized || ule.num_cuxrs >= ULE_MIN_STACK_SIZE_TO_FORCE_GC || - // ..or the ule's raw memsize is sufficiently large - (size_before_gc = ule_packed_memsize(&ule)) >= ULE_MIN_MEMSIZE_TO_FORCE_GC)) { - // ..then it's worth running gc, possibly initializing the txn manager state, if it isn't already + // there is garbage to clean, and our caller gave us state.. + // ..and either the state is pre-initialized, or the committed stack is + // large enough + // ..or the ule's raw memsize is sufficiently large + // ..then it's worth running gc, possibly initializing the txn manager + // state, if it isn't already + if (ule.num_cuxrs > 1 && txn_state_for_gc != nullptr && + (txn_state_for_gc->initialized || + ule.num_cuxrs >= ULE_MIN_STACK_SIZE_TO_FORCE_GC || + (size_before_gc = ule_packed_memsize(&ule)) >= + ULE_MIN_MEMSIZE_TO_FORCE_GC)) { if (!txn_state_for_gc->initialized) { txn_state_for_gc->init(); } - - size_before_gc = size_before_gc != 0 ? size_before_gc : // it's already been calculated above - ule_packed_memsize(&ule); - ule_garbage_collect(&ule, - txn_state_for_gc->snapshot_xids, - txn_state_for_gc->referenced_xids, - txn_state_for_gc->live_root_txns - ); + // it's already been calculated above + size_before_gc = + size_before_gc != 0 ? size_before_gc : ule_packed_memsize(&ule); + ule_garbage_collect( + &ule, + txn_state_for_gc->snapshot_xids, + txn_state_for_gc->referenced_xids, + txn_state_for_gc->live_root_txns); size_t size_after_gc = ule_packed_memsize(&ule); LE_STATUS_INC(LE_APPLY_GC_BYTES_IN, size_before_gc); LE_STATUS_INC(LE_APPLY_GC_BYTES_OUT, size_after_gc); } - void *maybe_free = nullptr; - int r = le_pack( - &ule, // create packed leafentry - data_buffer, - idx, - msg.kdbt()->data, // contract of this function is caller has this set, always - keylen, // contract of this function is caller has this set, always - old_keylen, - oldmemsize, - new_leafentry_p, - &maybe_free - ); + void* maybe_free = nullptr; + // create packed leafentry + // contract of this function is caller has keyp and keylen set, always + int r = + le_pack( + &ule, + data_buffer, + idx, + msg.kdbt()->data, + keylen, + old_keylen, + oldmemsize, + new_leafentry_p, + &maybe_free); invariant_zero(r); if (*new_leafentry_p) { newnumbytes = ule_get_innermost_numbytes(&ule, keylen); @@ -458,16 +573,22 @@ toku_le_apply_msg(const ft_msg &msg, if (maybe_free != nullptr) { toku_free(maybe_free); } + return rowcountdelta; } -bool toku_le_worth_running_garbage_collection(LEAFENTRY le, txn_gc_info *gc_info) { -// Effect: Quickly determines if it's worth trying to run garbage collection on a leafentry +bool toku_le_worth_running_garbage_collection( + LEAFENTRY le, + txn_gc_info* gc_info) { +// Effect: Quickly determines if it's worth trying to run garbage collection +// on a leafentry // Return: True if it makes sense to try garbage collection, false otherwise. // Rationale: Garbage collection is likely to clean up under two circumstances: -// 1.) There are multiple committed entries. Some may never be read by new txns. -// 2.) There is only one committed entry, but the outermost provisional entry -// is older than the oldest known referenced xid, so it must have commited. -// Therefor we can promote it to committed and get rid of the old commited entry. +// 1.) There are multiple committed entries. Some may never be read +// by new txns. +// 2.) There is only one committed entry, but the outermost +// provisional entry is older than the oldest known referenced +// xid, so it must have commited. Therefor we can promote it to +// committed and get rid of the old commited entry. if (le->type != LE_MVCC) { return false; } @@ -477,7 +598,8 @@ bool toku_le_worth_running_garbage_collection(LEAFENTRY le, txn_gc_info *gc_info paranoid_invariant(le->u.mvcc.num_cxrs == 1); } return le->u.mvcc.num_pxrs > 0 && - le_outermost_uncommitted_xid(le) < gc_info->oldest_referenced_xid_for_implicit_promotion; + le_outermost_uncommitted_xid(le) < + gc_info->oldest_referenced_xid_for_implicit_promotion; } // Garbage collect one leaf entry, using the given OMT's. @@ -498,16 +620,18 @@ bool toku_le_worth_running_garbage_collection(LEAFENTRY le, txn_gc_info *gc_info // -- referenced_xids : list of in memory active transactions. // NOTE: it is not a good idea to garbage collect a leaf // entry with only one committed value. -void -toku_le_garbage_collect(LEAFENTRY old_leaf_entry, - bn_data* data_buffer, - uint32_t idx, - void* keyp, - uint32_t keylen, - txn_gc_info *gc_info, - LEAFENTRY *new_leaf_entry, - int64_t * numbytes_delta_p) { - // We shouldn't want to run gc without having provided a snapshot of the txn system. +void toku_le_garbage_collect( + LEAFENTRY old_leaf_entry, + bn_data* data_buffer, + uint32_t idx, + void* keyp, + uint32_t keylen, + txn_gc_info* gc_info, + LEAFENTRY* new_leaf_entry, + int64_t* numbytes_delta_p) { + + // We shouldn't want to run gc without having provided a snapshot of the + // txn system. invariant_notnull(gc_info); invariant_notnull(gc_info->txn_state_for_gc); paranoid_invariant_notnull(new_leaf_entry); @@ -520,20 +644,24 @@ toku_le_garbage_collect(LEAFENTRY old_leaf_entry, oldnumbytes = ule_get_innermost_numbytes(&ule, keylen); uint32_t old_mem_size = leafentry_memsize(old_leaf_entry); - // Before running garbage collection, try to promote the outermost provisional - // entries to committed if its xid is older than the oldest possible live xid. + // Before running garbage collection, try to promote the outermost + // provisional entries to committed if its xid is older than the oldest + // possible live xid. // // The oldest known refeferenced xid is a lower bound on the oldest possible // live xid, so we use that. It's usually close enough to get rid of most // garbage in leafentries. - ule_try_promote_provisional_outermost(&ule, gc_info->oldest_referenced_xid_for_implicit_promotion); + ule_try_promote_provisional_outermost( + &ule, + gc_info->oldest_referenced_xid_for_implicit_promotion); // No need to run simple gc here if we're going straight for full gc. if (ule.num_cuxrs > 1) { size_t size_before_gc = ule_packed_memsize(&ule); - ule_garbage_collect(&ule, - gc_info->txn_state_for_gc->snapshot_xids, - gc_info->txn_state_for_gc->referenced_xids, - gc_info->txn_state_for_gc->live_root_txns); + ule_garbage_collect( + &ule, + gc_info->txn_state_for_gc->snapshot_xids, + gc_info->txn_state_for_gc->referenced_xids, + gc_info->txn_state_for_gc->live_root_txns); size_t size_after_gc = ule_packed_memsize(&ule); LE_STATUS_INC(LE_APPLY_GC_BYTES_IN, size_before_gc); @@ -541,17 +669,18 @@ toku_le_garbage_collect(LEAFENTRY old_leaf_entry, } void *maybe_free = nullptr; - int r = le_pack( - &ule, - data_buffer, - idx, - keyp, - keylen, - keylen, // old_keylen, same because the key isn't going to change for gc - old_mem_size, - new_leaf_entry, - &maybe_free - ); + // old_keylen, same because the key isn't going to change for gc + int r = + le_pack( + &ule, + data_buffer, + idx, + keyp, + keylen, + keylen, + old_mem_size, + new_leaf_entry, + &maybe_free); invariant_zero(r); if (*new_leaf_entry) { newnumbytes = ule_get_innermost_numbytes(&ule, keylen); @@ -564,49 +693,54 @@ toku_le_garbage_collect(LEAFENTRY old_leaf_entry, } } -///////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // This layer of abstraction (msg_xxx) // knows the accessors of msg, but not of leafentry or unpacked leaf entry. // It makes calls into the lower layer (le_xxx) which handles leafentries. // Purpose is to init the ule with given key and no transaction records // -static void -msg_init_empty_ule(ULE ule) { +static inline void msg_init_empty_ule(ULE ule) { ule_init_empty_ule(ule); } // Purpose is to modify the unpacked leafentry in our private workspace. // -static void -msg_modify_ule(ULE ule, const ft_msg &msg) { +// Returns -1, 0, or 1 that identifies the change in logical row count needed +// based on the results of the message application. For example, if a delete +// finds no logical leafentry or if an insert finds a duplicate and is +// converted to an update. +static int64_t msg_modify_ule(ULE ule, const ft_msg &msg) { + int64_t retval = 0; XIDS xids = msg.xids(); invariant(toku_xids_get_num_xids(xids) < MAX_TRANSACTION_RECORDS); enum ft_msg_type type = msg.type(); - if (type != FT_OPTIMIZE && type != FT_OPTIMIZE_FOR_UPGRADE) { + if (FT_LIKELY(type != FT_OPTIMIZE && type != FT_OPTIMIZE_FOR_UPGRADE)) { ule_do_implicit_promotions(ule, xids); } switch (type) { - case FT_INSERT_NO_OVERWRITE: { - UXR old_innermost_uxr = ule_get_innermost_uxr(ule); - //If something exists, quit (no overwrite). - if (uxr_is_insert(old_innermost_uxr)) break; - //else it is just an insert, so - //fall through to FT_INSERT on purpose. - } - case FT_INSERT: { - uint32_t vallen = msg.vdbt()->size; - invariant(IS_VALID_LEN(vallen)); - void * valp = msg.vdbt()->data; - ule_apply_insert(ule, xids, vallen, valp); + case FT_INSERT_NO_OVERWRITE: + retval = + ule_apply_insert_no_overwrite( + ule, + xids, + msg.vdbt()->size, + msg.vdbt()->data); + break; + case FT_INSERT: + retval = + ule_apply_insert( + ule, + xids, + msg.vdbt()->size, + msg.vdbt()->data); break; - } case FT_DELETE_ANY: - ule_apply_delete(ule, xids); + retval = ule_apply_delete(ule, xids); break; case FT_ABORT_ANY: case FT_ABORT_BROADCAST_TXN: - ule_apply_abort(ule, xids); + retval = ule_apply_abort(ule, xids); break; case FT_COMMIT_BROADCAST_ALL: ule_apply_broadcast_commit_all(ule); @@ -621,34 +755,40 @@ msg_modify_ule(ULE ule, const ft_msg &msg) { break; case FT_UPDATE: case FT_UPDATE_BROADCAST_ALL: - assert(false); // These messages don't get this far. Instead they get translated (in setval_fun in do_update) into FT_INSERT messages. + // These messages don't get this far. Instead they get translated (in + // setval_fun in do_update) into FT_INSERT messages. + assert(false); break; default: - assert(false); /* illegal ft msg type */ + // illegal ft msg type + assert(false); break; } + return retval; } -void test_msg_modify_ule(ULE ule, const ft_msg &msg){ +void test_msg_modify_ule(ULE ule, const ft_msg &msg) { msg_modify_ule(ule,msg); } static void ule_optimize(ULE ule, XIDS xids) { if (ule->num_puxrs) { - TXNID uncommitted = ule->uxrs[ule->num_cuxrs].xid; // outermost uncommitted + // outermost uncommitted + TXNID uncommitted = ule->uxrs[ule->num_cuxrs].xid; TXNID oldest_living_xid = TXNID_NONE; uint32_t num_xids = toku_xids_get_num_xids(xids); if (num_xids > 0) { invariant(num_xids==1); oldest_living_xid = toku_xids_get_xid(xids, 0); } - if (oldest_living_xid == TXNID_NONE || uncommitted < oldest_living_xid) { + if (oldest_living_xid == TXNID_NONE || + uncommitted < oldest_living_xid) { ule_promote_provisional_innermost_to_committed(ule); } } } -///////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // This layer of abstraction (le_xxx) understands the structure of the leafentry // and of the unpacked leafentry. It is the only layer that understands the // structure of leafentry. It has no knowledge of any other data structures. @@ -657,8 +797,7 @@ static void ule_optimize(ULE ule, XIDS xids) { // // required for every le_unpack that is done // -void -ule_cleanup(ULE ule) { +void ule_cleanup(ULE ule) { invariant(ule->uxrs); if (ule->uxrs != ule->uxrs_static) { toku_free(ule->uxrs); @@ -668,8 +807,7 @@ ule_cleanup(ULE ule) { // populate an unpacked leafentry using pointers into the given leafentry. // thus, the memory referenced by 'le' must live as long as the ULE. -void -le_unpack(ULE ule, LEAFENTRY le) { +void le_unpack(ULE ule, LEAFENTRY le) { uint8_t type = le->type; uint8_t *p; uint32_t i; @@ -694,9 +832,10 @@ le_unpack(ULE ule, LEAFENTRY le) { //Dynamic memory if (ule->num_cuxrs < MAX_TRANSACTION_RECORDS) { ule->uxrs = ule->uxrs_static; - } - else { - XMALLOC_N(ule->num_cuxrs + 1 + MAX_TRANSACTION_RECORDS, ule->uxrs); + } else { + XMALLOC_N( + ule->num_cuxrs + 1 + MAX_TRANSACTION_RECORDS, + ule->uxrs); } p = le->u.mvcc.xrs; @@ -717,9 +856,12 @@ le_unpack(ULE ule, LEAFENTRY le) { p += uxr_unpack_length_and_bit(innermost, p); } for (i = 0; i < ule->num_cuxrs; i++) { - p += uxr_unpack_length_and_bit(ule->uxrs + ule->num_cuxrs - 1 - i, p); + p += + uxr_unpack_length_and_bit( + ule->uxrs + ule->num_cuxrs - 1 - i, + p); } - + //unpack interesting values inner to outer if (ule->num_puxrs!=0) { UXR innermost = ule->uxrs + ule->num_cuxrs + ule->num_puxrs - 1; @@ -761,14 +903,12 @@ le_unpack(ULE ule, LEAFENTRY le) { #endif } -static inline size_t -uxr_pack_txnid(UXR uxr, uint8_t *p) { +static inline size_t uxr_pack_txnid(UXR uxr, uint8_t *p) { *(TXNID*)p = toku_htod64(uxr->xid); return sizeof(TXNID); } -static inline size_t -uxr_pack_type_and_length(UXR uxr, uint8_t *p) { +static inline size_t uxr_pack_type_and_length(UXR uxr, uint8_t *p) { size_t rval = 1; *p = uxr->type; if (uxr_is_insert(uxr)) { @@ -778,21 +918,18 @@ uxr_pack_type_and_length(UXR uxr, uint8_t *p) { return rval; } -static inline size_t -uxr_pack_length_and_bit(UXR uxr, uint8_t *p) { +static inline size_t uxr_pack_length_and_bit(UXR uxr, uint8_t *p) { uint32_t length_and_bit; if (uxr_is_insert(uxr)) { length_and_bit = INSERT_LENGTH(uxr->vallen); - } - else { + } else { length_and_bit = DELETE_LENGTH(uxr->vallen); } *(uint32_t*)p = toku_htod32(length_and_bit); return sizeof(uint32_t); } -static inline size_t -uxr_pack_data(UXR uxr, uint8_t *p) { +static inline size_t uxr_pack_data(UXR uxr, uint8_t *p) { if (uxr_is_insert(uxr)) { memcpy(p, uxr->valp, uxr->vallen); return uxr->vallen; @@ -800,14 +937,12 @@ uxr_pack_data(UXR uxr, uint8_t *p) { return 0; } -static inline size_t -uxr_unpack_txnid(UXR uxr, uint8_t *p) { +static inline size_t uxr_unpack_txnid(UXR uxr, uint8_t *p) { uxr->xid = toku_dtoh64(*(TXNID*)p); return sizeof(TXNID); } -static inline size_t -uxr_unpack_type_and_length(UXR uxr, uint8_t *p) { +static inline size_t uxr_unpack_type_and_length(UXR uxr, uint8_t *p) { size_t rval = 1; uxr->type = *p; if (uxr_is_insert(uxr)) { @@ -817,22 +952,19 @@ uxr_unpack_type_and_length(UXR uxr, uint8_t *p) { return rval; } -static inline size_t -uxr_unpack_length_and_bit(UXR uxr, uint8_t *p) { +static inline size_t uxr_unpack_length_and_bit(UXR uxr, uint8_t *p) { uint32_t length_and_bit = toku_dtoh32(*(uint32_t*)p); if (IS_INSERT(length_and_bit)) { uxr->type = XR_INSERT; uxr->vallen = GET_LENGTH(length_and_bit); - } - else { + } else { uxr->type = XR_DELETE; uxr->vallen = 0; } return sizeof(uint32_t); } -static inline size_t -uxr_unpack_data(UXR uxr, uint8_t *p) { +static inline size_t uxr_unpack_data(UXR uxr, uint8_t *p) { if (uxr_is_insert(uxr)) { uxr->valp = p; return uxr->vallen; @@ -841,8 +973,7 @@ uxr_unpack_data(UXR uxr, uint8_t *p) { } // executed too often to be worth making threadsafe -static inline void -update_le_status(ULE ule, size_t memsize) { +static inline void update_le_status(ULE ule, size_t memsize) { if (ule->num_cuxrs > LE_STATUS_VAL(LE_MAX_COMMITTED_XR)) LE_STATUS_VAL(LE_MAX_COMMITTED_XR) = ule->num_cuxrs; if (ule->num_puxrs > LE_STATUS_VAL(LE_MAX_PROVISIONAL_XR)) @@ -856,21 +987,22 @@ update_le_status(ULE ule, size_t memsize) { // Purpose is to return a newly allocated leaf entry in packed format, or // return null if leaf entry should be destroyed (if no transaction records // are for inserts). -// Transaction records in packed le are stored inner to outer (first xr is innermost), -// with some information extracted out of the transaction records into the header. +// Transaction records in packed le are stored inner to outer (first xr is +// innermost), with some information extracted out of the transaction records +// into the header. // Transaction records in ule are stored outer to inner (uxr[0] is outermost). -int -le_pack(ULE ule, // data to be packed into new leafentry - bn_data* data_buffer, - uint32_t idx, - void* keyp, - uint32_t keylen, - uint32_t old_keylen, - uint32_t old_le_size, - LEAFENTRY * const new_leafentry_p, // this is what this function creates - void **const maybe_free - ) -{ +// Takes 'ule' and creates 'new_leafentry_p +int le_pack( + ULE ule, + bn_data* data_buffer, + uint32_t idx, + void* keyp, + uint32_t keylen, + uint32_t old_keylen, + uint32_t old_le_size, + LEAFENTRY* const new_leafentry_p, + void** const maybe_free) { + invariant(ule->num_cuxrs > 0); invariant(ule->uxrs[0].xid == TXNID_NONE); int rval; @@ -888,7 +1020,8 @@ le_pack(ULE ule, // data to be packed into new leafentry } } if (data_buffer && old_le_size > 0) { - // must pass old_keylen and old_le_size, since that's what is actually stored in data_buffer + // must pass old_keylen and old_le_size, since that's what is + // actually stored in data_buffer data_buffer->delete_leafentry(idx, old_keylen, old_le_size); } *new_leafentry_p = NULL; @@ -898,14 +1031,24 @@ le_pack(ULE ule, // data to be packed into new leafentry found_insert: memsize = le_memsize_from_ule(ule); LEAFENTRY new_leafentry; - get_space_for_le(data_buffer, idx, keyp, keylen, old_keylen, old_le_size, memsize, &new_leafentry, maybe_free); + get_space_for_le( + data_buffer, + idx, + keyp, + keylen, + old_keylen, + old_le_size, + memsize, + &new_leafentry, + maybe_free); //p always points to first unused byte after leafentry we are packing uint8_t *p; invariant(ule->num_cuxrs>0); //Type specific data if (ule->num_cuxrs == 1 && ule->num_puxrs == 0) { - //Pack a 'clean leafentry' (no uncommitted transactions, only one committed value) + //Pack a 'clean leafentry' (no uncommitted transactions, only one + //committed value) new_leafentry->type = LE_CLEAN; uint32_t vallen = ule->uxrs[0].vallen; @@ -917,8 +1060,7 @@ le_pack(ULE ule, // data to be packed into new leafentry //Set p to after leafentry p = new_leafentry->u.clean.val + vallen; - } - else { + } else { uint32_t i; //Pack an 'mvcc leafentry' new_leafentry->type = LE_MVCC; @@ -969,7 +1111,9 @@ le_pack(ULE ule, // data to be packed into new leafentry p += uxr_pack_data(outermost, p); } //pack txnid, length, bit, data for non-outermost, non-innermost - for (i = ule->num_cuxrs + 1; i < ule->num_cuxrs + ule->num_puxrs - 1; i++) { + for (i = ule->num_cuxrs + 1; + i < ule->num_cuxrs + ule->num_puxrs - 1; + i++) { UXR uxr = ule->uxrs + i; p += uxr_pack_txnid(uxr, p); p += uxr_pack_type_and_length(uxr, p); @@ -1022,13 +1166,13 @@ le_pack(ULE ule, // data to be packed into new leafentry return rval; } -////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // Following functions provide convenient access to a packed leafentry. //Requires: -// Leafentry that ule represents should not be destroyed (is not just all deletes) -size_t -le_memsize_from_ule (ULE ule) { +// Leafentry that ule represents should not be destroyed (is not just all +// deletes) +size_t le_memsize_from_ule (ULE ule) { invariant(ule->num_cuxrs); size_t rval; if (ule->num_cuxrs == 1 && ule->num_puxrs == 0) { @@ -1037,13 +1181,13 @@ le_memsize_from_ule (ULE ule) { rval = 1 //type +4 //vallen +committed->vallen; //actual val - } - else { + } else { rval = 1 //type +4 //num_cuxrs +1 //num_puxrs +4*(ule->num_cuxrs) //types+lengths for committed - +8*(ule->num_cuxrs + ule->num_puxrs - 1); //txnids (excluding superroot) + +8*(ule->num_cuxrs + ule->num_puxrs - 1); //txnids (excluding + //superroot) uint32_t i; //Count data from committed uxrs and innermost puxr for (i = 0; i < ule->num_cuxrs; i++) { @@ -1072,8 +1216,11 @@ le_memsize_from_ule (ULE ule) { } // TODO: rename -size_t -leafentry_rest_memsize(uint32_t num_puxrs, uint32_t num_cuxrs, uint8_t* start) { +size_t leafentry_rest_memsize( + uint32_t num_puxrs, + uint32_t num_cuxrs, + uint8_t* start) { + UXR_S uxr; size_t lengths = 0; uint8_t* p = start; @@ -1122,8 +1269,7 @@ leafentry_rest_memsize(uint32_t num_puxrs, uint32_t num_cuxrs, uint8_t* start) { return rval; } -size_t -leafentry_memsize (LEAFENTRY le) { +size_t leafentry_memsize (LEAFENTRY le) { size_t rval = 0; uint8_t type = le->type; @@ -1162,13 +1308,11 @@ leafentry_memsize (LEAFENTRY le) { return rval; } -size_t -leafentry_disksize (LEAFENTRY le) { +size_t leafentry_disksize (LEAFENTRY le) { return leafentry_memsize(le); } -bool -le_is_clean(LEAFENTRY le) { +bool le_is_clean(LEAFENTRY le) { uint8_t type = le->type; uint32_t rval; switch (type) { @@ -1228,13 +1372,14 @@ int le_latest_is_del(LEAFENTRY le) { // -// returns true if the outermost provisional transaction id on the leafentry's stack matches -// the outermost transaction id in xids -// It is used to determine if a broadcast commit/abort message (look in ft-ops.c) should be applied to this leafentry -// If the outermost transactions match, then the broadcast commit/abort should be applied +// returns true if the outermost provisional transaction id on the leafentry's +// stack matches the outermost transaction id in xids +// It is used to determine if a broadcast commit/abort message (look in ft-ops.c) +// should be applied to this leafentry +// If the outermost transactions match, then the broadcast commit/abort should +// be applied // -bool -le_has_xids(LEAFENTRY le, XIDS xids) { +bool le_has_xids(LEAFENTRY le, XIDS xids) { //Read num_uxrs uint32_t num_xids = toku_xids_get_num_xids(xids); invariant(num_xids > 0); //Disallow checking for having TXNID_NONE @@ -1245,8 +1390,7 @@ le_has_xids(LEAFENTRY le, XIDS xids) { return rval; } -void* -le_latest_val_and_len (LEAFENTRY le, uint32_t *len) { +void* le_latest_val_and_len (LEAFENTRY le, uint32_t *len) { uint8_t type = le->type; void *valp; @@ -1277,8 +1421,7 @@ le_latest_val_and_len (LEAFENTRY le, uint32_t *len) { if (uxr_is_insert(&uxr)) { *len = uxr.vallen; valp = p + (num_cuxrs - 1 + (num_puxrs!=0))*sizeof(uint32_t); - } - else { + } else { *len = 0; valp = NULL; } @@ -1295,8 +1438,7 @@ le_latest_val_and_len (LEAFENTRY le, uint32_t *len) { if (uxr_is_insert(uxr)) { slow_valp = uxr->valp; slow_len = uxr->vallen; - } - else { + } else { slow_valp = NULL; slow_len = 0; } @@ -1310,8 +1452,7 @@ le_latest_val_and_len (LEAFENTRY le, uint32_t *len) { } //DEBUG ONLY can be slow -void* -le_latest_val (LEAFENTRY le) { +void* le_latest_val (LEAFENTRY le) { ULE_S ule; le_unpack(&ule, le); UXR uxr = ule_get_innermost_uxr(&ule); @@ -1325,8 +1466,7 @@ le_latest_val (LEAFENTRY le) { } //needed to be fast for statistics. -uint32_t -le_latest_vallen (LEAFENTRY le) { +uint32_t le_latest_vallen (LEAFENTRY le) { uint32_t rval; uint8_t type = le->type; uint8_t *p; @@ -1354,8 +1494,7 @@ le_latest_vallen (LEAFENTRY le) { uxr_unpack_length_and_bit(&uxr, p); if (uxr_is_insert(&uxr)) { rval = uxr.vallen; - } - else { + } else { rval = 0; } break; @@ -1377,8 +1516,7 @@ le_latest_vallen (LEAFENTRY le) { return rval; } -uint64_t -le_outermost_uncommitted_xid (LEAFENTRY le) { +uint64_t le_outermost_uncommitted_xid (LEAFENTRY le) { uint64_t rval = TXNID_NONE; uint8_t type = le->type; @@ -1412,8 +1550,7 @@ le_outermost_uncommitted_xid (LEAFENTRY le) { //Optimization not required. This is a debug only function. //Print a leafentry out in human-readable format -int -print_klpair (FILE *outf, const void* keyp, uint32_t keylen, LEAFENTRY le) { +int print_klpair (FILE *outf, const void* keyp, uint32_t keylen, LEAFENTRY le) { ULE_S ule; le_unpack(&ule, le); uint32_t i; @@ -1444,23 +1581,21 @@ print_klpair (FILE *outf, const void* keyp, uint32_t keylen, LEAFENTRY le) { return 0; } -///////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // This layer of abstraction (ule_xxx) knows the structure of the unpacked // leafentry and no other structure. // // ule constructor // Note that transaction 0 is explicit in the ule -static void -ule_init_empty_ule(ULE ule) { +static inline void ule_init_empty_ule(ULE ule) { ule->num_cuxrs = 1; ule->num_puxrs = 0; ule->uxrs = ule->uxrs_static; ule->uxrs[0] = committed_delete; } -static inline int32_t -min_i32(int32_t a, int32_t b) { +static inline int32_t min_i32(int32_t a, int32_t b) { int32_t rval = a < b ? a : b; return rval; } @@ -1470,8 +1605,8 @@ min_i32(int32_t a, int32_t b) { // // If the leafentry has already been promoted, there is nothing to do. // We have two transaction stacks (one from message, one from leaf entry). -// We want to implicitly promote transactions newer than (but not including) -// the innermost common ancestor (ICA) of the two stacks of transaction ids. We +// We want to implicitly promote transactions newer than (but not including) +// the innermost common ancestor (ICA) of the two stacks of transaction ids. We // know that this is the right thing to do because each transaction with an id // greater (later) than the ICA must have been either committed or aborted. // If it was aborted then we would have seen an abort message and removed the @@ -1483,8 +1618,7 @@ min_i32(int32_t a, int32_t b) { // record of ICA, keeping the transaction id of the ICA. // Outermost xid is zero for both ule and xids<> // -static void -ule_do_implicit_promotions(ULE ule, XIDS xids) { +static void ule_do_implicit_promotions(ULE ule, XIDS xids) { //Optimization for (most) common case. //No commits necessary if everything is already committed. if (ule->num_puxrs > 0) { @@ -1506,17 +1640,16 @@ ule_do_implicit_promotions(ULE ule, XIDS xids) { if (ica_index < ule->num_cuxrs) { invariant(ica_index == ule->num_cuxrs - 1); ule_promote_provisional_innermost_to_committed(ule); - } - else if (ica_index < ule->num_cuxrs + ule->num_puxrs - 1) { - //If ica is the innermost uxr in the leafentry, no commits are necessary. + } else if (ica_index < ule->num_cuxrs + ule->num_puxrs - 1) { + //If ica is the innermost uxr in the leafentry, no commits are + //necessary. ule_promote_provisional_innermost_to_index(ule, ica_index); } } } -static void -ule_promote_provisional_innermost_to_committed(ULE ule) { +static void ule_promote_provisional_innermost_to_committed(ULE ule) { //Must be something to promote. invariant(ule->num_puxrs); //Take value (or delete flag) from innermost. @@ -1532,8 +1665,7 @@ ule_promote_provisional_innermost_to_committed(ULE ule) { ule->num_puxrs = 0; //Discard all provisional uxrs. if (uxr_is_delete(old_innermost_uxr)) { ule_push_delete_uxr(ule, true, old_outermost_uncommitted_uxr->xid); - } - else { + } else { ule_push_insert_uxr(ule, true, old_outermost_uncommitted_uxr->xid, old_innermost_uxr->vallen, @@ -1541,11 +1673,13 @@ ule_promote_provisional_innermost_to_committed(ULE ule) { } } -static void -ule_try_promote_provisional_outermost(ULE ule, TXNID oldest_possible_live_xid) { +static void ule_try_promote_provisional_outermost( + ULE ule, + TXNID oldest_possible_live_xid) { // Effect: If there is a provisional record whose outermost xid is older than // the oldest known referenced_xid, promote it to committed. - if (ule->num_puxrs > 0 && ule_get_xid(ule, ule->num_cuxrs) < oldest_possible_live_xid) { + if (ule->num_puxrs > 0 && + ule_get_xid(ule, ule->num_cuxrs) < oldest_possible_live_xid) { ule_promote_provisional_innermost_to_committed(ule); } } @@ -1553,8 +1687,9 @@ ule_try_promote_provisional_outermost(ULE ule, TXNID oldest_possible_live_xid) { // Purpose is to promote the value (and type) of the innermost transaction // record to the uxr at the specified index (keeping the txnid of the uxr at // specified index.) -static void -ule_promote_provisional_innermost_to_index(ULE ule, uint32_t index) { +static void ule_promote_provisional_innermost_to_index( + ULE ule, + uint32_t index) { //Must not promote to committed portion of stack. invariant(index >= ule->num_cuxrs); //Must actually be promoting. @@ -1562,15 +1697,17 @@ ule_promote_provisional_innermost_to_index(ULE ule, uint32_t index) { UXR old_innermost_uxr = ule_get_innermost_uxr(ule); assert(!uxr_is_placeholder(old_innermost_uxr)); TXNID new_innermost_xid = ule->uxrs[index].xid; - ule->num_puxrs = index - ule->num_cuxrs; //Discard old uxr at index (and everything inner) + //Discard old uxr at index (and everything inner) + ule->num_puxrs = index - ule->num_cuxrs; if (uxr_is_delete(old_innermost_uxr)) { ule_push_delete_uxr(ule, false, new_innermost_xid); - } - else { - ule_push_insert_uxr(ule, false, - new_innermost_xid, - old_innermost_uxr->vallen, - old_innermost_uxr->valp); + } else { + ule_push_insert_uxr( + ule, + false, + new_innermost_xid, + old_innermost_uxr->vallen, + old_innermost_uxr->valp); } } @@ -1581,19 +1718,60 @@ ule_promote_provisional_innermost_to_index(ULE ule, uint32_t index) { // Purpose is to apply an insert message to this leafentry: -static void -ule_apply_insert(ULE ule, XIDS xids, uint32_t vallen, void * valp) { +static inline int64_t ule_apply_insert_no_overwrite( + ULE ule, + XIDS xids, + uint32_t vallen, + void* valp) { + + invariant(IS_VALID_LEN(vallen)); + int64_t retval = 0; + UXR old_innermost_uxr = ule_get_innermost_uxr(ule); + // If something exists, don't overwrite + if (uxr_is_insert(old_innermost_uxr)) { + retval = -1; + return retval; + } ule_prepare_for_new_uxr(ule, xids); - TXNID this_xid = toku_xids_get_innermost_xid(xids); // xid of transaction doing this insert + // xid of transaction doing this insert + TXNID this_xid = toku_xids_get_innermost_xid(xids); ule_push_insert_uxr(ule, this_xid == TXNID_NONE, this_xid, vallen, valp); + return retval; +} + +// Purpose is to apply an insert message to this leafentry: +static inline int64_t ule_apply_insert( + ULE ule, + XIDS xids, + uint32_t vallen, + void* valp) { + + invariant(IS_VALID_LEN(vallen)); + int64_t retval = 0; + UXR old_innermost_uxr = ule_get_innermost_uxr(ule); + // If something exists, overwrite + if (uxr_is_insert(old_innermost_uxr)) { + retval = -1; + } + ule_prepare_for_new_uxr(ule, xids); + // xid of transaction doing this insert + TXNID this_xid = toku_xids_get_innermost_xid(xids); + ule_push_insert_uxr(ule, this_xid == TXNID_NONE, this_xid, vallen, valp); + return retval; } // Purpose is to apply a delete message to this leafentry: -static void -ule_apply_delete(ULE ule, XIDS xids) { +static inline int64_t ule_apply_delete(ULE ule, XIDS xids) { + int64_t retval = 0; + UXR old_innermost_uxr = ule_get_innermost_uxr(ule); + if (FT_UNLIKELY(uxr_is_delete(old_innermost_uxr))) { + retval = 1; + } ule_prepare_for_new_uxr(ule, xids); - TXNID this_xid = toku_xids_get_innermost_xid(xids); // xid of transaction doing this delete + // xid of transaction doing this delete + TXNID this_xid = toku_xids_get_innermost_xid(xids); ule_push_delete_uxr(ule, this_xid == TXNID_NONE, this_xid); + return retval; } // First, discard anything done earlier by this transaction. @@ -1601,20 +1779,18 @@ ule_apply_delete(ULE ule, XIDS xids) { // outer transactions that are newer than then newest (innermost) transaction in // the leafentry. If so, record those outer transactions in the leafentry // with placeholders. -static void -ule_prepare_for_new_uxr(ULE ule, XIDS xids) { +static inline void ule_prepare_for_new_uxr(ULE ule, XIDS xids) { TXNID this_xid = toku_xids_get_innermost_xid(xids); //This is for LOADER_USE_PUTS or transactionless environment //where messages use XIDS of 0 if (this_xid == TXNID_NONE && ule_get_innermost_xid(ule) == TXNID_NONE) { ule_remove_innermost_uxr(ule); - } - // case where we are transactional and xids stack matches ule stack - else if (ule->num_puxrs > 0 && ule_get_innermost_xid(ule) == this_xid) { + } else if (ule->num_puxrs > 0 && ule_get_innermost_xid(ule) == this_xid) { + // case where we are transactional and xids stack matches ule stack ule_remove_innermost_uxr(ule); - } - // case where we are transactional and xids stack does not match ule stack - else { + } else { + // case where we are transactional and xids stack does not match ule + // stack ule_add_placeholders(ule, xids); } } @@ -1625,10 +1801,12 @@ ule_prepare_for_new_uxr(ULE ule, XIDS xids) { // then there is nothing to be done. // If this transaction did modify the leafentry, then undo whatever it did (by // removing the transaction record (uxr) and any placeholders underneath. -// Remember, the innermost uxr can only be an insert or a delete, not a placeholder. -static void -ule_apply_abort(ULE ule, XIDS xids) { - TXNID this_xid = toku_xids_get_innermost_xid(xids); // xid of transaction doing this abort +// Remember, the innermost uxr can only be an insert or a delete, not a +// placeholder. +static inline int64_t ule_apply_abort(ULE ule, XIDS xids) { + int64_t retval = 0; + // xid of transaction doing this abort + TXNID this_xid = toku_xids_get_innermost_xid(xids); invariant(this_xid!=TXNID_NONE); UXR innermost = ule_get_innermost_uxr(ule); // need to check for provisional entries in ule, otherwise @@ -1636,15 +1814,34 @@ ule_apply_abort(ULE ule, XIDS xids) { // in a bug where the most recently committed has same xid // as the XID's innermost if (ule->num_puxrs > 0 && innermost->xid == this_xid) { + // if this is a rollback of a delete of a new ule, return 0 + // (i.e. double delete) + if (uxr_is_delete(innermost)) { + if (ule->num_puxrs == 1 && ule->num_cuxrs == 1 && + uxr_is_delete(&(ule->uxrs[0]))) { + retval = 0; + } else { + retval = 1; + } + } else if (uxr_is_insert(innermost)) { + if (ule->num_puxrs == 1 && ule->num_cuxrs == 1 && + uxr_is_insert(&(ule->uxrs[0]))) { + retval = 0; + } else { + retval = -1; + } + } + // if this is a rollback of a insert of an exising ule, return 0 + // (i.e. double insert) invariant(ule->num_puxrs>0); ule_remove_innermost_uxr(ule); ule_remove_innermost_placeholders(ule); } invariant(ule->num_cuxrs > 0); + return retval; } -static void -ule_apply_broadcast_commit_all (ULE ule) { +static void ule_apply_broadcast_commit_all (ULE ule) { ule->uxrs[0] = ule->uxrs[ule->num_puxrs + ule->num_cuxrs - 1]; ule->uxrs[0].xid = TXNID_NONE; ule->num_puxrs = 0; @@ -1657,9 +1854,11 @@ ule_apply_broadcast_commit_all (ULE ule) { // then there is nothing to be done. // Also, if there are no uncommitted transaction records there is nothing to do. // If this transaction did modify the leafentry, then promote whatever it did. -// Remember, the innermost uxr can only be an insert or a delete, not a placeholder. +// Remember, the innermost uxr can only be an insert or a delete, not a +// placeholder. void ule_apply_commit(ULE ule, XIDS xids) { - TXNID this_xid = toku_xids_get_innermost_xid(xids); // xid of transaction committing + // xid of transaction committing + TXNID this_xid = toku_xids_get_innermost_xid(xids); invariant(this_xid!=TXNID_NONE); // need to check for provisional entries in ule, otherwise // there is nothing to abort, not checking this may result @@ -1668,16 +1867,19 @@ void ule_apply_commit(ULE ule, XIDS xids) { if (ule->num_puxrs > 0 && ule_get_innermost_xid(ule) == this_xid) { // 3 cases: //1- it's already a committed value (do nothing) (num_puxrs==0) - //2- it's provisional but root level (make a new committed value (num_puxrs==1) + //2- it's provisional but root level (make a new committed value + // (num_puxrs==1) //3- it's provisional and not root (promote); (num_puxrs>1) if (ule->num_puxrs == 1) { //new committed value ule_promote_provisional_innermost_to_committed(ule); - } - else if (ule->num_puxrs > 1) { - //ule->uxrs[ule->num_cuxrs+ule->num_puxrs-1] is the innermost (this transaction) + } else if (ule->num_puxrs > 1) { + //ule->uxrs[ule->num_cuxrs+ule->num_puxrs-1] is the innermost + // (this transaction) //ule->uxrs[ule->num_cuxrs+ule->num_puxrs-2] is the 2nd innermost //We want to promote the innermost uxr one level out. - ule_promote_provisional_innermost_to_index(ule, ule->num_cuxrs+ule->num_puxrs-2); + ule_promote_provisional_innermost_to_index( + ule, + ule->num_cuxrs+ule->num_puxrs-2); } } } @@ -1687,14 +1889,17 @@ void ule_apply_commit(ULE ule, XIDS xids) { // // Purpose is to record an insert for this transaction (and set type correctly). -static void -ule_push_insert_uxr(ULE ule, bool is_committed, TXNID xid, uint32_t vallen, void * valp) { - UXR uxr = ule_get_first_empty_uxr(ule); +static inline void ule_push_insert_uxr( + ULE ule, + bool is_committed, TXNID xid, + uint32_t vallen, + void* valp) { + + UXR uxr = ule_get_first_empty_uxr(ule); if (is_committed) { invariant(ule->num_puxrs==0); ule->num_cuxrs++; - } - else { + } else { ule->num_puxrs++; } uxr->xid = xid; @@ -1706,23 +1911,21 @@ ule_push_insert_uxr(ULE ule, bool is_committed, TXNID xid, uint32_t vallen, void // Purpose is to record a delete for this transaction. If this transaction // is the root transaction, then truly delete the leafentry by marking the // ule as empty. -static void -ule_push_delete_uxr(ULE ule, bool is_committed, TXNID xid) { +static inline void ule_push_delete_uxr(ULE ule, bool is_committed, TXNID xid) { UXR uxr = ule_get_first_empty_uxr(ule); if (is_committed) { invariant(ule->num_puxrs==0); ule->num_cuxrs++; - } - else { + } else { ule->num_puxrs++; } uxr->xid = xid; uxr->type = XR_DELETE; } -// Purpose is to push a placeholder on the top of the leafentry's transaction stack. -static void -ule_push_placeholder_uxr(ULE ule, TXNID xid) { +// Purpose is to push a placeholder on the top of the leafentry's transaction +// stack. +static inline void ule_push_placeholder_uxr(ULE ule, TXNID xid) { invariant(ule->num_cuxrs>0); UXR uxr = ule_get_first_empty_uxr(ule); uxr->xid = xid; @@ -1731,16 +1934,14 @@ ule_push_placeholder_uxr(ULE ule, TXNID xid) { } // Return innermost transaction record. -static UXR -ule_get_innermost_uxr(ULE ule) { +static inline UXR ule_get_innermost_uxr(ULE ule) { invariant(ule->num_cuxrs > 0); UXR rval = &(ule->uxrs[ule->num_cuxrs + ule->num_puxrs - 1]); return rval; } // Return first empty transaction record -static UXR -ule_get_first_empty_uxr(ULE ule) { +static inline UXR ule_get_first_empty_uxr(ULE ule) { invariant(ule->num_puxrs < MAX_TRANSACTION_RECORDS-1); UXR rval = &(ule->uxrs[ule->num_cuxrs+ule->num_puxrs]); return rval; @@ -1748,14 +1949,12 @@ ule_get_first_empty_uxr(ULE ule) { // Remove the innermost transaction (pop the leafentry's stack), undoing // whatever the innermost transaction did. -static void -ule_remove_innermost_uxr(ULE ule) { +static inline void ule_remove_innermost_uxr(ULE ule) { //It is possible to remove the committed delete at first insert. invariant(ule->num_cuxrs > 0); if (ule->num_puxrs) { ule->num_puxrs--; - } - else { + } else { //This is for LOADER_USE_PUTS or transactionless environment //where messages use XIDS of 0 invariant(ule->num_cuxrs == 1); @@ -1764,14 +1963,12 @@ ule_remove_innermost_uxr(ULE ule) { } } -static TXNID -ule_get_innermost_xid(ULE ule) { +static inline TXNID ule_get_innermost_xid(ULE ule) { TXNID rval = ule_get_xid(ule, ule->num_cuxrs + ule->num_puxrs - 1); return rval; } -static TXNID -ule_get_xid(ULE ule, uint32_t index) { +static inline TXNID ule_get_xid(ULE ule, uint32_t index) { invariant(index < ule->num_cuxrs + ule->num_puxrs); TXNID rval = ule->uxrs[index].xid; return rval; @@ -1781,8 +1978,7 @@ ule_get_xid(ULE ule, uint32_t index) { // innermost recorded transactions), if necessary. This function is idempotent. // It makes no logical sense for a placeholder to be the innermost recorded // transaction record, so placeholders at the top of the stack are not legal. -static void -ule_remove_innermost_placeholders(ULE ule) { +static void ule_remove_innermost_placeholders(ULE ule) { UXR uxr = ule_get_innermost_uxr(ule); while (uxr_is_placeholder(uxr)) { invariant(ule->num_puxrs>0); @@ -1796,8 +1992,7 @@ ule_remove_innermost_placeholders(ULE ule) { // Note, after placeholders are added, an insert or delete will be added. This // function temporarily leaves the transaction stack in an illegal state (having // placeholders on top). -static void -ule_add_placeholders(ULE ule, XIDS xids) { +static void ule_add_placeholders(ULE ule, XIDS xids) { //Placeholders can be placed on top of the committed uxr. invariant(ule->num_cuxrs > 0); @@ -1819,47 +2014,40 @@ ule_add_placeholders(ULE ule, XIDS xids) { } } -uint64_t -ule_num_uxrs(ULE ule) { +uint64_t ule_num_uxrs(ULE ule) { return ule->num_cuxrs + ule->num_puxrs; } -UXR -ule_get_uxr(ULE ule, uint64_t ith) { +UXR ule_get_uxr(ULE ule, uint64_t ith) { invariant(ith < ule_num_uxrs(ule)); return &ule->uxrs[ith]; } -uint32_t -ule_get_num_committed(ULE ule) { +uint32_t ule_get_num_committed(ULE ule) { return ule->num_cuxrs; } -uint32_t -ule_get_num_provisional(ULE ule) { +uint32_t ule_get_num_provisional(ULE ule) { return ule->num_puxrs; } -int -ule_is_committed(ULE ule, uint64_t ith) { +int ule_is_committed(ULE ule, uint64_t ith) { invariant(ith < ule_num_uxrs(ule)); return ith < ule->num_cuxrs; } -int -ule_is_provisional(ULE ule, uint64_t ith) { +int ule_is_provisional(ULE ule, uint64_t ith) { invariant(ith < ule_num_uxrs(ule)); return ith >= ule->num_cuxrs; } // return size of data for innermost uxr, the size of val -uint32_t -ule_get_innermost_numbytes(ULE ule, uint32_t keylen) { +uint32_t ule_get_innermost_numbytes(ULE ule, uint32_t keylen) { uint32_t rval; UXR uxr = ule_get_innermost_uxr(ule); - if (uxr_is_delete(uxr)) + if (uxr_is_delete(uxr)) { rval = 0; - else { + } else { rval = uxr_get_vallen(uxr) + keylen; } return rval; @@ -1870,68 +2058,65 @@ ule_get_innermost_numbytes(ULE ule, uint32_t keylen) { // This layer of abstraction (uxr_xxx) understands uxr and nothing else. // -static inline bool -uxr_type_is_insert(uint8_t type) { +static inline bool uxr_type_is_insert(uint8_t type) { bool rval = (bool)(type == XR_INSERT); return rval; } -bool -uxr_is_insert(UXR uxr) { +bool uxr_is_insert(UXR uxr) { return uxr_type_is_insert(uxr->type); } -static inline bool -uxr_type_is_delete(uint8_t type) { +static inline bool uxr_type_is_delete(uint8_t type) { bool rval = (bool)(type == XR_DELETE); return rval; } -bool -uxr_is_delete(UXR uxr) { +bool uxr_is_delete(UXR uxr) { return uxr_type_is_delete(uxr->type); } -static inline bool -uxr_type_is_placeholder(uint8_t type) { +static inline bool uxr_type_is_placeholder(uint8_t type) { bool rval = (bool)(type == XR_PLACEHOLDER); return rval; } -bool -uxr_is_placeholder(UXR uxr) { +bool uxr_is_placeholder(UXR uxr) { return uxr_type_is_placeholder(uxr->type); } -void * -uxr_get_val(UXR uxr) { +void* uxr_get_val(UXR uxr) { return uxr->valp; } -uint32_t -uxr_get_vallen(UXR uxr) { +uint32_t uxr_get_vallen(UXR uxr) { return uxr->vallen; } -TXNID -uxr_get_txnid(UXR uxr) { +TXNID uxr_get_txnid(UXR uxr) { return uxr->xid; } -static int -le_iterate_get_accepted_index(TXNID *xids, uint32_t *index, uint32_t num_xids, LE_ITERATE_CALLBACK f, TOKUTXN context, bool top_is_provisional) { +static int le_iterate_get_accepted_index( + TXNID* xids, + uint32_t* index, + uint32_t num_xids, + LE_ITERATE_CALLBACK f, + TOKUTXN context, + bool top_is_provisional) { + uint32_t i; int r = 0; - // if this for loop does not return anything, we return num_xids-1, which should map to T_0 + // if this for loop does not return anything, we return num_xids-1, which + // should map to T_0 for (i = 0; i < num_xids - 1; i++) { TXNID xid = toku_dtoh64(xids[i]); r = f(xid, context, (i == 0 && top_is_provisional)); if (r==TOKUDB_ACCEPT) { r = 0; break; //or goto something - } - else if (r!=0) { + } else if (r!=0) { break; } } @@ -1940,8 +2125,7 @@ le_iterate_get_accepted_index(TXNID *xids, uint32_t *index, uint32_t num_xids, L } #if ULE_DEBUG -static void -ule_verify_xids(ULE ule, uint32_t interesting, TXNID *xids) { +static void ule_verify_xids(ULE ule, uint32_t interesting, TXNID *xids) { int has_p = (ule->num_puxrs != 0); invariant(ule->num_cuxrs + has_p == interesting); uint32_t i; @@ -1953,21 +2137,29 @@ ule_verify_xids(ULE ule, uint32_t interesting, TXNID *xids) { #endif // -// Iterates over "possible" TXNIDs in a leafentry's stack, until one is accepted by 'f'. If the value -// associated with the accepted TXNID is not an insert, then set *is_emptyp to true, otherwise false +// Iterates over "possible" TXNIDs in a leafentry's stack, until one is +// accepted by 'f'. If the value associated with the accepted TXNID is not an +// insert, then set *is_emptyp to true, otherwise false // The "possible" TXNIDs are: -// if provisionals exist, then the first possible TXNID is the outermost provisional. -// The next possible TXNIDs are the committed TXNIDs, from most recently committed to T_0. -// If provisionals exist, and the outermost provisional is accepted by 'f', +// If provisionals exist, then the first possible TXNID is the outermost +// provisional. +// The next possible TXNIDs are the committed TXNIDs, from most recently +// committed to T_0. +// If provisionals exist, and the outermost provisional is accepted by 'f', // the associated value checked is the innermost provisional's value. // Parameters: // le - leafentry to iterate over -// f - callback function that checks if a TXNID in le is accepted, and its associated value should be examined. +// f - callback function that checks if a TXNID in le is accepted, and its +// associated value should be examined. // is_delp - output parameter that returns answer // context - parameter for f // -static int -le_iterate_is_del(LEAFENTRY le, LE_ITERATE_CALLBACK f, bool *is_delp, TOKUTXN context) { +static int le_iterate_is_del( + LEAFENTRY le, + LE_ITERATE_CALLBACK f, + bool* is_delp, + TOKUTXN context) { + #if ULE_DEBUG ULE_S ule; le_unpack(&ule, le); @@ -2002,8 +2194,17 @@ le_iterate_is_del(LEAFENTRY le, LE_ITERATE_CALLBACK f, bool *is_delp, TOKUTXN co #if ULE_DEBUG ule_verify_xids(&ule, num_interesting, xids); #endif - r = le_iterate_get_accepted_index(xids, &index, num_interesting, f, context, (num_puxrs != 0)); - if (r!=0) goto cleanup; + r = + le_iterate_get_accepted_index( + xids, + &index, + num_interesting, + f, + context, + (num_puxrs != 0)); + if (r != 0) { + goto cleanup; + } invariant(index < num_interesting); //Skip TXNIDs @@ -2017,7 +2218,9 @@ le_iterate_is_del(LEAFENTRY le, LE_ITERATE_CALLBACK f, bool *is_delp, TOKUTXN co #if ULE_DEBUG { uint32_t has_p = (ule.num_puxrs != 0); - uint32_t ule_index = (index==0) ? ule.num_cuxrs + ule.num_puxrs - 1 : ule.num_cuxrs - 1 + has_p - index; + uint32_t ule_index = (index==0) ? + ule.num_cuxrs + ule.num_puxrs - 1 : + ule.num_cuxrs - 1 + has_p - index; UXR uxr = ule.uxrs + ule_index; invariant(uxr_is_delete(uxr) == is_del); } @@ -2034,7 +2237,11 @@ le_iterate_is_del(LEAFENTRY le, LE_ITERATE_CALLBACK f, bool *is_delp, TOKUTXN co return r; } -static int le_iterate_read_committed_callback(TXNID txnid, TOKUTXN txn, bool is_provisional UU()) { +static int le_iterate_read_committed_callback( + TXNID txnid, + TOKUTXN txn, + bool is_provisional UU()) { + if (is_provisional) { return toku_txn_reads_txnid(txnid, txn, is_provisional); } @@ -2058,33 +2265,40 @@ int le_val_is_del(LEAFENTRY le, enum cursor_read_type read_type, TOKUTXN txn) { txn ); rval = is_del; - } - else if (read_type == C_READ_ANY) { + } else if (read_type == C_READ_ANY) { rval = le_latest_is_del(le); - } - else { + } else { invariant(false); } return rval; } // -// Iterates over "possible" TXNIDs in a leafentry's stack, until one is accepted by 'f'. Set -// valpp and vallenp to value and length associated with accepted TXNID +// Iterates over "possible" TXNIDs in a leafentry's stack, until one is accepted +// by 'f'. Set valpp and vallenp to value and length associated with accepted +// TXNID // The "possible" TXNIDs are: -// if provisionals exist, then the first possible TXNID is the outermost provisional. -// The next possible TXNIDs are the committed TXNIDs, from most recently committed to T_0. -// If provisionals exist, and the outermost provisional is accepted by 'f', +// If provisionals exist, then the first possible TXNID is the outermost +// provisional. +// The next possible TXNIDs are the committed TXNIDs, from most recently +// committed to T_0. +// If provisionals exist, and the outermost provisional is accepted by 'f', // the associated length value is the innermost provisional's length and value. // Parameters: // le - leafentry to iterate over -// f - callback function that checks if a TXNID in le is accepted, and its associated value should be examined. +// f - callback function that checks if a TXNID in le is accepted, and its +// associated value should be examined. // valpp - output parameter that returns pointer to value // vallenp - output parameter that returns length of value // context - parameter for f // -int -le_iterate_val(LEAFENTRY le, LE_ITERATE_CALLBACK f, void** valpp, uint32_t *vallenp, TOKUTXN context) { +int le_iterate_val( + LEAFENTRY le, + LE_ITERATE_CALLBACK f, + void** valpp, + uint32_t* vallenp, + TOKUTXN context) { + #if ULE_DEBUG ULE_S ule; le_unpack(&ule, le); @@ -2124,8 +2338,17 @@ le_iterate_val(LEAFENTRY le, LE_ITERATE_CALLBACK f, void** valpp, uint32_t *vall #if ULE_DEBUG ule_verify_xids(&ule, num_interesting, xids); #endif - r = le_iterate_get_accepted_index(xids, &index, num_interesting, f, context, (num_puxrs != 0)); - if (r!=0) goto cleanup; + r = + le_iterate_get_accepted_index( + xids, + &index, + num_interesting, + f, + context, + (num_puxrs != 0)); + if (r != 0) { + goto cleanup; + } invariant(index < num_interesting); //Skip TXNIDs @@ -2158,7 +2381,9 @@ le_iterate_val(LEAFENTRY le, LE_ITERATE_CALLBACK f, void** valpp, uint32_t *vall #if ULE_DEBUG { uint32_t has_p = (ule.num_puxrs != 0); - uint32_t ule_index = (index==0) ? ule.num_cuxrs + ule.num_puxrs - 1 : ule.num_cuxrs - 1 + has_p - index; + uint32_t ule_index = (index==0) ? + ule.num_cuxrs + ule.num_puxrs - 1 : + ule.num_cuxrs - 1 + has_p - index; UXR uxr = ule.uxrs + ule_index; invariant(uxr_is_insert(uxr)); invariant(uxr->vallen == vallen); @@ -2188,10 +2413,15 @@ verify_is_empty:; return r; } -void le_extract_val(LEAFENTRY le, - // should we return the entire leafentry as the val? - bool is_leaf_mode, enum cursor_read_type read_type, - TOKUTXN ttxn, uint32_t *vallen, void **val) { +void le_extract_val( + LEAFENTRY le, + // should we return the entire leafentry as the val? + bool is_leaf_mode, + enum cursor_read_type read_type, + TOKUTXN ttxn, + uint32_t* vallen, + void** val) { + if (is_leaf_mode) { *val = le; *vallen = leafentry_memsize(le); @@ -2199,18 +2429,11 @@ void le_extract_val(LEAFENTRY le, LE_ITERATE_CALLBACK f = (read_type == C_READ_SNAPSHOT) ? toku_txn_reads_txnid : le_iterate_read_committed_callback; - int r = le_iterate_val( - le, - f, - val, - vallen, - ttxn - ); + int r = le_iterate_val(le, f, val, vallen, ttxn); lazy_assert_zero(r); } else if (read_type == C_READ_ANY){ *val = le_latest_val_and_len(le, vallen); - } - else { + } else { assert(false); } } @@ -2244,9 +2467,9 @@ static_assert(18 == sizeof(leafentry_13), "wrong size"); static_assert(9 == __builtin_offsetof(leafentry_13, u), "wrong offset"); //Requires: -// Leafentry that ule represents should not be destroyed (is not just all deletes) -static size_t -le_memsize_from_ule_13 (ULE ule, LEAFENTRY_13 le) { +// Leafentry that ule represents should not be destroyed (is not just all +// deletes) +static size_t le_memsize_from_ule_13 (ULE ule, LEAFENTRY_13 le) { uint32_t num_uxrs = ule->num_cuxrs + ule->num_puxrs; assert(num_uxrs); size_t rval; @@ -2257,8 +2480,7 @@ le_memsize_from_ule_13 (ULE ule, LEAFENTRY_13 le) { +4 //vallen +le->keylen //actual key +ule->uxrs[0].vallen; //actual val - } - else { + } else { rval = 1 //num_uxrs +4 //keylen +le->keylen //actual key @@ -2276,16 +2498,20 @@ le_memsize_from_ule_13 (ULE ule, LEAFENTRY_13 le) { return rval; } -//This function is mostly copied from 4.1.1 (which is version 12, same as 13 except that only 13 is upgradable). -// Note, number of transaction records in version 13 has been replaced by separate counters in version 14 (MVCC), -// one counter for committed transaction records and one counter for provisional transaction records. When -// upgrading a version 13 le to version 14, the number of committed transaction records is always set to one (1) -// and the number of provisional transaction records is set to the original number of transaction records -// minus one. The bottom transaction record is assumed to be a committed value. (If there is no committed -// value then the bottom transaction record of version 13 is a committed delete.) -// This is the only change from the 4.1.1 code. The rest of the leafentry is read as is. -static void -le_unpack_13(ULE ule, LEAFENTRY_13 le) { +// This function is mostly copied from 4.1.1 (which is version 12, same as 13 +// except that only 13 is upgradable). +// Note, number of transaction records in version 13 has been replaced by +// separate counters in version 14 (MVCC), one counter for committed transaction +// records and one counter for provisional transaction records. When upgrading +// a version 13 le to version 14, the number of committed transaction records is +// always set to one (1) and the number of provisional transaction records is +// set to the original number of transaction records minus one. The bottom +// transaction record is assumed to be a committed value. (If there is no +// committed value then the bottom transaction record of version 13 is a +// committed delete.) +// This is the only change from the 4.1.1 code. The rest of the leafentry is +// read as is. +static void le_unpack_13(ULE ule, LEAFENTRY_13 le) { //Read num_uxrs uint8_t num_xrs = le->num_xrs; assert(num_xrs > 0); @@ -2302,15 +2528,15 @@ le_unpack_13(ULE ule, LEAFENTRY_13 le) { uint8_t *p; if (num_xrs == 1) { //Unpack a 'committed leafentry' (No uncommitted transactions exist) - ule->uxrs[0].type = XR_INSERT; //Must be or the leafentry would not exist + //Must be or the leafentry would not exist + ule->uxrs[0].type = XR_INSERT; ule->uxrs[0].vallen = vallen_of_innermost_insert; ule->uxrs[0].valp = &le->u.comm.key_val[keylen]; ule->uxrs[0].xid = 0; //Required. //Set p to immediately after leafentry p = &le->u.comm.key_val[keylen + vallen_of_innermost_insert]; - } - else { + } else { //Unpack a 'provisional leafentry' (Uncommitted transactions exist) //Read in type. @@ -2337,8 +2563,7 @@ le_unpack_13(ULE ule, LEAFENTRY_13 le) { //Not innermost, so load the type. uxr->type = *p; p += 1; - } - else { + } else { //Innermost, load the type previously read from header uxr->type = innermost_type; } @@ -2349,12 +2574,11 @@ le_unpack_13(ULE ule, LEAFENTRY_13 le) { //Not committed nor outermost uncommitted, so load the xid. uxr->xid = toku_dtoh64(*(TXNID*)p); p += 8; - } - else if (i == 1) { - //Outermost uncommitted, load the xid previously read from header + } else if (i == 1) { + //Outermost uncommitted, load the xid previously read from + //header uxr->xid = xid_outermost_uncommitted; - } - else { + } else { // i == 0, committed entry uxr->xid = 0; } @@ -2367,9 +2591,9 @@ le_unpack_13(ULE ule, LEAFENTRY_13 le) { uxr->valp = p; p += uxr->vallen; - } - else { - //Innermost insert, load the vallen/valp previously read from header + } else { + //Innermost insert, load the vallen/valp previously read + //from header uxr->vallen = vallen_of_innermost_insert; uxr->valp = valp_of_innermost_insert; found_innermost_insert = true; @@ -2384,8 +2608,7 @@ le_unpack_13(ULE ule, LEAFENTRY_13 le) { #endif } -size_t -leafentry_disksize_13(LEAFENTRY_13 le) { +size_t leafentry_disksize_13(LEAFENTRY_13 le) { ULE_S ule; le_unpack_13(&ule, le); size_t memsize = le_memsize_from_ule_13(&ule, le); @@ -2393,13 +2616,13 @@ leafentry_disksize_13(LEAFENTRY_13 le) { return memsize; } -int -toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, - void** keyp, - uint32_t* keylen, - size_t *new_leafentry_memorysize, - LEAFENTRY *new_leafentry_p - ) { +int toku_le_upgrade_13_14( + LEAFENTRY_13 old_leafentry, + void** keyp, + uint32_t* keylen, + size_t* new_leafentry_memorysize, + LEAFENTRY* new_leafentry_p) { + ULE_S ule; int rval; invariant(old_leafentry); @@ -2408,23 +2631,23 @@ toku_le_upgrade_13_14(LEAFENTRY_13 old_leafentry, *keylen = old_leafentry->keylen; if (old_leafentry->num_xrs == 1) { *keyp = old_leafentry->u.comm.key_val; - } - else { + } else { *keyp = old_leafentry->u.prov.key_val_xrs; } // We used to pass NULL for omt and mempool, so that we would use // malloc instead of a mempool. However after supporting upgrade, // we need to use mempools and the OMT. - rval = le_pack(&ule, // create packed leafentry - nullptr, - 0, //only matters if we are passing in a bn_data - nullptr, //only matters if we are passing in a bn_data - 0, //only matters if we are passing in a bn_data - 0, //only matters if we are passing in a bn_data - 0, //only matters if we are passing in a bn_data - new_leafentry_p, - nullptr //only matters if we are passing in a bn_data - ); + rval = + le_pack( + &ule, // create packed leafentry + nullptr, + 0, //only matters if we are passing in a bn_data + nullptr, //only matters if we are passing in a bn_data + 0, //only matters if we are passing in a bn_data + 0, //only matters if we are passing in a bn_data + 0, //only matters if we are passing in a bn_data + new_leafentry_p, + nullptr); //only matters if we are passing in a bn_data ule_cleanup(&ule); *new_leafentry_memorysize = leafentry_memsize(*new_leafentry_p); return rval; diff --git a/storage/tokudb/PerconaFT/locktree/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/locktree/tests/CMakeLists.txt index 47ec4d884fb2a..20ab682ae1238 100644 --- a/storage/tokudb/PerconaFT/locktree/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/locktree/tests/CMakeLists.txt @@ -7,7 +7,7 @@ if(BUILD_TESTING) foreach(src ${srcs}) get_filename_component(base ${src} NAME_WE) - add_executable(${base} ${base}) + add_executable(${base} ${base}.cc) add_space_separated_property(TARGET ${base} COMPILE_FLAGS -fvisibility=hidden) target_link_libraries(${base} locktree ft ${LIBTOKUPORTABILITY}) add_locktree_test(${base}) diff --git a/storage/tokudb/PerconaFT/portability/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/portability/tests/CMakeLists.txt index 7fea21fc8e327..ff2333274364f 100644 --- a/storage/tokudb/PerconaFT/portability/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/portability/tests/CMakeLists.txt @@ -10,7 +10,7 @@ if(BUILD_TESTING) foreach(src ${srcs}) get_filename_component(test ${src} NAME_WE) - add_executable(${test} ${test}) + add_executable(${test} ${test}.cc) target_link_libraries(${test} ${LIBTOKUPORTABILITY}) set_target_properties(${test} PROPERTIES POSITION_INDEPENDENT_CODE ON) add_space_separated_property(TARGET ${test} COMPILE_FLAGS -fvisibility=hidden) diff --git a/storage/tokudb/PerconaFT/portability/toku_pthread.h b/storage/tokudb/PerconaFT/portability/toku_pthread.h index 25cf48dfd8caa..84c277362010f 100644 --- a/storage/tokudb/PerconaFT/portability/toku_pthread.h +++ b/storage/tokudb/PerconaFT/portability/toku_pthread.h @@ -72,15 +72,18 @@ typedef struct toku_mutex_aligned { toku_mutex_t aligned_mutex __attribute__((__aligned__(64))); } toku_mutex_aligned_t; -// Different OSes implement mutexes as different amounts of nested structs. -// C++ will fill out all missing values with zeroes if you provide at least one zero, but it needs the right amount of nesting. -#if defined(__FreeBSD__) -# define ZERO_MUTEX_INITIALIZER {0} -#elif defined(__APPLE__) -# define ZERO_MUTEX_INITIALIZER {{0}} -#else // __linux__, at least -# define ZERO_MUTEX_INITIALIZER {{{0}}} -#endif +// Initializing with {} will fill in a struct with all zeros. +// But you may also need a pragma to suppress the warnings, as follows +// +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wmissing-field-initializers" +// toku_mutex_t foo = ZERO_MUTEX_INITIALIZER; +// #pragma GCC diagnostic pop +// +// In general it will be a lot of busy work to make this codebase compile +// cleanly with -Wmissing-field-initializers + +# define ZERO_MUTEX_INITIALIZER {} #if TOKU_PTHREAD_DEBUG # define TOKU_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER, .owner = 0, .locked = false, .valid = true } @@ -223,15 +226,9 @@ typedef struct toku_cond { pthread_cond_t pcond; } toku_cond_t; -// Different OSes implement mutexes as different amounts of nested structs. -// C++ will fill out all missing values with zeroes if you provide at least one zero, but it needs the right amount of nesting. -#if defined(__FreeBSD__) -# define ZERO_COND_INITIALIZER {0} -#elif defined(__APPLE__) -# define ZERO_COND_INITIALIZER {{0}} -#else // __linux__, at least -# define ZERO_COND_INITIALIZER {{{0}}} -#endif +// Same considerations as for ZERO_MUTEX_INITIALIZER apply +#define ZERO_COND_INITIALIZER {} + #define TOKU_COND_INITIALIZER {PTHREAD_COND_INITIALIZER} static inline void diff --git a/storage/tokudb/PerconaFT/portability/toku_time.h b/storage/tokudb/PerconaFT/portability/toku_time.h index c476b64a212c5..11a3f3aa2b99c 100644 --- a/storage/tokudb/PerconaFT/portability/toku_time.h +++ b/storage/tokudb/PerconaFT/portability/toku_time.h @@ -108,3 +108,13 @@ static inline uint64_t toku_current_time_microsec(void) { gettimeofday(&t, NULL); return t.tv_sec * (1UL * 1000 * 1000) + t.tv_usec; } + +// sleep microseconds +static inline void toku_sleep_microsec(uint64_t ms) { + struct timeval t; + + t.tv_sec = ms / 1000000; + t.tv_usec = ms % 1000000; + + select(0, NULL, NULL, NULL, &t); +} diff --git a/storage/tokudb/PerconaFT/src/export.map b/storage/tokudb/PerconaFT/src/export.map index 3f2c7569ea4e3..fc2be5f41a546 100644 --- a/storage/tokudb/PerconaFT/src/export.map +++ b/storage/tokudb/PerconaFT/src/export.map @@ -82,6 +82,7 @@ toku_test_db_redirect_dictionary; toku_test_get_latest_lsn; toku_test_get_checkpointing_user_data_status; + toku_set_test_txn_sync_callback; toku_indexer_set_test_only_flags; toku_increase_last_xid; diff --git a/storage/tokudb/PerconaFT/src/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/src/tests/CMakeLists.txt index 457dd9b96a9db..47f6aa44a75e8 100644 --- a/storage/tokudb/PerconaFT/src/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/src/tests/CMakeLists.txt @@ -49,15 +49,15 @@ if(BUILD_TESTING OR BUILD_SRC_TESTS) ## #5138 only reproduces when using the static library. list(REMOVE_ITEM tdb_bins test-5138.tdb) - add_executable(test-5138.tdb test-5138) + add_executable(test-5138.tdb test-5138.cc) target_link_libraries(test-5138.tdb ${LIBTOKUDB}_static z ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) add_space_separated_property(TARGET test-5138.tdb COMPILE_FLAGS -fvisibility=hidden) add_ydb_test(test-5138.tdb) - + add_ydb_test(rollback-inconsistency.tdb) foreach(bin ${tdb_bins}) get_filename_component(base ${bin} NAME_WE) - add_executable(${base}.tdb ${base}) + add_executable(${base}.tdb ${base}.cc) # Some of the symbols in util may not be exported properly by # libtokudb.so. # We link the test with util directly so that the test code itself can use diff --git a/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc b/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc new file mode 100644 index 0000000000000..2fc05b23f0d33 --- /dev/null +++ b/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc @@ -0,0 +1,161 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +#ident "$Id$" +/*====== +This file is part of PerconaFT. + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + PerconaFT 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 PerconaFT. If not, see . + +---------------------------------------- + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License, version 3, + as published by the Free Software Foundation. + + PerconaFT 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with PerconaFT. If not, see . +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "test.h" + +// insert enough rows with a child txn and then force an eviction to verify the rollback +// log node is in valid state. +// the test fails without the fix (and of course passes with it). +// The test basically simulates the test script of George's. + + +static void +populate_table(int start, int end, DB_TXN * parent, DB_ENV * env, DB * db) { + DB_TXN *txn = NULL; + int r = env->txn_begin(env, parent, &txn, 0); assert_zero(r); + for (int i = start; i < end; i++) { + int k = htonl(i); + char kk[4]; + char str[220]; + memset(kk, 0, sizeof kk); + memcpy(kk, &k, sizeof k); + memset(str,'a', sizeof str-1); + DBT key = { .data = kk, .size = sizeof kk }; + DBT val = { .data = str, .size = 220 }; + r = db->put(db, txn, &key, &val, 0); + assert_zero(r); + } + r = txn->commit(txn, 0); + assert_zero(r); +} + +static void +populate_and_test(DB_ENV *env, DB *db) { + int r; + DB_TXN *parent = NULL; + r = env->txn_begin(env, NULL, &parent, 0); assert_zero(r); + + populate_table(0, 128, parent, env, db); + + //we know the eviction is going to happen here and the log node of parent txn is going to be evicted + //due to the extremely low cachesize. + populate_table(128, 256, parent, env, db); + + //again eviction due to the memory pressure. 256 rows is the point when that rollback log spills out. The spilled node + //will be written back but will not be dirtied by including rollback nodes from child txn(in which case the bug is bypassed). + populate_table(256, 512, parent, env, db); + + r = parent->abort(parent); assert_zero(r); + + //try to search anything in the lost range + int k = htonl(200); + char kk[4]; + memset(kk, 0, sizeof kk); + memcpy(kk, &k, sizeof k); + DBT key = { .data = kk, .size = sizeof kk }; + DBT val; + r = db->get(db, NULL, &key, &val, 0); + assert(r==DB_NOTFOUND); + +} + +static void +run_test(void) { + int r; + DB_ENV *env = NULL; + r = db_env_create(&env, 0); + assert_zero(r); + env->set_errfile(env, stderr); + + //setting up the cachetable size 64k + uint32_t cachesize = 64*1024; + r = env->set_cachesize(env, 0, cachesize, 1); + assert_zero(r); + + //setting up the log write block size to 4k so the rollback log nodes spill in accordance with the node size + r = env->set_lg_bsize(env, 4096); + assert_zero(r); + + r = env->open(env, TOKU_TEST_FILENAME, DB_INIT_MPOOL|DB_CREATE|DB_THREAD |DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_PRIVATE, S_IRWXU+S_IRWXG+S_IRWXO); + assert_zero(r); + + DB *db = NULL; + r = db_create(&db, env, 0); + assert_zero(r); + + r = db->set_pagesize(db, 4096); + assert_zero(r); + + r = db->set_readpagesize(db, 1024); + assert_zero(r); + + r = db->open(db, NULL, "test.tdb", NULL, DB_BTREE, DB_AUTO_COMMIT+DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); + assert_zero(r); + + populate_and_test(env, db); + + r = db->close(db, 0); assert_zero(r); + + r = env->close(env, 0); assert_zero(r); +} + +int +test_main(int argc, char * const argv[]) { + int r; + + // parse_args(argc, argv); + for (int i = 1; i < argc; i++) { + char * const arg = argv[i]; + if (strcmp(arg, "-v") == 0) { + verbose++; + continue; + } + if (strcmp(arg, "-q") == 0) { + verbose = 0; + continue; + } + } + + toku_os_recursive_delete(TOKU_TEST_FILENAME); + r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO); assert_zero(r); + + run_test(); + + return 0; +} + diff --git a/storage/tokudb/PerconaFT/src/tests/stat64-root-changes.cc b/storage/tokudb/PerconaFT/src/tests/stat64-root-changes.cc index 0c70b0669adcf..a2b48e443cdfd 100644 --- a/storage/tokudb/PerconaFT/src/tests/stat64-root-changes.cc +++ b/storage/tokudb/PerconaFT/src/tests/stat64-root-changes.cc @@ -166,7 +166,7 @@ run_test (void) { DB_BTREE_STAT64 s; r = db->stat64(db, NULL, &s); CKERR(r); - assert(s.bt_nkeys == 1 && s.bt_dsize == sizeof key + sizeof val); + assert(s.bt_nkeys == 0); r = db->close(db, 0); CKERR(r); @@ -176,7 +176,7 @@ run_test (void) { r = txn->commit(txn, 0); CKERR(r); r = db->stat64(db, NULL, &s); CKERR(r); - assert(s.bt_nkeys == 1 && s.bt_dsize == sizeof key + sizeof val); + assert(s.bt_nkeys == 0); } // verify update callback overwrites the row diff --git a/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc b/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc new file mode 100644 index 0000000000000..c3ebbd811bb13 --- /dev/null +++ b/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc @@ -0,0 +1,528 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +#ident "$Id$" +/*====== +This file is part of PerconaFT. + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + PerconaFT 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 PerconaFT. If not, see . + +---------------------------------------- + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License, version 3, + as published by the Free Software Foundation. + + PerconaFT 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with PerconaFT. If not, see . +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "test.h" +#include + +#include +#include + +// Tests that the logical row counts are correct and not subject to variance +// due to normal insert/delete messages within the tree with the few exceptions +// of 1) rollback messages not yet applied; 2) inserts messages turned to +// updates on apply; and 3) missing leafentries on delete messages on apply. + +static DB_TXN* const null_txn = 0; +static const uint64_t num_records = 4*1024; + +#define CHECK_NUM_ROWS(_expected, _stats) assert(_stats.bt_ndata == _expected) + +static DB* create_db(const char* fname, DB_ENV* env) { + int r; + DB* db; + + r = db_create(&db, env, 0); + assert(r == 0); + db->set_errfile(db, stderr); + + r = db->set_pagesize(db, 8192); + assert(r == 0); + + r = db->set_readpagesize(db, 1024); + assert(r == 0); + + r = db->set_fanout(db, 4); + assert(r == 0); + + r = db->set_compression_method(db, TOKU_NO_COMPRESSION); + assert(r == 0); + + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, + 0666); + assert(r == 0); + + return db; +} +static void add_records(DB* db, DB_TXN* txn, uint64_t start_id, uint64_t num) { + int r; + for (uint64_t i = 0, j=start_id; i < num; i++,j++) { + char key[100], val[256]; + DBT k,v; + snprintf(key, 100, "%08lu", j); + snprintf(val, 256, "%*s", 200, key); + r = + db->put( + db, + txn, + dbt_init(&k, key, 1+strlen(key)), + dbt_init(&v, val, 1+strlen(val)), + 0); + assert(r == 0); + } +} +static void delete_records( + DB* db, + DB_TXN* txn, + uint64_t start_id, + uint64_t num) { + + int r; + for (uint64_t i = 0, j=start_id; i < num; i++,j++) { + char key[100]; + DBT k; + snprintf(key, 100, "%08lu", j); + r = + db->del( + db, + txn, + dbt_init(&k, key, 1+strlen(key)), + 0); + assert(r == 0); + } +} +static void full_optimize(DB* db) { + int r; + uint64_t loops_run = 0; + + r = db->optimize(db); + assert(r == 0); + + r = db->hot_optimize(db, NULL, NULL, NULL, NULL, &loops_run); + assert(r == 0); +} +static void test_insert_commit(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf("%s : before commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + + r = txn->commit(txn, 0); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + + db->close(db, 0); +} +static void test_insert_delete_commit(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf("%s : before delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + + delete_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + + r = txn->commit(txn, 0); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + + db->close(db, 0); +} +static void test_insert_commit_delete_commit(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf( + "%s : before insert commit %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + r = txn->commit(txn, 0); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf( + "%s : after insert commit %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + delete_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + + r = txn->commit(txn, 0); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf( + "%s : after delete commit %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + db->close(db, 0); +} +static void test_insert_rollback(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf("%s : before rollback %lu rows\n", __FUNCTION__, stats.bt_ndata); + + r = txn->abort(txn); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + // CAN NOT TEST stats HERE AS THEY ARE SOMEWHAT NON_DETERMINISTIC UNTIL + // optimize + hot_optimize HAVE BEEN RUN DUE TO THE FACT THAT ROLLBACK + // MESSAGES ARE "IN-FLIGHT" IN THE TREE AND MUST BE APPLIED IN ORDER TO + // CORRECT THE RUNNING LOGICAL COUNT + if (verbose) + printf("%s : after rollback %lu rows\n", __FUNCTION__, stats.bt_ndata); + + full_optimize(db); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf( + "%s : after rollback optimize %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + db->close(db, 0); +} +static void test_insert_delete_rollback(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf("%s : before delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + + delete_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + + r = txn->abort(txn); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + + db->close(db, 0); +} +static void test_insert_commit_delete_rollback(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf( + "%s : before insert commit %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + r = txn->commit(txn, 0); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf( + "%s : after insert commit %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + delete_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(0, stats); + if (verbose) + printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + + r = txn->abort(txn); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + // CAN NOT TEST stats HERE AS THEY ARE SOMEWHAT NON_DETERMINISTIC UNTIL + // optimize + hot_optimize HAVE BEEN RUN DUE TO THE FACT THAT ROLLBACK + // MESSAGES ARE "IN-FLIGHT" IN THE TREE AND MUST BE APPLIED IN ORDER TO + // CORRECT THE RUNNING LOGICAL COUNT + if (verbose) + printf( + "%s : after delete rollback %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + full_optimize(db); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf( + "%s : after delete rollback optimize %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + db->close(db, 0); +} +static inline uint64_t time_in_microsec() { + struct timeval t; + gettimeofday(&t, NULL); + return t.tv_sec * (1UL * 1000 * 1000) + t.tv_usec; +} + +static int test_recount_insert_commit_progress( + uint64_t count, + uint64_t deleted, + void*) { + + if (verbose) + printf( + "%s : count[%lu] deleted[%lu]\n", + __FUNCTION__, + count, + deleted); + return 0; +} +static int test_recount_cancel_progress(uint64_t, uint64_t, void*) { + return 1; +} + +static void test_recount_insert_commit(DB_ENV* env) { + int r; + DB* db; + DB_TXN* txn; + DB_BTREE_STAT64 stats; + + db = create_db(__FUNCTION__, env); + + r = env->txn_begin(env, null_txn, &txn, 0); + assert(r == 0); + + add_records(db, txn, 0, num_records); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf( + "%s : before commit %lu rows\n", + __FUNCTION__, + stats.bt_ndata); + + r = txn->commit(txn, 0); + assert(r == 0); + + r = db->stat64(db, null_txn, &stats); + assert(r == 0); + + CHECK_NUM_ROWS(num_records, stats); + if (verbose) + printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + + // test that recount counted correct # of rows + r = db->recount_rows(db, test_recount_insert_commit_progress, NULL); + assert(r == 0); + CHECK_NUM_ROWS(num_records, stats); + + // test that recount callback cancel returns + r = db->recount_rows(db, test_recount_cancel_progress, NULL); + assert(r == 1); + CHECK_NUM_ROWS(num_records, stats); + + db->close(db, 0); +} +int test_main(int UU(argc), char UU(*const argv[])) { + int r; + DB_ENV* env; + + toku_os_recursive_delete(TOKU_TEST_FILENAME); + toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU + S_IRWXG + S_IRWXO); + + r = db_env_create(&env, 0); + assert(r == 0); + + r = + env->open( + env, + TOKU_TEST_FILENAME, + DB_INIT_MPOOL + DB_INIT_LOG + DB_INIT_TXN + DB_PRIVATE + DB_CREATE, + S_IRWXU + S_IRWXG + S_IRWXO); + assert(r == 0); + + test_insert_commit(env); + test_insert_delete_commit(env); + test_insert_commit_delete_commit(env); + test_insert_rollback(env); + test_insert_delete_rollback(env); + test_insert_commit_delete_rollback(env); + test_recount_insert_commit(env); + + r = env->close(env, 0); + assert(r == 0); + + return 0; +} diff --git a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc new file mode 100644 index 0000000000000..b55610757e283 --- /dev/null +++ b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc @@ -0,0 +1,217 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +#ident "$Id$" +/*====== +This file is part of PerconaFT. + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + PerconaFT 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 PerconaFT. If not, see . + +---------------------------------------- + + PerconaFT is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License, version 3, + as published by the Free Software Foundation. + + PerconaFT 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with PerconaFT. If not, see . +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +//In response to the read-commit crash bug in the sysbench, this test is created to test +//the atomicity of the txn manager when handling the child txn snapshot. +//The test is supposed to fail before the read-commit-fix. + +#include "test.h" +#include "toku_pthread.h" +#include "ydb.h" +struct test_sync { + int state; + toku_mutex_t lock; + toku_cond_t cv; +}; + +static void test_sync_init(struct test_sync *UU(sync)) { +#if TOKU_DEBUG_TXN_SYNC + sync->state = 0; + toku_mutex_init(&sync->lock, NULL); + toku_cond_init(&sync->cv, NULL); +#endif +} + +static void test_sync_destroy(struct test_sync *UU(sync)) { +#if TOKU_DEBUG_TXN_SYNC + toku_mutex_destroy(&sync->lock); + toku_cond_destroy(&sync->cv); +#endif +} + +static void test_sync_sleep(struct test_sync *UU(sync), int UU(new_state)) { +#if TOKU_DEBUG_TXN_SYNC + toku_mutex_lock(&sync->lock); + while (sync->state != new_state) { + toku_cond_wait(&sync->cv, &sync->lock); + } + toku_mutex_unlock(&sync->lock); +#endif +} + +static void test_sync_next_state(struct test_sync *UU(sync)) { +#if TOKU_DEBUG_TXN_SYNC + toku_mutex_lock(&sync->lock); + sync->state++; + toku_cond_broadcast(&sync->cv); + toku_mutex_unlock(&sync->lock); +#endif +} + + +struct start_txn_arg { + DB_ENV *env; + DB *db; + DB_TXN * parent; +}; + +static struct test_sync sync_s; + +static void test_callback(uint64_t self_tid, void * extra) { + pthread_t **p = (pthread_t **) extra; + pthread_t tid_1 = *p[0]; + pthread_t tid_2 = *p[1]; + assert(self_tid == tid_2); + printf("%s: the thread[%" PRIu64 "] is going to wait...\n", __func__, tid_1); + test_sync_next_state(&sync_s); + sleep(3); + //test_sync_sleep(&sync_s,3); + //using test_sync_sleep/test_sync_next_state pair can sync threads better, however + //after the fix, this might cause a deadlock. just simply use sleep to do a proof- + //of-concept test. + printf("%s: the thread[%" PRIu64 "] is resuming...\n", __func__, tid_1); + return; +} + +static void * start_txn2(void * extra) { + struct start_txn_arg * args = (struct start_txn_arg *) extra; + DB_ENV * env = args -> env; + DB * db = args->db; + DB_TXN * parent = args->parent; + test_sync_sleep(&sync_s, 1); + printf("start %s [thread %" PRIu64 "]\n", __func__, pthread_self()); + DB_TXN *txn; + int r = env->txn_begin(env, parent, &txn, DB_READ_COMMITTED); + assert(r == 0); + //do some random things... + DBT key, data; + dbt_init(&key, "hello", 6); + dbt_init(&data, "world", 6); + db->put(db, txn, &key, &data, 0); + db->get(db, txn, &key, &data, 0); + + r = txn->commit(txn, 0); + assert(r == 0); + printf("%s done[thread %" PRIu64 "]\n", __func__, pthread_self()); + return extra; +} + +static void * start_txn1(void * extra) { + struct start_txn_arg * args = (struct start_txn_arg *) extra; + DB_ENV * env = args -> env; + DB * db = args->db; + printf("start %s: [thread %" PRIu64 "]\n", __func__, pthread_self()); + DB_TXN *txn; + int r = env->txn_begin(env, NULL, &txn, DB_READ_COMMITTED); + assert(r == 0); + printf("%s: txn began by [thread %" PRIu64 "], will wait\n", __func__, pthread_self()); + test_sync_next_state(&sync_s); + test_sync_sleep(&sync_s,2); + printf("%s: [thread %" PRIu64 "] resumed\n", __func__, pthread_self()); + //do some random things... + DBT key, data; + dbt_init(&key, "hello", 6); + dbt_init(&data, "world", 6); + db->put(db, txn, &key, &data, 0); + db->get(db, txn, &key, &data, 0); + r = txn->commit(txn, 0); + assert(r == 0); + printf("%s: done[thread %" PRIu64 "]\n", __func__, pthread_self()); + //test_sync_next_state(&sync_s); + return extra; +} + +int test_main (int UU(argc), char * const UU(argv[])) { + int r; + toku_os_recursive_delete(TOKU_TEST_FILENAME); + r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO); + assert(r == 0); + + DB_ENV *env; + r = db_env_create(&env, 0); + assert(r == 0); + + r = env->open(env, TOKU_TEST_FILENAME, DB_INIT_MPOOL|DB_CREATE|DB_THREAD |DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_PRIVATE, S_IRWXU+S_IRWXG+S_IRWXO); + assert(r == 0); + + DB *db = NULL; + r = db_create(&db, env, 0); + assert(r == 0); + + r = db->open(db, NULL, "testit", NULL, DB_BTREE, DB_AUTO_COMMIT+DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); + assert(r == 0); + + DB_TXN * parent = NULL; + r = env->txn_begin(env, 0, &parent, DB_READ_COMMITTED); + assert(r == 0); + + ZERO_STRUCT(sync_s); + test_sync_init(&sync_s); + + pthread_t tid_1 = 0; + pthread_t tid_2 = 0; + pthread_t* callback_extra[2] = {&tid_1, &tid_2}; + toku_set_test_txn_sync_callback(test_callback, callback_extra); + + struct start_txn_arg args = {env, db, parent}; + + r = pthread_create(&tid_1, NULL, start_txn1, &args); + assert(r==0); + + r= pthread_create(&tid_2, NULL, start_txn2, &args); + assert(r==0); + + void * ret; + r = pthread_join(tid_1, &ret); + assert(r == 0); + r = pthread_join(tid_2, &ret); + assert(r == 0); + + r = parent->commit(parent, 0); + assert(r ==0); + + test_sync_destroy(&sync_s); + r = db->close(db, 0); + assert(r == 0); + + r = env->close(env, 0); + assert(r == 0); + + return 0; +} + diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc index 88c6c86f214d7..61ce5a8476e85 100644 --- a/storage/tokudb/PerconaFT/src/ydb.cc +++ b/storage/tokudb/PerconaFT/src/ydb.cc @@ -3148,6 +3148,10 @@ toku_test_get_latest_lsn(DB_ENV *env) { return rval.lsn; } +void toku_set_test_txn_sync_callback(void (* cb) (uint64_t, void *), void * extra) { + set_test_txn_sync_callback(cb, extra); +} + int toku_test_get_checkpointing_user_data_status (void) { return toku_cachetable_get_checkpointing_user_data_status(); diff --git a/storage/tokudb/PerconaFT/src/ydb.h b/storage/tokudb/PerconaFT/src/ydb.h index 9d4e94c6f309d..bd2902e6c6e58 100644 --- a/storage/tokudb/PerconaFT/src/ydb.h +++ b/storage/tokudb/PerconaFT/src/ydb.h @@ -58,3 +58,6 @@ extern "C" uint64_t toku_test_get_latest_lsn(DB_ENV *env) __attribute__((__visib // test-only function extern "C" int toku_test_get_checkpointing_user_data_status(void) __attribute__((__visibility__("default"))); + +// test-only function +extern "C" void toku_set_test_txn_sync_callback(void (* ) (uint64_t, void *), void * extra) __attribute__((__visibility__("default"))); diff --git a/storage/tokudb/PerconaFT/src/ydb_db.cc b/storage/tokudb/PerconaFT/src/ydb_db.cc index 25b2446768497..e5bd4e7d089d5 100644 --- a/storage/tokudb/PerconaFT/src/ydb_db.cc +++ b/storage/tokudb/PerconaFT/src/ydb_db.cc @@ -1015,6 +1015,25 @@ toku_db_verify_with_progress(DB *db, int (*progress_callback)(void *extra, float return r; } + +static int +toku_db_recount_rows(DB* db, int (*progress_callback)(uint64_t count, + uint64_t deleted, + void* progress_extra), + void* progress_extra) { + + HANDLE_PANICKED_DB(db); + int r = 0; + r = + toku_ft_recount_rows( + db->i->ft_handle, + progress_callback, + progress_extra); + + return r; +} + + int toku_setup_db_internal (DB **dbp, DB_ENV *env, uint32_t flags, FT_HANDLE ft_handle, bool is_open) { if (flags || env == NULL) return EINVAL; @@ -1098,6 +1117,7 @@ toku_db_create(DB ** db, DB_ENV * env, uint32_t flags) { USDB(dbt_pos_infty); USDB(dbt_neg_infty); USDB(get_fragmentation); + USDB(recount_rows); #undef USDB result->get_indexer = db_get_indexer; result->del = autotxn_db_del; diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt index 6d17210eeb07d..d3808483fea60 100644 --- a/storage/tokudb/PerconaFT/tools/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/tools/CMakeLists.txt @@ -2,7 +2,7 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE DONT_DEPR set(tools tokudb_dump tokuftdump tokuft_logprint tdb-recover ftverify ba_replay) foreach(tool ${tools}) - add_executable(${tool} ${tool}) + add_executable(${tool} ${tool}.cc) add_dependencies(${tool} install_tdb_h) target_link_libraries(${tool} ${LIBTOKUDB}_static ft_static z lzma snappy ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} ${EXTRA_SYSTEM_LIBS}) diff --git a/storage/tokudb/PerconaFT/util/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/util/tests/CMakeLists.txt index f3768c4195635..8d53dd89a273b 100644 --- a/storage/tokudb/PerconaFT/util/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/util/tests/CMakeLists.txt @@ -6,7 +6,7 @@ if(BUILD_TESTING) endforeach(src) foreach(test ${tests}) - add_executable(${test} ${test}) + add_executable(${test} ${test}.cc) target_link_libraries(${test} util ${LIBTOKUPORTABILITY}) endforeach(test) diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 5e8c3819afff5..3979b360d8f2d 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -23,60 +23,18 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." -#ifdef USE_PRAGMA_IMPLEMENTATION -#pragma implementation // gcc: Class implementation -#endif - -#include -extern "C" { -#include "stdint.h" -#define __STDC_FORMAT_MACROS -#include "inttypes.h" -#if defined(_WIN32) -#include "misc.h" -#endif -} - -#define MYSQL_SERVER 1 -#include "mysql_version.h" -#include "sql_table.h" -#include "handler.h" -#include "table.h" -#include "log.h" -#include "sql_class.h" -#include "sql_show.h" -#include "discover.h" - -#if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) -#include -#endif - -#include "db.h" -#include "toku_os.h" -#include "hatoku_defines.h" +#include "hatoku_hton.h" #include "hatoku_cmp.h" - -static inline uint get_key_parts(const KEY *key); - -#undef PACKAGE -#undef VERSION -#undef HAVE_DTRACE -#undef _DTRACE_VERSION - -/* We define DTRACE after mysql_priv.h in case it disabled dtrace in the main server */ -#ifdef HAVE_DTRACE -#define _DTRACE_VERSION 1 -#else -#endif - #include "tokudb_buffer.h" #include "tokudb_status.h" #include "tokudb_card.h" #include "ha_tokudb.h" -#include "hatoku_hton.h" -#include -static const char *ha_tokudb_exts[] = { + +HASH TOKUDB_SHARE::_open_tables; +tokudb::thread::mutex_t TOKUDB_SHARE::_open_tables_mutex; + +static const char* ha_tokudb_exts[] = { ha_tokudb_ext, NullS }; @@ -84,10 +42,15 @@ static const char *ha_tokudb_exts[] = { // // This offset is calculated starting from AFTER the NULL bytes // -static inline uint32_t get_fixed_field_size(KEY_AND_COL_INFO* kc_info, TABLE_SHARE* table_share, uint keynr) { +static inline uint32_t get_fixed_field_size( + KEY_AND_COL_INFO* kc_info, + TABLE_SHARE* table_share, + uint keynr) { + uint offset = 0; for (uint i = 0; i < table_share->fields; i++) { - if (is_fixed_field(kc_info, i) && !bitmap_is_set(&kc_info->key_filters[keynr],i)) { + if (is_fixed_field(kc_info, i) && + !bitmap_is_set(&kc_info->key_filters[keynr], i)) { offset += kc_info->field_lengths[i]; } } @@ -95,10 +58,15 @@ static inline uint32_t get_fixed_field_size(KEY_AND_COL_INFO* kc_info, TABLE_SHA } -static inline uint32_t get_len_of_offsets(KEY_AND_COL_INFO* kc_info, TABLE_SHARE* table_share, uint keynr) { +static inline uint32_t get_len_of_offsets( + KEY_AND_COL_INFO* kc_info, + TABLE_SHARE* table_share, + uint keynr) { + uint len = 0; for (uint i = 0; i < table_share->fields; i++) { - if (is_variable_field(kc_info, i) && !bitmap_is_set(&kc_info->key_filters[keynr],i)) { + if (is_variable_field(kc_info, i) && + !bitmap_is_set(&kc_info->key_filters[keynr], i)) { len += kc_info->num_offset_bytes; } } @@ -106,32 +74,36 @@ static inline uint32_t get_len_of_offsets(KEY_AND_COL_INFO* kc_info, TABLE_SHARE } -static int allocate_key_and_col_info ( TABLE_SHARE* table_share, KEY_AND_COL_INFO* kc_info) { +static int allocate_key_and_col_info( + TABLE_SHARE* table_share, + KEY_AND_COL_INFO* kc_info) { + int error; // // initialize all of the bitmaps // for (uint i = 0; i < MAX_KEY + 1; i++) { - error = bitmap_init( - &kc_info->key_filters[i], - NULL, - table_share->fields, - false - ); + error = + bitmap_init( + &kc_info->key_filters[i], + NULL, + table_share->fields, + false); if (error) { goto exit; } } - + // // create the field lengths // - kc_info->multi_ptr = tokudb_my_multi_malloc(MYF(MY_WME+MY_ZEROFILL), - &kc_info->field_types, (uint)(table_share->fields * sizeof (uint8_t)), - &kc_info->field_lengths, (uint)(table_share->fields * sizeof (uint16_t)), - &kc_info->length_bytes, (uint)(table_share->fields * sizeof (uint8_t)), - &kc_info->blob_fields, (uint)(table_share->fields * sizeof (uint32_t)), - NullS); + kc_info->multi_ptr = tokudb::memory::multi_malloc( + MYF(MY_WME+MY_ZEROFILL), + &kc_info->field_types, (uint)(table_share->fields * sizeof (uint8_t)), + &kc_info->field_lengths, (uint)(table_share->fields * sizeof (uint16_t)), + &kc_info->length_bytes, (uint)(table_share->fields * sizeof (uint8_t)), + &kc_info->blob_fields, (uint)(table_share->fields * sizeof (uint32_t)), + NullS); if (kc_info->multi_ptr == NULL) { error = ENOMEM; goto exit; @@ -141,7 +113,7 @@ static int allocate_key_and_col_info ( TABLE_SHARE* table_share, KEY_AND_COL_INF for (uint i = 0; MAX_KEY + 1; i++) { bitmap_free(&kc_info->key_filters[i]); } - tokudb_my_free(kc_info->multi_ptr); + tokudb::memory::free(kc_info->multi_ptr); } return error; } @@ -150,136 +122,263 @@ static void free_key_and_col_info (KEY_AND_COL_INFO* kc_info) { for (uint i = 0; i < MAX_KEY+1; i++) { bitmap_free(&kc_info->key_filters[i]); } - + for (uint i = 0; i < MAX_KEY+1; i++) { - tokudb_my_free(kc_info->cp_info[i]); + tokudb::memory::free(kc_info->cp_info[i]); kc_info->cp_info[i] = NULL; // 3144 } - tokudb_my_free(kc_info->multi_ptr); + tokudb::memory::free(kc_info->multi_ptr); kc_info->field_types = NULL; kc_info->field_lengths = NULL; kc_info->length_bytes = NULL; kc_info->blob_fields = NULL; } -void TOKUDB_SHARE::init(void) { - use_count = 0; - thr_lock_init(&lock); - tokudb_pthread_mutex_init(&mutex, MY_MUTEX_INIT_FAST); - my_rwlock_init(&num_DBs_lock, 0); - tokudb_pthread_cond_init(&m_openclose_cond, NULL); - m_state = CLOSED; -} -void TOKUDB_SHARE::destroy(void) { - assert(m_state == CLOSED); - thr_lock_delete(&lock); - tokudb_pthread_mutex_destroy(&mutex); - rwlock_destroy(&num_DBs_lock); - tokudb_pthread_cond_destroy(&m_openclose_cond); - tokudb_my_free(rec_per_key); - rec_per_key = NULL; -} +uchar* TOKUDB_SHARE::hash_get_key( + TOKUDB_SHARE* share, + size_t* length, + TOKUDB_UNUSED(my_bool not_used)) { -// MUST have tokudb_mutex locked on input -static TOKUDB_SHARE *get_share(const char *table_name, TABLE_SHARE* table_share) { - TOKUDB_SHARE *share = NULL; + *length = share->_full_table_name.length(); + return (uchar *) share->_full_table_name.c_ptr(); +} +void TOKUDB_SHARE::hash_free_element(TOKUDB_SHARE* share) { + share->destroy(); + delete share; +} +void TOKUDB_SHARE::static_init() { + my_hash_init( + &_open_tables, + table_alias_charset, + 32, + 0, + 0, + (my_hash_get_key)hash_get_key, + (my_hash_free_key)hash_free_element, 0); +} +void TOKUDB_SHARE::static_destroy() { + my_hash_free(&_open_tables); +} +void* TOKUDB_SHARE::operator new(size_t sz) { + return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE)); +} +void TOKUDB_SHARE::operator delete(void* p) { + tokudb::memory::free(p); +} +TOKUDB_SHARE::TOKUDB_SHARE() : + _num_DBs_lock(), + _mutex() { +} +void TOKUDB_SHARE::init(const char* table_name) { + _use_count = 0; + thr_lock_init(&_thr_lock); + _state = CLOSED; + _row_delta_activity = 0; + _allow_auto_analysis = true; + + _full_table_name.append(table_name); + + String tmp_dictionary_name; + tokudb_split_dname( + table_name, + _database_name, + _table_name, + tmp_dictionary_name); +} +void TOKUDB_SHARE::destroy() { + assert_always(_use_count == 0); + assert_always( + _state == TOKUDB_SHARE::CLOSED || _state == TOKUDB_SHARE::ERROR); + thr_lock_delete(&_thr_lock); +} +TOKUDB_SHARE* TOKUDB_SHARE::get_share( + const char* table_name, + TABLE_SHARE* table_share, + THR_LOCK_DATA* data, + bool create_new) { + + _open_tables_mutex.lock(); int error = 0; uint length = (uint) strlen(table_name); - if (!(share = (TOKUDB_SHARE *) my_hash_search(&tokudb_open_tables, (uchar *) table_name, length))) { - char *tmp_name; - + TOKUDB_SHARE* share = + (TOKUDB_SHARE*)my_hash_search( + &_open_tables, + (uchar*)table_name, + length); + if (!share) { + if (create_new == false) + goto exit; // create share and fill it with all zeroes // hence, all pointers are initialized to NULL - share = (TOKUDB_SHARE *) tokudb_my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), - &share, sizeof(*share), - &tmp_name, length + 1, - NullS - ); - assert(share); - - share->init(); + share = new TOKUDB_SHARE; + assert_always(share); - share->table_name_length = length; - share->table_name = tmp_name; - strmov(share->table_name, table_name); + share->init(table_name); - error = my_hash_insert(&tokudb_open_tables, (uchar *) share); + error = my_hash_insert(&_open_tables, (uchar*)share); if (error) { free_key_and_col_info(&share->kc_info); + share->destroy(); + tokudb::memory::free((uchar*)share); + share = NULL; goto exit; } } + share->addref(); + + if (data) + thr_lock_data_init(&(share->_thr_lock), data, NULL); + exit: - if (error) { - share->destroy(); - tokudb_my_free((uchar *) share); - share = NULL; - } + _open_tables_mutex.unlock(); return share; } +void TOKUDB_SHARE::drop_share(TOKUDB_SHARE* share) { + _open_tables_mutex.lock(); + my_hash_delete(&_open_tables, (uchar*)share); + _open_tables_mutex.unlock(); +} +TOKUDB_SHARE::share_state_t TOKUDB_SHARE::addref() { + lock(); + _use_count++; -static int free_share(TOKUDB_SHARE * share) { - int error, result = 0; + DBUG_PRINT("info", ("0x%p share->_use_count %u", this, _use_count)); - tokudb_pthread_mutex_lock(&share->mutex); - DBUG_PRINT("info", ("share->use_count %u", share->use_count)); - if (!--share->use_count) { - share->m_state = TOKUDB_SHARE::CLOSING; - tokudb_pthread_mutex_unlock(&share->mutex); + return _state; +} +int TOKUDB_SHARE::release() { + int error, result = 0; - // - // number of open DB's may not be equal to number of keys we have because add_index - // may have added some. So, we loop through entire array and close any non-NULL value - // It is imperative that we reset a DB to NULL once we are done with it. - // - for (uint i = 0; i < sizeof(share->key_file)/sizeof(share->key_file[0]); i++) { - if (share->key_file[i]) { - if (tokudb_debug & TOKUDB_DEBUG_OPEN) { - TOKUDB_TRACE("dbclose:%p", share->key_file[i]); - } - error = share->key_file[i]->close(share->key_file[i], 0); - assert(error == 0); + _mutex.lock(); + assert_always(_use_count != 0); + _use_count--; + DBUG_PRINT("info", ("0x%p share->_use_count %u", this, _use_count)); + if (_use_count == 0 && _state == TOKUDB_SHARE::OPENED) { + // number of open DB's may not be equal to number of keys we have + // because add_index may have added some. So, we loop through entire + // array and close any non-NULL value. It is imperative that we reset + // a DB to NULL once we are done with it. + for (uint i = 0; i < sizeof(key_file)/sizeof(key_file[0]); i++) { + if (key_file[i]) { + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_OPEN, + "dbclose:%p", + key_file[i]); + error = key_file[i]->close(key_file[i], 0); + assert_always(error == 0); if (error) { result = error; } - if (share->key_file[i] == share->file) - share->file = NULL; - share->key_file[i] = NULL; + if (key_file[i] == file) + file = NULL; + key_file[i] = NULL; } } - error = tokudb::close_status(&share->status_block); - assert(error == 0); + error = tokudb::metadata::close(&status_block); + assert_always(error == 0); - free_key_and_col_info(&share->kc_info); - - tokudb_pthread_mutex_lock(&tokudb_mutex); - tokudb_pthread_mutex_lock(&share->mutex); - share->m_state = TOKUDB_SHARE::CLOSED; - if (share->use_count > 0) { - tokudb_pthread_cond_broadcast(&share->m_openclose_cond); - tokudb_pthread_mutex_unlock(&share->mutex); - tokudb_pthread_mutex_unlock(&tokudb_mutex); - } else { + free_key_and_col_info(&kc_info); - my_hash_delete(&tokudb_open_tables, (uchar *) share); - - tokudb_pthread_mutex_unlock(&share->mutex); - tokudb_pthread_mutex_unlock(&tokudb_mutex); + if (_rec_per_key) { + tokudb::memory::free(_rec_per_key); + _rec_per_key = NULL; + _rec_per_keys = 0; + } - share->destroy(); - tokudb_my_free((uchar *) share); + for (uint i = 0; i < _keys; i++) { + tokudb::memory::free(_key_descriptors[i]._name); } - } else { - tokudb_pthread_mutex_unlock(&share->mutex); + tokudb::memory::free(_key_descriptors); + _keys = _max_key_parts = 0; _key_descriptors = NULL; + + _state = TOKUDB_SHARE::CLOSED; } + _mutex.unlock(); return result; } +void TOKUDB_SHARE::update_row_count( + THD* thd, + uint64_t added, + uint64_t deleted, + uint64_t updated) { + + uint64_t delta = added + deleted + updated; + lock(); + if (deleted > added && _rows < (deleted - added)) { + _rows = 0; + } else { + _rows += added - deleted; + } + _row_delta_activity += delta; + if (_row_delta_activity == (uint64_t)~0) + _row_delta_activity = 1; + + ulonglong auto_threshold = tokudb::sysvars::auto_analyze(thd); + if (delta && auto_threshold > 0 && _allow_auto_analysis) { + ulonglong pct_of_rows_changed_to_trigger; + pct_of_rows_changed_to_trigger = ((_rows * auto_threshold) / 100); + if (_row_delta_activity >= pct_of_rows_changed_to_trigger) { + char msg[200]; + snprintf( + msg, + sizeof(msg), + "TokuDB: Auto %s background analysis for %s, delta_activity " + "%llu is greater than %llu percent of %llu rows.", + tokudb::sysvars::analyze_in_background(thd) > 0 ? + "scheduling" : "running", + full_table_name(), + _row_delta_activity, + auto_threshold, + (ulonglong)(_rows)); + + // analyze_standard will unlock _mutex regardless of success/failure + int ret = analyze_standard(thd, NULL); + if (ret == 0) { + sql_print_information("%s - succeeded.", msg); + } else { + sql_print_information( + "%s - failed, likely a job already running.", + msg); + } + } + } + unlock(); +} +void TOKUDB_SHARE::set_cardinality_counts_in_table(TABLE* table) { + // if there is nothing new to report, just skip it. + if (_card_changed) { + lock(); + uint32_t next_key_part = 0; + for (uint32_t i = 0; i < table->s->keys; i++) { + bool is_unique_key = + (i == table->s->primary_key) || + (table->key_info[i].flags & HA_NOSAME); + + uint32_t num_key_parts = get_key_parts(&table->key_info[i]); + for (uint32_t j = 0; j < num_key_parts; j++) { + assert_always(next_key_part < _rec_per_keys); + ulong val = _rec_per_key[next_key_part++]; + if (is_unique_key && j == num_key_parts-1) { + val = 1; + } else { + val = + (val*tokudb::sysvars::cardinality_scale_percent)/100; + if (val == 0) + val = 1; + } + table->key_info[i].rec_per_key[j] = val; + } + } + _card_changed = false; + unlock(); + } +} #define HANDLE_INVALID_CURSOR() \ if (cursor == NULL) { \ @@ -288,7 +387,6 @@ static int free_share(TOKUDB_SHARE * share) { } const char *ha_tokudb::table_type() const { - extern const char * const tokudb_hton_name; return tokudb_hton_name; } @@ -296,7 +394,7 @@ const char *ha_tokudb::index_type(uint inx) { return "BTREE"; } -/* +/* * returns NULL terminated file extension string */ const char **ha_tokudb::bas_ext() const { @@ -315,13 +413,19 @@ static inline bool is_replace_into(THD* thd) { return thd->lex->duplicates == DUP_REPLACE; } -static inline bool do_ignore_flag_optimization(THD* thd, TABLE* table, bool opt_eligible) { +static inline bool do_ignore_flag_optimization( + THD* thd, + TABLE* table, + bool opt_eligible) { + bool do_opt = false; if (opt_eligible) { if (is_replace_into(thd) || is_insert_ignore(thd)) { - uint pk_insert_mode = get_pk_insert_mode(thd); - if ((!table->triggers && pk_insert_mode < 2) || pk_insert_mode == 0) { - if (mysql_bin_log.is_open() && thd->variables.binlog_format != BINLOG_FORMAT_STMT) { + uint pk_insert_mode = tokudb::sysvars::pk_insert_mode(thd); + if ((!table->triggers && pk_insert_mode < 2) || + pk_insert_mode == 0) { + if (mysql_bin_log.is_open() && + thd->variables.binlog_format != BINLOG_FORMAT_STMT) { do_opt = false; } else { do_opt = true; @@ -332,16 +436,6 @@ static inline bool do_ignore_flag_optimization(THD* thd, TABLE* table, bool opt_ return do_opt; } -static inline uint get_key_parts(const KEY *key) { -#if (50609 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ - (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100009 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099) - return key->user_defined_key_parts; -#else - return key->key_parts; -#endif -} - #if TOKU_INCLUDE_EXTENDED_KEYS static inline uint get_ext_key_parts(const KEY *key) { #if (50609 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ @@ -365,8 +459,9 @@ ulonglong ha_tokudb::table_flags() const { // ulong ha_tokudb::index_flags(uint idx, uint part, bool all_parts) const { TOKUDB_HANDLER_DBUG_ENTER(""); - assert(table_share); - ulong flags = (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEYREAD_ONLY | HA_READ_RANGE); + assert_always(table_share); + ulong flags = (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | + HA_KEYREAD_ONLY | HA_READ_RANGE); #if defined(MARIADB_BASE_VERSION) || (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) flags |= HA_DO_INDEX_COND_PUSHDOWN; #endif @@ -434,13 +529,13 @@ static int loader_poll_fun(void *extra, float progress) { static void loader_ai_err_fun(DB *db, int i, int err, DBT *key, DBT *val, void *error_extra) { LOADER_CONTEXT context = (LOADER_CONTEXT)error_extra; - assert(context->ha); + assert_always(context->ha); context->ha->set_loader_error(err); } static void loader_dup_fun(DB *db, int i, int err, DBT *key, DBT *val, void *error_extra) { LOADER_CONTEXT context = (LOADER_CONTEXT)error_extra; - assert(context->ha); + assert_always(context->ha); context->ha->set_loader_error(err); if (err == DB_KEYEXIST) { context->ha->set_dup_value_for_pk(key); @@ -620,8 +715,7 @@ static ulonglong retrieve_auto_increment(uint16 type, uint32 offset,const uchar break; default: - DBUG_ASSERT(0); - unsigned_autoinc = 0; + assert_unreachable(); } if (signed_autoinc < 0) { @@ -632,21 +726,6 @@ static ulonglong retrieve_auto_increment(uint16 type, uint32 offset,const uchar unsigned_autoinc : (ulonglong) signed_autoinc; } -static inline bool -is_null_field( TABLE* table, Field* field, const uchar* record) { - uint null_offset; - bool ret_val; - if (!field->real_maybe_null()) { - ret_val = false; - goto exitpt; - } - null_offset = get_null_offset(table,field); - ret_val = (record[null_offset] & field->null_bit) ? true: false; - -exitpt: - return ret_val; -} - static inline ulong field_offset(Field* field, TABLE* table) { return((ulong) (field->ptr - table->record[0])); } @@ -830,7 +909,7 @@ static inline uchar* write_var_field( int2store(to_tokudb_offset_ptr,offset); break; default: - assert(false); + assert_unreachable(); break; } return to_tokudb_data + data_length; @@ -850,8 +929,7 @@ static inline uint32_t get_var_data_length( data_length = uint2korr(from_mysql); break; default: - assert(false); - break; + assert_unreachable(); } return data_length; } @@ -894,8 +972,7 @@ static inline void unpack_var_field( int2store(to_mysql, from_tokudb_data_len); break; default: - assert(false); - break; + assert_unreachable(); } // // store the data @@ -928,7 +1005,7 @@ static uchar* pack_toku_field_blob( length = uint4korr(from_mysql); break; default: - assert(false); + assert_unreachable(); } if (length > 0) { @@ -940,7 +1017,9 @@ static uchar* pack_toku_field_blob( static int create_tokudb_trx_data_instance(tokudb_trx_data** out_trx) { int error; - tokudb_trx_data* trx = (tokudb_trx_data *) tokudb_my_malloc(sizeof(*trx), MYF(MY_ZEROFILL)); + tokudb_trx_data* trx = (tokudb_trx_data *) tokudb::memory::malloc( + sizeof(*trx), + MYF(MY_ZEROFILL)); if (!trx) { error = ENOMEM; goto cleanup; @@ -1011,32 +1090,27 @@ static inline int tokudb_generate_row( void* old_ptr = dest_key->data; void* new_ptr = NULL; new_ptr = realloc(old_ptr, max_key_len); - assert(new_ptr); + assert_always(new_ptr); dest_key->data = new_ptr; dest_key->ulen = max_key_len; } buff = (uchar *)dest_key->data; - assert(buff != NULL && max_key_len > 0); - } - else { - assert(false); + assert_always(buff != NULL && max_key_len > 0); + } else { + assert_unreachable(); } - dest_key->size = pack_key_from_desc( - buff, - row_desc, - desc_size, - src_key, - src_val - ); - assert(dest_key->ulen >= dest_key->size); - if (tokudb_debug & TOKUDB_DEBUG_CHECK_KEY && !max_key_len) { + dest_key->size = pack_key_from_desc(buff, row_desc, desc_size, src_key, + src_val); + assert_always(dest_key->ulen >= dest_key->size); + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_CHECK_KEY)) && + !max_key_len) { max_key_len = max_key_size_from_desc(row_desc, desc_size); max_key_len += src_key->size; } if (max_key_len) { - assert(max_key_len >= dest_key->size); + assert_always(max_key_len >= dest_key->size); } row_desc += desc_size; @@ -1045,8 +1119,7 @@ static inline int tokudb_generate_row( if (dest_val != NULL) { if (!is_key_clustering(row_desc, desc_size) || src_val->size == 0) { dest_val->size = 0; - } - else { + } else { uchar* buff = NULL; if (dest_val->flags == 0) { dest_val->ulen = 0; @@ -1059,23 +1132,21 @@ static inline int tokudb_generate_row( void* old_ptr = dest_val->data; void* new_ptr = NULL; new_ptr = realloc(old_ptr, src_val->size); - assert(new_ptr); + assert_always(new_ptr); dest_val->data = new_ptr; dest_val->ulen = src_val->size; } buff = (uchar *)dest_val->data; - assert(buff != NULL); - } - else { - assert(false); + assert_always(buff != NULL); + } else { + assert_unreachable(); } dest_val->size = pack_clustering_val_from_desc( buff, row_desc, desc_size, - src_val - ); - assert(dest_val->ulen >= dest_val->size); + src_val); + assert_always(dest_val->ulen >= dest_val->size); } } error = 0; @@ -1143,6 +1214,7 @@ ha_tokudb::ha_tokudb(handlerton * hton, TABLE_SHARE * table_arg):handler(hton, t read_key = false; added_rows = 0; deleted_rows = 0; + updated_rows = 0; last_dup_key = UINT_MAX; using_ignore = false; using_ignore_no_key = false; @@ -1224,41 +1296,42 @@ bool ha_tokudb::has_auto_increment_flag(uint* index) { static int open_status_dictionary(DB** ptr, const char* name, DB_TXN* txn) { int error; char* newname = NULL; - newname = (char *)tokudb_my_malloc( - get_max_dict_name_path_length(name), - MYF(MY_WME)); + size_t newname_len = get_max_dict_name_path_length(name); + newname = (char*)tokudb::memory::malloc(newname_len, MYF(MY_WME)); if (newname == NULL) { error = ENOMEM; goto cleanup; } - make_name(newname, name, "status"); - if (tokudb_debug & TOKUDB_DEBUG_OPEN) { - TOKUDB_TRACE("open:%s", newname); - } + make_name(newname, newname_len, name, "status"); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_OPEN, "open:%s", newname); - error = tokudb::open_status(db_env, ptr, newname, txn); + error = tokudb::metadata::open(db_env, ptr, newname, txn); cleanup: - tokudb_my_free(newname); + tokudb::memory::free(newname); return error; } -int ha_tokudb::open_main_dictionary(const char* name, bool is_read_only, DB_TXN* txn) { +int ha_tokudb::open_main_dictionary( + const char* name, + bool is_read_only, + DB_TXN* txn) { + int error; char* newname = NULL; + size_t newname_len = 0; uint open_flags = (is_read_only ? DB_RDONLY : 0) | DB_THREAD; - assert(share->file == NULL); - assert(share->key_file[primary_key] == NULL); - - newname = (char *)tokudb_my_malloc( - get_max_dict_name_path_length(name), - MYF(MY_WME|MY_ZEROFILL) - ); + assert_always(share->file == NULL); + assert_always(share->key_file[primary_key] == NULL); + newname_len = get_max_dict_name_path_length(name); + newname = (char*)tokudb::memory::malloc( + newname_len, + MYF(MY_WME|MY_ZEROFILL)); if (newname == NULL) { error = ENOMEM; goto exit; } - make_name(newname, name, "main"); + make_name(newname, newname_len, name, "main"); error = db_create(&share->file, db_env, 0); if (error) { @@ -1266,14 +1339,24 @@ int ha_tokudb::open_main_dictionary(const char* name, bool is_read_only, DB_TXN* } share->key_file[primary_key] = share->file; - error = share->file->open(share->file, txn, newname, NULL, DB_BTREE, open_flags, 0); + error = + share->file->open( + share->file, + txn, + newname, + NULL, + DB_BTREE, + open_flags, + 0); if (error) { goto exit; } - - if (tokudb_debug & TOKUDB_DEBUG_OPEN) { - TOKUDB_HANDLER_TRACE("open:%s:file=%p", newname, share->file); - } + + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_OPEN, + "open:%s:file=%p", + newname, + share->file); error = 0; exit: @@ -1283,34 +1366,42 @@ int ha_tokudb::open_main_dictionary(const char* name, bool is_read_only, DB_TXN* share->file, 0 ); - assert(r==0); + assert_always(r==0); share->file = NULL; share->key_file[primary_key] = NULL; } } - tokudb_my_free(newname); + tokudb::memory::free(newname); return error; } // -// Open a secondary table, the key will be a secondary index, the data will be a primary key +// Open a secondary table, the key will be a secondary index, the data will +// be a primary key // -int ha_tokudb::open_secondary_dictionary(DB** ptr, KEY* key_info, const char* name, bool is_read_only, DB_TXN* txn) { +int ha_tokudb::open_secondary_dictionary( + DB** ptr, + KEY* key_info, + const char* name, + bool is_read_only, + DB_TXN* txn) { + int error = ENOSYS; char dict_name[MAX_DICT_NAME_LEN]; uint open_flags = (is_read_only ? DB_RDONLY : 0) | DB_THREAD; char* newname = NULL; - uint newname_len = 0; - + size_t newname_len = 0; + sprintf(dict_name, "key-%s", key_info->name); newname_len = get_max_dict_name_path_length(name); - newname = (char *)tokudb_my_malloc(newname_len, MYF(MY_WME|MY_ZEROFILL)); + newname = + (char*)tokudb::memory::malloc(newname_len, MYF(MY_WME|MY_ZEROFILL)); if (newname == NULL) { error = ENOMEM; goto cleanup; } - make_name(newname, name, dict_name); + make_name(newname, newname_len, name, dict_name); if ((error = db_create(ptr, db_env, 0))) { @@ -1319,22 +1410,25 @@ int ha_tokudb::open_secondary_dictionary(DB** ptr, KEY* key_info, const char* na } - if ((error = (*ptr)->open(*ptr, txn, newname, NULL, DB_BTREE, open_flags, 0))) { + error = (*ptr)->open(*ptr, txn, newname, NULL, DB_BTREE, open_flags, 0); + if (error) { my_errno = error; goto cleanup; } - if (tokudb_debug & TOKUDB_DEBUG_OPEN) { - TOKUDB_HANDLER_TRACE("open:%s:file=%p", newname, *ptr); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_OPEN, + "open:%s:file=%p", + newname, + *ptr); cleanup: if (error) { if (*ptr) { int r = (*ptr)->close(*ptr, 0); - assert(r==0); + assert_always(r==0); *ptr = NULL; } } - tokudb_my_free(newname); + tokudb::memory::free(newname); return error; } @@ -1343,11 +1437,10 @@ static int initialize_col_pack_info(KEY_AND_COL_INFO* kc_info, TABLE_SHARE* tabl // // set up the cp_info // - assert(kc_info->cp_info[keynr] == NULL); - kc_info->cp_info[keynr] = (COL_PACK_INFO *)tokudb_my_malloc( - table_share->fields*sizeof(COL_PACK_INFO), - MYF(MY_WME | MY_ZEROFILL) - ); + assert_always(kc_info->cp_info[keynr] == NULL); + kc_info->cp_info[keynr] = (COL_PACK_INFO*)tokudb::memory::malloc( + table_share->fields * sizeof(COL_PACK_INFO), + MYF(MY_WME | MY_ZEROFILL)); if (kc_info->cp_info[keynr] == NULL) { error = ENOMEM; goto exit; @@ -1396,12 +1489,18 @@ static int initialize_col_pack_info(KEY_AND_COL_INFO* kc_info, TABLE_SHARE* tabl // reset the kc_info state at keynr static void reset_key_and_col_info(KEY_AND_COL_INFO *kc_info, uint keynr) { bitmap_clear_all(&kc_info->key_filters[keynr]); - tokudb_my_free(kc_info->cp_info[keynr]); + tokudb::memory::free(kc_info->cp_info[keynr]); kc_info->cp_info[keynr] = NULL; kc_info->mcp_info[keynr] = (MULTI_COL_PACK_INFO) { 0, 0 }; } -static int initialize_key_and_col_info(TABLE_SHARE* table_share, TABLE* table, KEY_AND_COL_INFO* kc_info, uint hidden_primary_key, uint primary_key) { +static int initialize_key_and_col_info( + TABLE_SHARE* table_share, + TABLE* table, + KEY_AND_COL_INFO* kc_info, + uint hidden_primary_key, + uint primary_key) { + int error = 0; uint32_t curr_blob_field_index = 0; uint32_t max_var_bytes = 0; @@ -1420,7 +1519,7 @@ static int initialize_key_and_col_info(TABLE_SHARE* table_share, TABLE* table, K case toku_type_fixbinary: case toku_type_fixstring: pack_length = field->pack_length(); - assert(pack_length < 1<<16); + assert_always(pack_length < 1<<16); kc_info->field_types[i] = KEY_AND_COL_INFO::TOKUDB_FIXED_FIELD; kc_info->field_lengths[i] = (uint16_t)pack_length; kc_info->length_bytes[i] = 0; @@ -1436,11 +1535,12 @@ static int initialize_key_and_col_info(TABLE_SHARE* table_share, TABLE* table, K case toku_type_varbinary: kc_info->field_types[i] = KEY_AND_COL_INFO::TOKUDB_VARIABLE_FIELD; kc_info->field_lengths[i] = 0; - kc_info->length_bytes[i] = (uchar)((Field_varstring *)field)->length_bytes; + kc_info->length_bytes[i] = + (uchar)((Field_varstring*)field)->length_bytes; max_var_bytes += field->field_length; break; default: - assert(false); + assert_unreachable(); } } kc_info->num_blobs = curr_blob_field_index; @@ -1452,48 +1552,44 @@ static int initialize_key_and_col_info(TABLE_SHARE* table_share, TABLE* table, K // if (max_var_bytes < 256) { kc_info->num_offset_bytes = 1; - } - else { + } else { kc_info->num_offset_bytes = 2; } - for (uint i = 0; i < table_share->keys + tokudb_test(hidden_primary_key); i++) { + for (uint i = 0; + i < table_share->keys + tokudb_test(hidden_primary_key); + i++) { // // do the cluster/primary key filtering calculations // - if (! (i==primary_key && hidden_primary_key) ){ - if ( i == primary_key ) { + if (!(i==primary_key && hidden_primary_key)) { + if (i == primary_key) { set_key_filter( &kc_info->key_filters[primary_key], &table_share->key_info[primary_key], table, - true - ); - } - else { + true); + } else { set_key_filter( &kc_info->key_filters[i], &table_share->key_info[i], table, - true - ); + true); if (!hidden_primary_key) { set_key_filter( &kc_info->key_filters[i], &table_share->key_info[primary_key], table, - true - ); + true); } } } if (i == primary_key || key_is_clustering(&table_share->key_info[i])) { - error = initialize_col_pack_info(kc_info,table_share,i); + error = initialize_col_pack_info(kc_info, table_share, i); if (error) { goto exit; } } - } exit: return error; @@ -1544,8 +1640,6 @@ int ha_tokudb::initialize_share(const char* name, int mode) { if (error) { goto exit; } } - DBUG_PRINT("info", ("share->use_count %u", share->use_count)); - share->m_initialize_count++; error = get_status(txn); if (error) { @@ -1574,43 +1668,63 @@ int ha_tokudb::initialize_share(const char* name, int mode) { goto exit; #endif - error = initialize_key_and_col_info( - table_share, - table, - &share->kc_info, - hidden_primary_key, - primary_key - ); + error = + initialize_key_and_col_info( + table_share, + table, + &share->kc_info, + hidden_primary_key, + primary_key); if (error) { goto exit; } - + error = open_main_dictionary(name, mode == O_RDONLY, txn); - if (error) { goto exit; } + if (error) { + goto exit; + } share->has_unique_keys = false; + share->_keys = table_share->keys; + share->_max_key_parts = table_share->key_parts; + share->_key_descriptors = + (TOKUDB_SHARE::key_descriptor_t*)tokudb::memory::malloc( + sizeof(TOKUDB_SHARE::key_descriptor_t) * share->_keys, + MYF(MY_ZEROFILL)); + /* Open other keys; These are part of the share structure */ for (uint i = 0; i < table_share->keys; i++) { + share->_key_descriptors[i]._parts = get_key_parts(&table_share->key_info[i]); + if (i == primary_key) { + share->_key_descriptors[i]._is_unique = true; + share->_key_descriptors[i]._name = tokudb::memory::strdup("primary", 0); + } else { + share->_key_descriptors[i]._is_unique = false; + share->_key_descriptors[i]._name = + tokudb::memory::strdup(table_share->key_info[i].name, 0); + } + if (table_share->key_info[i].flags & HA_NOSAME) { + share->_key_descriptors[i]._is_unique = true; share->has_unique_keys = true; } if (i != primary_key) { - error = open_secondary_dictionary( - &share->key_file[i], - &table_share->key_info[i], - name, - mode == O_RDONLY, - txn - ); + error = + open_secondary_dictionary( + &share->key_file[i], + &table_share->key_info[i], + name, + mode == O_RDONLY, + txn); if (error) { goto exit; } } } - share->replace_into_fast = can_replace_into_be_fast( - table_share, - &share->kc_info, - primary_key - ); - + share->replace_into_fast = + can_replace_into_be_fast( + table_share, + &share->kc_info, + primary_key); + share->pk_has_string = false; if (!hidden_primary_key) { // @@ -1640,9 +1754,8 @@ int ha_tokudb::initialize_share(const char* name, int mode) { // estimate_num_rows should not fail under normal conditions // if (error == 0) { - share->rows = num_rows; - } - else { + share->set_row_count(num_rows, true); + } else { goto exit; } // @@ -1655,8 +1768,7 @@ int ha_tokudb::initialize_share(const char* name, int mode) { if (may_table_be_empty(txn)) { share->try_table_lock = true; - } - else { + } else { share->try_table_lock = false; } @@ -1665,12 +1777,22 @@ int ha_tokudb::initialize_share(const char* name, int mode) { init_hidden_prim_key_info(txn); // initialize cardinality info from the status dictionary - share->n_rec_per_key = tokudb::compute_total_key_parts(table_share); - share->rec_per_key = (uint64_t *) tokudb_my_realloc(share->rec_per_key, share->n_rec_per_key * sizeof (uint64_t), MYF(MY_FAE + MY_ALLOW_ZERO_PTR)); - error = tokudb::get_card_from_status(share->status_block, txn, share->n_rec_per_key, share->rec_per_key); - if (error) { - for (uint i = 0; i < share->n_rec_per_key; i++) - share->rec_per_key[i] = 0; + { + uint32_t rec_per_keys = tokudb::compute_total_key_parts(table_share); + uint64_t* rec_per_key = + (uint64_t*)tokudb::memory::malloc( + rec_per_keys * sizeof(uint64_t), + MYF(MY_FAE)); + error = + tokudb::get_card_from_status( + share->status_block, + txn, + rec_per_keys, + rec_per_key); + if (error) { + memset(rec_per_key, 0, sizeof(ulonglong) * rec_per_keys); + } + share->init_cardinality_counts(rec_per_keys, rec_per_key); } error = 0; @@ -1720,7 +1842,8 @@ int ha_tokudb::open(const char *name, int mode, uint test_if_locked) { // the "+ 1" is for the first byte that states +/- infinity // multiply everything by 2 to account for clustered keys having a key and primary key together max_key_length = 2*(table_share->max_key_length + MAX_REF_PARTS * 3 + sizeof(uchar)); - alloc_ptr = tokudb_my_multi_malloc(MYF(MY_WME), + alloc_ptr = tokudb::memory::multi_malloc( + MYF(MY_WME), &key_buff, max_key_length, &key_buff2, max_key_length, &key_buff3, max_key_length, @@ -1730,81 +1853,80 @@ int ha_tokudb::open(const char *name, int mode, uint test_if_locked) { &primary_key_buff, (hidden_primary_key ? 0 : max_key_length), &fixed_cols_for_query, table_share->fields*sizeof(uint32_t), &var_cols_for_query, table_share->fields*sizeof(uint32_t), - NullS - ); + NullS); if (alloc_ptr == NULL) { ret_val = 1; goto exit; } - size_range_query_buff = get_tokudb_read_buf_size(thd); - range_query_buff = (uchar *)tokudb_my_malloc(size_range_query_buff, MYF(MY_WME)); + size_range_query_buff = tokudb::sysvars::read_buf_size(thd); + range_query_buff = + (uchar*)tokudb::memory::malloc(size_range_query_buff, MYF(MY_WME)); if (range_query_buff == NULL) { ret_val = 1; goto exit; } - alloced_rec_buff_length = table_share->rec_buff_length + table_share->fields; - rec_buff = (uchar *) tokudb_my_malloc(alloced_rec_buff_length, MYF(MY_WME)); + alloced_rec_buff_length = table_share->rec_buff_length + + table_share->fields; + rec_buff = (uchar *) tokudb::memory::malloc( + alloced_rec_buff_length, + MYF(MY_WME)); if (rec_buff == NULL) { ret_val = 1; goto exit; } alloced_update_rec_buff_length = alloced_rec_buff_length; - rec_update_buff = (uchar *) tokudb_my_malloc(alloced_update_rec_buff_length, MYF(MY_WME)); + rec_update_buff = (uchar*)tokudb::memory::malloc( + alloced_update_rec_buff_length, + MYF(MY_WME)); if (rec_update_buff == NULL) { ret_val = 1; goto exit; } // lookup or create share - tokudb_pthread_mutex_lock(&tokudb_mutex); - share = get_share(name, table_share); - assert(share); + share = TOKUDB_SHARE::get_share(name, table_share, &lock, true); + assert_always(share); - thr_lock_data_init(&share->lock, &lock, NULL); - - tokudb_pthread_mutex_lock(&share->mutex); - tokudb_pthread_mutex_unlock(&tokudb_mutex); - share->use_count++; - while (share->m_state == TOKUDB_SHARE::OPENING || share->m_state == TOKUDB_SHARE::CLOSING) { - tokudb_pthread_cond_wait(&share->m_openclose_cond, &share->mutex); - } - if (share->m_state == TOKUDB_SHARE::CLOSED) { - share->m_state = TOKUDB_SHARE::OPENING; - tokudb_pthread_mutex_unlock(&share->mutex); + if (share->state() != TOKUDB_SHARE::OPENED) { + // means we're responsible for the transition to OPENED, ERROR or CLOSED ret_val = allocate_key_and_col_info(table_share, &share->kc_info); if (ret_val == 0) { ret_val = initialize_share(name, mode); } - tokudb_pthread_mutex_lock(&share->mutex); if (ret_val == 0) { - share->m_state = TOKUDB_SHARE::OPENED; + share->set_state(TOKUDB_SHARE::OPENED); } else { - share->m_state = TOKUDB_SHARE::ERROR; - share->m_error = ret_val; + share->set_state(TOKUDB_SHARE::ERROR); } - tokudb_pthread_cond_broadcast(&share->m_openclose_cond); + share->unlock(); + } else { + // got an already OPENED instance + share->unlock(); } - if (share->m_state == TOKUDB_SHARE::ERROR) { - ret_val = share->m_error; - tokudb_pthread_mutex_unlock(&share->mutex); - free_share(share); + + if (share->state() == TOKUDB_SHARE::ERROR) { + share->release(); goto exit; - } else { - assert(share->m_state == TOKUDB_SHARE::OPENED); - tokudb_pthread_mutex_unlock(&share->mutex); } + assert_always(share->state() == TOKUDB_SHARE::OPENED); + ref_length = share->ref_length; // If second open - - if (tokudb_debug & TOKUDB_DEBUG_OPEN) { - TOKUDB_HANDLER_TRACE("tokudbopen:%p:share=%p:file=%p:table=%p:table->s=%p:%d", - this, share, share->file, table, table->s, share->use_count); - } + + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_OPEN, + "tokudbopen:%p:share=%p:file=%p:table=%p:table->s=%p:%d", + this, + share, + share->file, + table, + table->s, + share->use_count()); key_read = false; stats.block_size = 1<<20; // QQQ Tokudb DB block size @@ -1813,13 +1935,13 @@ int ha_tokudb::open(const char *name, int mode, uint test_if_locked) { exit: if (ret_val) { - tokudb_my_free(range_query_buff); + tokudb::memory::free(range_query_buff); range_query_buff = NULL; - tokudb_my_free(alloc_ptr); + tokudb::memory::free(alloc_ptr); alloc_ptr = NULL; - tokudb_my_free(rec_buff); + tokudb::memory::free(rec_buff); rec_buff = NULL; - tokudb_my_free(rec_update_buff); + tokudb::memory::free(rec_update_buff); rec_update_buff = NULL; if (error) { @@ -1982,7 +2104,7 @@ int ha_tokudb::write_frm_data(DB* db, DB_TXN* txn, const char* frm_name) { error = 0; cleanup: - tokudb_my_free(frm_data); + tokudb::memory::free(frm_data); TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -1993,8 +2115,8 @@ int ha_tokudb::remove_frm_data(DB *db, DB_TXN *txn) { static int smart_dbt_callback_verify_frm (DBT const *key, DBT const *row, void *context) { DBT* stored_frm = (DBT *)context; stored_frm->size = row->size; - stored_frm->data = (uchar *)tokudb_my_malloc(row->size, MYF(MY_WME)); - assert(stored_frm->data); + stored_frm->data = (uchar *)tokudb::memory::malloc(row->size, MYF(MY_WME)); + assert_always(stored_frm->data); memcpy(stored_frm->data, row->data, row->size); return 0; } @@ -2046,8 +2168,8 @@ int ha_tokudb::verify_frm_data(const char* frm_name, DB_TXN* txn) { error = 0; cleanup: - tokudb_my_free(mysql_frm_data); - tokudb_my_free(stored_frm.data); + tokudb::memory::free(mysql_frm_data); + tokudb::memory::free(stored_frm.data); TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -2083,7 +2205,7 @@ int ha_tokudb::write_auto_inc_create(DB* db, ulonglong val, DB_TXN* txn){ // // Closes a handle to a table. // -int ha_tokudb::close(void) { +int ha_tokudb::close() { TOKUDB_HANDLER_DBUG_ENTER(""); int r = __close(); TOKUDB_HANDLER_DBUG_RETURN(r); @@ -2091,13 +2213,12 @@ int ha_tokudb::close(void) { int ha_tokudb::__close() { TOKUDB_HANDLER_DBUG_ENTER(""); - if (tokudb_debug & TOKUDB_DEBUG_OPEN) - TOKUDB_HANDLER_TRACE("close:%p", this); - tokudb_my_free(rec_buff); - tokudb_my_free(rec_update_buff); - tokudb_my_free(blob_buff); - tokudb_my_free(alloc_ptr); - tokudb_my_free(range_query_buff); + TOKUDB_HANDLER_TRACE_FOR_FLAGS(TOKUDB_DEBUG_OPEN, "close:%p", this); + tokudb::memory::free(rec_buff); + tokudb::memory::free(rec_update_buff); + tokudb::memory::free(blob_buff); + tokudb::memory::free(alloc_ptr); + tokudb::memory::free(range_query_buff); for (uint32_t i = 0; i < sizeof(mult_key_dbt_array)/sizeof(mult_key_dbt_array[0]); i++) { toku_dbt_array_destroy(&mult_key_dbt_array[i]); } @@ -2108,7 +2229,7 @@ int ha_tokudb::__close() { rec_update_buff = NULL; alloc_ptr = NULL; ha_tokudb::reset(); - int retval = free_share(share); + int retval = share->release(); TOKUDB_HANDLER_DBUG_RETURN(retval); } @@ -2120,8 +2241,11 @@ int ha_tokudb::__close() { // bool ha_tokudb::fix_rec_buff_for_blob(ulong length) { if (!rec_buff || (length > alloced_rec_buff_length)) { - uchar *newptr; - if (!(newptr = (uchar *) tokudb_my_realloc((void *) rec_buff, length, MYF(MY_ALLOW_ZERO_PTR)))) + uchar* newptr = (uchar*)tokudb::memory::realloc( + (void*)rec_buff, + length, + MYF(MY_ALLOW_ZERO_PTR)); + if (!newptr) return 1; rec_buff = newptr; alloced_rec_buff_length = length; @@ -2137,8 +2261,11 @@ bool ha_tokudb::fix_rec_buff_for_blob(ulong length) { // bool ha_tokudb::fix_rec_update_buff_for_blob(ulong length) { if (!rec_update_buff || (length > alloced_update_rec_buff_length)) { - uchar *newptr; - if (!(newptr = (uchar *) tokudb_my_realloc((void *) rec_update_buff, length, MYF(MY_ALLOW_ZERO_PTR)))) + uchar* newptr = (uchar*)tokudb::memory::realloc( + (void*)rec_update_buff, + length, + MYF(MY_ALLOW_ZERO_PTR)); + if (!newptr) return 1; rec_update_buff= newptr; alloced_update_rec_buff_length = length; @@ -2273,9 +2400,11 @@ int ha_tokudb::unpack_blobs( // // assert that num_bytes > 0 iff share->num_blobs > 0 // - assert( !((share->kc_info.num_blobs == 0) && (num_bytes > 0)) ); + assert_always( !((share->kc_info.num_blobs == 0) && (num_bytes > 0)) ); if (num_bytes > num_blob_bytes) { - ptr = (uchar *)tokudb_my_realloc((void *)blob_buff, num_bytes, MYF(MY_ALLOW_ZERO_PTR)); + ptr = (uchar*)tokudb::memory::realloc( + (void*)blob_buff, num_bytes, + MYF(MY_ALLOW_ZERO_PTR)); if (ptr == NULL) { error = ENOMEM; goto exit; @@ -2390,8 +2519,7 @@ int ha_tokudb::unpack_row( data_end_offset = uint2korr(var_field_offset_ptr); break; default: - assert(false); - break; + assert_unreachable(); } unpack_var_field( record + field_offset(field, table), @@ -2513,7 +2641,7 @@ uint32_t ha_tokudb::place_key_into_mysql_buff( // // HOPEFULLY TEMPORARY // - assert(table->s->db_low_byte_first); + assert_always(table->s->db_low_byte_first); #endif pos = unpack_toku_key_field( record + field_offset(key_part->field, table), @@ -2585,7 +2713,7 @@ uint32_t ha_tokudb::place_key_into_dbt_buff( // // HOPEFULLY TEMPORARY // - assert(table->s->db_low_byte_first); + assert_always(table->s->db_low_byte_first); #endif // // accessing field_offset(key_part->field) instead off key_part->offset @@ -2782,7 +2910,7 @@ DBT *ha_tokudb::pack_key( offset = 1; // Data is at key_ptr+1 } #if !defined(MARIADB_BASE_VERSION) - assert(table->s->db_low_byte_first); + assert_always(table->s->db_low_byte_first); #endif buff = pack_key_toku_key_field( buff, @@ -2838,7 +2966,7 @@ DBT *ha_tokudb::pack_ext_key( for (; key_part != end && (int) key_length > 0; key_part++) { // if the SK part is part of the PK, then append it to the list. if (key_part->field->part_of_key.is_set(primary_key)) { - assert(pk_next < pk_parts); + assert_always(pk_next < pk_parts); pk_info[pk_next].key_ptr = key_ptr; pk_info[pk_next].key_part = key_part; pk_next++; @@ -2855,7 +2983,7 @@ DBT *ha_tokudb::pack_ext_key( offset = 1; // Data is at key_ptr+1 } #if !defined(MARIADB_BASE_VERSION) - assert(table->s->db_low_byte_first); + assert_always(table->s->db_low_byte_first); #endif buff = pack_key_toku_key_field( buff, @@ -2869,22 +2997,33 @@ DBT *ha_tokudb::pack_ext_key( } if (key_length > 0) { - assert(key_part == end); + assert_always(key_part == end); end = key_info->key_part + get_ext_key_parts(key_info); // pack PK in order of PK key parts - for (uint pk_index = 0; key_part != end && (int) key_length > 0 && pk_index < pk_parts; pk_index++) { + for (uint pk_index = 0; + key_part != end && (int) key_length > 0 && pk_index < pk_parts; + pk_index++) { uint i; for (i = 0; i < pk_next; i++) { - if (pk_info[i].key_part->fieldnr == pk_key_info->key_part[pk_index].fieldnr) + if (pk_info[i].key_part->fieldnr == + pk_key_info->key_part[pk_index].fieldnr) break; } if (i < pk_next) { const uchar *this_key_ptr = pk_info[i].key_ptr; KEY_PART_INFO *this_key_part = pk_info[i].key_part; - buff = pack_key_toku_key_field(buff, (uchar *) this_key_ptr, this_key_part->field, this_key_part->length); + buff = pack_key_toku_key_field( + buff, + (uchar*)this_key_ptr, + this_key_part->field, + this_key_part->length); } else { - buff = pack_key_toku_key_field(buff, (uchar *) key_ptr, key_part->field, key_part->length); + buff = pack_key_toku_key_field( + buff, + (uchar*)key_ptr, + key_part->field, + key_part->length); key_ptr += key_part->store_length; key_length -= key_part->store_length; key_part++; @@ -2907,18 +3046,22 @@ void ha_tokudb::init_hidden_prim_key_info(DB_TXN *txn) { if (!(share->status & STATUS_PRIMARY_KEY_INIT)) { int error = 0; DBC* c = NULL; - error = share->key_file[primary_key]->cursor(share->key_file[primary_key], txn, &c, 0); - assert(error == 0); + error = share->key_file[primary_key]->cursor( + share->key_file[primary_key], + txn, + &c, + 0); + assert_always(error == 0); DBT key,val; memset(&key, 0, sizeof(key)); memset(&val, 0, sizeof(val)); error = c->c_get(c, &key, &val, DB_LAST); if (error == 0) { - assert(key.size == TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH); + assert_always(key.size == TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH); share->auto_ident = hpk_char_to_num((uchar *)key.data); } error = c->c_close(c); - assert(error == 0); + assert_always(error == 0); share->status |= STATUS_PRIMARY_KEY_INIT; } TOKUDB_HANDLER_DBUG_VOID_RETURN; @@ -2939,11 +3082,11 @@ int ha_tokudb::get_status(DB_TXN* txn) { // open status.tokudb // if (!share->status_block) { - error = open_status_dictionary( - &share->status_block, - share->table_name, - txn - ); + error = + open_status_dictionary( + &share->status_block, + share->full_table_name(), + txn); if (error) { goto cleanup; } @@ -2958,7 +3101,7 @@ int ha_tokudb::get_status(DB_TXN* txn) { key.size = sizeof(curr_key); value.flags = DB_DBT_USERMEM; - assert(share->status_block); + assert_always(share->status_block); // // get version // @@ -3048,7 +3191,7 @@ int ha_tokudb::get_status(DB_TXN* txn) { */ ha_rows ha_tokudb::estimate_rows_upper_bound() { TOKUDB_HANDLER_DBUG_ENTER(""); - DBUG_RETURN(share->rows + HA_TOKUDB_EXTRA_ROWS); + DBUG_RETURN(share->row_count() + HA_TOKUDB_EXTRA_ROWS); } // @@ -3112,8 +3255,8 @@ bool ha_tokudb::may_table_be_empty(DB_TXN *txn) { DBC* tmp_cursor = NULL; DB_TXN* tmp_txn = NULL; - const int empty_scan = THDVAR(ha_thd(), empty_scan); - if (empty_scan == TOKUDB_EMPTY_SCAN_DISABLED) + const int empty_scan = tokudb::sysvars::empty_scan(ha_thd()); + if (empty_scan == tokudb::sysvars::TOKUDB_EMPTY_SCAN_DISABLED) goto cleanup; if (txn == NULL) { @@ -3128,7 +3271,7 @@ bool ha_tokudb::may_table_be_empty(DB_TXN *txn) { if (error) goto cleanup; tmp_cursor->c_set_check_interrupt_callback(tmp_cursor, tokudb_killed_thd_callback, ha_thd()); - if (empty_scan == TOKUDB_EMPTY_SCAN_LR) + if (empty_scan == tokudb::sysvars::TOKUDB_EMPTY_SCAN_LR) error = tmp_cursor->c_getf_next(tmp_cursor, 0, smart_dbt_do_nothing, NULL); else error = tmp_cursor->c_getf_prev(tmp_cursor, 0, smart_dbt_do_nothing, NULL); @@ -3142,7 +3285,7 @@ bool ha_tokudb::may_table_be_empty(DB_TXN *txn) { cleanup: if (tmp_cursor) { int r = tmp_cursor->c_close(tmp_cursor); - assert(r == 0); + assert_always(r == 0); tmp_cursor = NULL; } if (tmp_txn) { @@ -3165,22 +3308,23 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) { ai_metadata_update_required = false; abort_loader = false; - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); uint curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); num_DBs_locked_in_bulk = true; lock_count = 0; if ((rows == 0 || rows > 1) && share->try_table_lock) { - if (get_prelock_empty(thd) && may_table_be_empty(transaction) && transaction != NULL) { + if (tokudb::sysvars::prelock_empty(thd) && + may_table_be_empty(transaction) && + transaction != NULL) { if (using_ignore || is_insert_ignore(thd) || thd->lex->duplicates != DUP_ERROR) { acquire_table_lock(transaction, lock_write); - } - else { + } else { mult_dbt_flags[primary_key] = 0; if (!thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS) && !hidden_primary_key) { mult_put_flags[primary_key] = DB_NOOVERWRITE; } - uint32_t loader_flags = (get_load_save_space(thd)) ? + uint32_t loader_flags = (tokudb::sysvars::load_save_space(thd)) ? LOADER_COMPRESS_INTERMEDIATES : 0; int error = db_env->create_loader( @@ -3195,7 +3339,7 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) { loader_flags ); if (error) { - assert(loader == NULL); + assert_always(loader == NULL); goto exit_try_table_lock; } @@ -3203,18 +3347,18 @@ void ha_tokudb::start_bulk_insert(ha_rows rows) { lc.ha = this; error = loader->set_poll_function(loader, loader_poll_fun, &lc); - assert(!error); + assert_always(!error); error = loader->set_error_callback(loader, loader_dup_fun, &lc); - assert(!error); + assert_always(!error); trx->stmt_progress.using_loader = true; } } exit_try_table_lock: - tokudb_pthread_mutex_lock(&share->mutex); + share->lock(); share->try_table_lock = false; - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); } TOKUDB_HANDLER_DBUG_VOID_RETURN; } @@ -3231,9 +3375,9 @@ int ha_tokudb::end_bulk_insert(bool abort) { tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); bool using_loader = (loader != NULL); if (ai_metadata_update_required) { - tokudb_pthread_mutex_lock(&share->mutex); + share->lock(); error = update_max_auto_inc(share->status_block, share->last_auto_increment); - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); if (error) { goto cleanup; } } delay_updating_ai_metadata = false; @@ -3284,7 +3428,7 @@ int ha_tokudb::end_bulk_insert(bool abort) { cleanup: if (num_DBs_locked_in_bulk) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } num_DBs_locked_in_bulk = false; lock_count = 0; @@ -3379,10 +3523,10 @@ int ha_tokudb::is_index_unique(bool* is_unique, DB_TXN* txn, DB* db, KEY* key_in cnt++; if ((cnt % 10000) == 0) { sprintf( - status_msg, - "Verifying index uniqueness: Checked %llu of %llu rows in key-%s.", - (long long unsigned) cnt, - share->rows, + status_msg, + "Verifying index uniqueness: Checked %llu of %llu rows in key-%s.", + (long long unsigned) cnt, + share->row_count(), key_info->name); thd_proc_info(thd, status_msg); if (thd_killed(thd)) { @@ -3466,7 +3610,7 @@ int ha_tokudb::is_val_unique(bool* is_unique, uchar* record, KEY* key_info, uint cleanup: if (tmp_cursor) { int r = tmp_cursor->c_close(tmp_cursor); - assert(r==0); + assert_always(r==0); tmp_cursor = NULL; } return error; @@ -3474,21 +3618,25 @@ int ha_tokudb::is_val_unique(bool* is_unique, uchar* record, KEY* key_info, uint static void maybe_do_unique_checks_delay(THD *thd) { if (thd->slave_thread) { - uint64_t delay_ms = THDVAR(thd, rpl_unique_checks_delay); + uint64_t delay_ms = tokudb::sysvars::rpl_unique_checks_delay(thd); if (delay_ms) usleep(delay_ms * 1000); } } static bool need_read_only(THD *thd) { - return opt_readonly || !THDVAR(thd, rpl_check_readonly); -} + return opt_readonly || !tokudb::sysvars::rpl_check_readonly(thd); +} static bool do_unique_checks(THD *thd, bool do_rpl_event) { - if (do_rpl_event && thd->slave_thread && need_read_only(thd) && !THDVAR(thd, rpl_unique_checks)) + if (do_rpl_event && + thd->slave_thread && + need_read_only(thd) && + !tokudb::sysvars::rpl_unique_checks(thd)) { return false; - else + } else { return !thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS); + } } int ha_tokudb::do_uniqueness_checks(uchar* record, DB_TXN* txn, THD* thd) { @@ -3551,10 +3699,10 @@ void ha_tokudb::test_row_packing(uchar* record, DBT* pk_key, DBT* pk_val) { // //use for testing the packing of keys // - tmp_pk_key_data = (uchar *)tokudb_my_malloc(pk_key->size, MYF(MY_WME)); - assert(tmp_pk_key_data); - tmp_pk_val_data = (uchar *)tokudb_my_malloc(pk_val->size, MYF(MY_WME)); - assert(tmp_pk_val_data); + tmp_pk_key_data = (uchar*)tokudb::memory::malloc(pk_key->size, MYF(MY_WME)); + assert_always(tmp_pk_key_data); + tmp_pk_val_data = (uchar*)tokudb::memory::malloc(pk_val->size, MYF(MY_WME)); + assert_always(tmp_pk_val_data); memcpy(tmp_pk_key_data, pk_key->data, pk_key->size); memcpy(tmp_pk_val_data, pk_val->data, pk_val->size); tmp_pk_key.data = tmp_pk_key_data; @@ -3587,19 +3735,21 @@ void ha_tokudb::test_row_packing(uchar* record, DBT* pk_key, DBT* pk_val) { &tmp_pk_key, &tmp_pk_val ); - assert(tmp_num_bytes == key.size); + assert_always(tmp_num_bytes == key.size); cmp = memcmp(key_buff3,key_buff2,tmp_num_bytes); - assert(cmp == 0); + assert_always(cmp == 0); // // test key packing of clustering keys // if (key_is_clustering(&table->key_info[keynr])) { error = pack_row(&row, (const uchar *) record, keynr); - assert(error == 0); + assert_always(error == 0); uchar* tmp_buff = NULL; - tmp_buff = (uchar *)tokudb_my_malloc(alloced_rec_buff_length,MYF(MY_WME)); - assert(tmp_buff); + tmp_buff = (uchar*)tokudb::memory::malloc( + alloced_rec_buff_length, + MYF(MY_WME)); + assert_always(tmp_buff); row_desc = (uchar *)share->key_file[keynr]->descriptor->dbt.data; row_desc += (*(uint32_t *)row_desc); row_desc += (*(uint32_t *)row_desc); @@ -3611,10 +3761,10 @@ void ha_tokudb::test_row_packing(uchar* record, DBT* pk_key, DBT* pk_val) { desc_size, &tmp_pk_val ); - assert(tmp_num_bytes == row.size); + assert_always(tmp_num_bytes == row.size); cmp = memcmp(tmp_buff,rec_buff,tmp_num_bytes); - assert(cmp == 0); - tokudb_my_free(tmp_buff); + assert_always(cmp == 0); + tokudb::memory::free(tmp_buff); } } @@ -3622,12 +3772,12 @@ void ha_tokudb::test_row_packing(uchar* record, DBT* pk_key, DBT* pk_val) { // copy stuff back out // error = pack_row(pk_val, (const uchar *) record, primary_key); - assert(pk_val->size == tmp_pk_val.size); + assert_always(pk_val->size == tmp_pk_val.size); cmp = memcmp(pk_val->data, tmp_pk_val_data, pk_val->size); - assert( cmp == 0); + assert_always( cmp == 0); - tokudb_my_free(tmp_pk_key_data); - tokudb_my_free(tmp_pk_val_data); + tokudb::memory::free(tmp_pk_key_data); + tokudb::memory::free(tmp_pk_val_data); } // set the put flags for the main dictionary @@ -3674,7 +3824,7 @@ void ha_tokudb::set_main_dict_put_flags(THD* thd, bool opt_eligible, uint32_t* p int ha_tokudb::insert_row_to_main_dictionary(uchar* record, DBT* pk_key, DBT* pk_val, DB_TXN* txn) { int error = 0; uint curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); - assert(curr_num_DBs == 1); + assert_always(curr_num_DBs == 1); uint32_t put_flags = mult_put_flags[primary_key]; THD *thd = ha_thd(); @@ -3806,33 +3956,36 @@ int ha_tokudb::write_row(uchar * record) { // of the auto inc field. // if (share->has_auto_inc && record == table->record[0]) { - tokudb_pthread_mutex_lock(&share->mutex); + share->lock(); ulonglong curr_auto_inc = retrieve_auto_increment( - table->field[share->ai_field_index]->key_type(), field_offset(table->field[share->ai_field_index], table), record); + table->field[share->ai_field_index]->key_type(), + field_offset(table->field[share->ai_field_index], table), + record); if (curr_auto_inc > share->last_auto_increment) { share->last_auto_increment = curr_auto_inc; if (delay_updating_ai_metadata) { ai_metadata_update_required = true; - } - else { - update_max_auto_inc(share->status_block, share->last_auto_increment); + } else { + update_max_auto_inc( + share->status_block, + share->last_auto_increment); } } - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); } // // grab reader lock on numDBs_lock // if (!num_DBs_locked_in_bulk) { - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); num_DBs_locked = true; } else { lock_count++; if (lock_count >= 2000) { - rw_unlock(&share->num_DBs_lock); - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); + share->_num_DBs_lock.lock_read(); lock_count = 0; } } @@ -3862,10 +4015,8 @@ int ha_tokudb::write_row(uchar * record) { } } txn = create_sub_trans ? sub_trans : transaction; - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("txn %p", txn); - } - if (tokudb_debug & TOKUDB_DEBUG_CHECK_KEY) { + TOKUDB_HANDLER_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "txn %p", txn); + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_CHECK_KEY))) { test_row_packing(record,&prim_key,&row); } if (loader) { @@ -3874,8 +4025,7 @@ int ha_tokudb::write_row(uchar * record) { abort_loader = true; goto cleanup; } - } - else { + } else { error = do_uniqueness_checks(record, txn, thd); if (error) { // for #4633 @@ -3888,8 +4038,7 @@ int ha_tokudb::write_row(uchar * record) { // was found and this is a duplicate key, // so we set last_dup_key last_dup_key = primary_key; - } - else if (r != DB_NOTFOUND) { + } else if (r != DB_NOTFOUND) { // if some other error is returned, return that to the user. error = r; } @@ -3899,8 +4048,7 @@ int ha_tokudb::write_row(uchar * record) { if (curr_num_DBs == 1) { error = insert_row_to_main_dictionary(record,&prim_key, &row, txn); if (error) { goto cleanup; } - } - else { + } else { error = insert_rows_to_dictionaries_mult(&prim_key, &row, txn, thd); if (error) { goto cleanup; } } @@ -3918,7 +4066,7 @@ int ha_tokudb::write_row(uchar * record) { } cleanup: if (num_DBs_locked) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } if (error == DB_KEYEXIST) { error = HA_ERR_FOUND_DUPP_KEY; @@ -3989,7 +4137,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) { // of the auto inc field. // if (share->has_auto_inc && new_row == table->record[0]) { - tokudb_pthread_mutex_lock(&share->mutex); + share->lock(); ulonglong curr_auto_inc = retrieve_auto_increment( table->field[share->ai_field_index]->key_type(), field_offset(table->field[share->ai_field_index], table), @@ -4001,7 +4149,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) { share->last_auto_increment = curr_auto_inc; } } - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); } // @@ -4009,7 +4157,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) { // bool num_DBs_locked = false; if (!num_DBs_locked_in_bulk) { - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); num_DBs_locked = true; } curr_num_DBs = share->num_DBs; @@ -4100,6 +4248,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) { last_dup_key = primary_key; } else if (!error) { + updated_rows++; trx->stmt_progress.updated++; track_progress(thd); } @@ -4107,7 +4256,7 @@ int ha_tokudb::update_row(const uchar * old_row, uchar * new_row) { cleanup: if (num_DBs_locked) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } if (error == DB_KEYEXIST) { error = HA_ERR_FOUND_DUPP_KEY; @@ -4150,7 +4299,7 @@ int ha_tokudb::delete_row(const uchar * record) { // bool num_DBs_locked = false; if (!num_DBs_locked_in_bulk) { - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); num_DBs_locked = true; } curr_num_DBs = share->num_DBs; @@ -4166,33 +4315,36 @@ int ha_tokudb::delete_row(const uchar * record) { goto cleanup; } - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("all %p stmt %p sub_sp_level %p transaction %p", trx->all, trx->stmt, trx->sub_sp_level, transaction); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "all %p stmt %p sub_sp_level %p transaction %p", + trx->all, + trx->stmt, + trx->sub_sp_level, + transaction); - error = db_env->del_multiple( - db_env, - share->key_file[primary_key], - transaction, - &prim_key, - &row, - curr_num_DBs, - share->key_file, - mult_key_dbt_array, - mult_del_flags - ); + error = + db_env->del_multiple( + db_env, + share->key_file[primary_key], + transaction, + &prim_key, + &row, + curr_num_DBs, + share->key_file, + mult_key_dbt_array, + mult_del_flags); if (error) { DBUG_PRINT("error", ("Got error %d", error)); - } - else { + } else { deleted_rows++; trx->stmt_progress.deleted++; track_progress(thd); } cleanup: if (num_DBs_locked) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -4309,7 +4461,7 @@ static bool tokudb_do_bulk_fetch(THD *thd) { case SQLCOM_INSERT_SELECT: case SQLCOM_REPLACE_SELECT: case SQLCOM_DELETE: - return THDVAR(thd, bulk_fetch) != 0; + return tokudb::sysvars::bulk_fetch(thd) != 0; default: return false; } @@ -4361,7 +4513,7 @@ int ha_tokudb::prepare_index_key_scan(const uchar * key, uint key_len) { // if (cursor) { int r = cursor->c_close(cursor); - assert(r==0); + assert_always(r==0); cursor = NULL; remove_from_trx_handler_list(); } @@ -4404,7 +4556,7 @@ int ha_tokudb::index_init(uint keynr, bool sorted) { if (cursor) { DBUG_PRINT("note", ("Closing active cursor")); int r = cursor->c_close(cursor); - assert(r==0); + assert_always(r==0); remove_from_trx_handler_list(); } active_index = keynr; @@ -4430,10 +4582,12 @@ int ha_tokudb::index_init(uint keynr, bool sorted) { if (use_write_locks) { cursor_flags |= DB_RMW; } - if (get_disable_prefetching(thd)) { + if (tokudb::sysvars::disable_prefetching(thd)) { cursor_flags |= DBC_DISABLE_PREFETCHING; } - if ((error = share->key_file[keynr]->cursor(share->key_file[keynr], transaction, &cursor, cursor_flags))) { + if ((error = share->key_file[keynr]->cursor(share->key_file[keynr], + transaction, &cursor, + cursor_flags))) { if (error == TOKUDB_MVCC_DICTIONARY_TOO_NEW) { error = HA_ERR_TABLE_DEF_CHANGED; my_error(ER_TABLE_DEF_CHANGED, MYF(0)); @@ -4478,7 +4632,7 @@ int ha_tokudb::index_end() { if (cursor) { DBUG_PRINT("enter", ("table: '%s'", table_share->table_name.str)); int r = cursor->c_close(cursor); - assert(r==0); + assert_always(r==0); cursor = NULL; remove_from_trx_handler_list(); last_cursor_error = 0; @@ -4546,7 +4700,7 @@ void ha_tokudb::extract_hidden_primary_key(uint keynr, DBT const *found_key) { int ha_tokudb::read_row_callback (uchar * buf, uint keynr, DBT const *row, DBT const *found_key) { - assert(keynr == primary_key); + assert_always(keynr == primary_key); return unpack_row(buf, row,found_key, keynr); } @@ -4703,7 +4857,7 @@ int ha_tokudb::index_next_same(uchar * buf, const uchar * key, uint keylen) { // -// According to InnoDB handlerton: Positions an index cursor to the index +// According to InnoDB handlerton: Positions an index cursor to the index // specified in keynr. Fetches the row if any // Parameters: // [out] buf - buffer for the returned row @@ -4719,10 +4873,20 @@ int ha_tokudb::index_next_same(uchar * buf, const uchar * key, uint keylen) { // TODO: investigate this for correctness // error otherwise // -int ha_tokudb::index_read(uchar * buf, const uchar * key, uint key_len, enum ha_rkey_function find_flag) { - TOKUDB_HANDLER_DBUG_ENTER("key %p %u:%2.2x find=%u", key, key_len, key ? key[0] : 0, find_flag); +int ha_tokudb::index_read( + uchar* buf, + const uchar* key, + uint key_len, + enum ha_rkey_function find_flag) { + + TOKUDB_HANDLER_DBUG_ENTER( + "key %p %u:%2.2x find=%u", + key, + key_len, + key ? key[0] : 0, + find_flag); invalidate_bulk_fetch(); - if (tokudb_debug & TOKUDB_DEBUG_INDEX_KEY) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_INDEX_KEY))) { TOKUDB_DBUG_DUMP("mysql key=", key, key_len); } DBT row; @@ -4730,14 +4894,17 @@ int ha_tokudb::index_read(uchar * buf, const uchar * key, uint key_len, enum ha_ int error = 0; uint32_t flags = 0; THD* thd = ha_thd(); - tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);; + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); struct smart_dbt_info info; struct index_read_info ir_info; HANDLE_INVALID_CURSOR(); - // if we locked a non-null key range and we now have a null key, then remove the bounds from the cursor - if (range_lock_grabbed && !range_lock_grabbed_null && index_key_is_null(table, tokudb_active_index, key, key_len)) { + // if we locked a non-null key range and we now have a null key, then + // remove the bounds from the cursor + if (range_lock_grabbed && + !range_lock_grabbed_null && + index_key_is_null(table, tokudb_active_index, key, key_len)) { range_lock_grabbed = range_lock_grabbed_null = false; cursor->c_remove_restriction(cursor); } @@ -4758,7 +4925,7 @@ int ha_tokudb::index_read(uchar * buf, const uchar * key, uint key_len, enum ha_ pack_key(&lookup_key, tokudb_active_index, key_buff3, key, key_len, COL_NEG_INF); DBT lookup_bound; pack_key(&lookup_bound, tokudb_active_index, key_buff4, key, key_len, COL_POS_INF); - if (tokudb_debug & TOKUDB_DEBUG_INDEX_KEY) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_INDEX_KEY))) { TOKUDB_DBUG_DUMP("tokudb key=", lookup_key.data, lookup_key.size); } ir_info.orig_key = &lookup_key; @@ -4815,8 +4982,8 @@ int ha_tokudb::index_read(uchar * buf, const uchar * key, uint key_len, enum ha_ if (!error && !key_read && tokudb_active_index != primary_key && !key_is_clustering(&table->key_info[tokudb_active_index])) { error = read_full_row(buf); } - - if (error && (tokudb_debug & TOKUDB_DEBUG_ERROR)) { + + if (TOKUDB_UNLIKELY(error && TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ERROR))) { TOKUDB_HANDLER_TRACE("error:%d:%d", error, find_flag); } trx->stmt_progress.queried++; @@ -4845,7 +5012,7 @@ int ha_tokudb::read_data_from_range_query_buff(uchar* buf, bool need_val, bool d // if this is a covering index, this is all we need if (do_key_read) { - assert(!need_val); + assert_always(!need_val); extract_hidden_primary_key(tokudb_active_index, &curr_key); read_key_only(buf, tokudb_active_index, &curr_key); error = 0; @@ -4979,7 +5146,7 @@ int ha_tokudb::fill_range_query_buf( // uint32_t size_remaining = size_range_query_buff - bytes_used_in_range_query_buff; uint32_t size_needed; - uint32_t user_defined_size = get_tokudb_read_buf_size(thd); + uint32_t user_defined_size = tokudb::sysvars::read_buf_size(thd); uchar* curr_pos = NULL; if (key_to_compare) { @@ -5036,7 +5203,7 @@ int ha_tokudb::fill_range_query_buf( size_needed = sizeof(uint32_t) + key->size; } if (size_remaining < size_needed) { - range_query_buff = (uchar *)tokudb_my_realloc( + range_query_buff = (uchar *)tokudb::memory::realloc( (void *)range_query_buff, bytes_used_in_range_query_buff+size_needed, MYF(MY_WME) @@ -5136,7 +5303,7 @@ int ha_tokudb::fill_range_query_buf( } bytes_used_in_range_query_buff = curr_pos - range_query_buff; - assert(bytes_used_in_range_query_buff <= size_range_query_buff); + assert_always(bytes_used_in_range_query_buff <= size_range_query_buff); // // now determine if we should continue with the bulk fetch @@ -5153,7 +5320,7 @@ int ha_tokudb::fill_range_query_buf( // row fetch upper bound. if (bulk_fetch_iteration < HA_TOKU_BULK_FETCH_ITERATION_MAX) { uint64_t row_fetch_upper_bound = 1LLU << bulk_fetch_iteration; - assert(row_fetch_upper_bound > 0); + assert_always(row_fetch_upper_bound > 0); if (rows_fetched_using_bulk_fetch >= row_fetch_upper_bound) { error = 0; goto cleanup; @@ -5509,40 +5676,69 @@ int ha_tokudb::rnd_next(uchar * buf) { void ha_tokudb::track_progress(THD* thd) { tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); if (trx) { - ulonglong num_written = trx->stmt_progress.inserted + trx->stmt_progress.updated + trx->stmt_progress.deleted; + ulonglong num_written = trx->stmt_progress.inserted + + trx->stmt_progress.updated + + trx->stmt_progress.deleted; bool update_status = - (trx->stmt_progress.queried && tokudb_read_status_frequency && (trx->stmt_progress.queried % tokudb_read_status_frequency) == 0) || - (num_written && tokudb_write_status_frequency && (num_written % tokudb_write_status_frequency) == 0); + (trx->stmt_progress.queried && + tokudb::sysvars::read_status_frequency && + (trx->stmt_progress.queried % + tokudb::sysvars::read_status_frequency) == 0) || + (num_written && tokudb::sysvars::write_status_frequency && + (num_written % tokudb::sysvars::write_status_frequency) == 0); if (update_status) { char *next_status = write_status_msg; bool first = true; int r; if (trx->stmt_progress.queried) { - r = sprintf(next_status, "Queried about %llu row%s", trx->stmt_progress.queried, trx->stmt_progress.queried == 1 ? "" : "s"); - assert(r >= 0); + r = sprintf( + next_status, + "Queried about %llu row%s", + trx->stmt_progress.queried, + trx->stmt_progress.queried == 1 ? "" : "s"); + assert_always(r >= 0); next_status += r; first = false; } if (trx->stmt_progress.inserted) { if (trx->stmt_progress.using_loader) { - r = sprintf(next_status, "%sFetched about %llu row%s, loading data still remains", first ? "" : ", ", trx->stmt_progress.inserted, trx->stmt_progress.inserted == 1 ? "" : "s"); - } - else { - r = sprintf(next_status, "%sInserted about %llu row%s", first ? "" : ", ", trx->stmt_progress.inserted, trx->stmt_progress.inserted == 1 ? "" : "s"); + r = sprintf( + next_status, + "%sFetched about %llu row%s, loading data still remains", + first ? "" : ", ", + trx->stmt_progress.inserted, + trx->stmt_progress.inserted == 1 ? "" : "s"); + } else { + r = sprintf( + next_status, + "%sInserted about %llu row%s", + first ? "" : ", ", + trx->stmt_progress.inserted, + trx->stmt_progress.inserted == 1 ? "" : "s"); } - assert(r >= 0); + assert_always(r >= 0); next_status += r; first = false; } if (trx->stmt_progress.updated) { - r = sprintf(next_status, "%sUpdated about %llu row%s", first ? "" : ", ", trx->stmt_progress.updated, trx->stmt_progress.updated == 1 ? "" : "s"); - assert(r >= 0); + r = sprintf( + next_status, + "%sUpdated about %llu row%s", + first ? "" : ", ", + trx->stmt_progress.updated, + trx->stmt_progress.updated == 1 ? "" : "s"); + assert_always(r >= 0); next_status += r; first = false; } if (trx->stmt_progress.deleted) { - r = sprintf(next_status, "%sDeleted about %llu row%s", first ? "" : ", ", trx->stmt_progress.deleted, trx->stmt_progress.deleted == 1 ? "" : "s"); - assert(r >= 0); + r = sprintf( + next_status, + "%sDeleted about %llu row%s", + first ? "" : ", ", + trx->stmt_progress.deleted, + trx->stmt_progress.deleted == 1 ? "" : "s"); + assert_always(r >= 0); next_status += r; first = false; } @@ -5583,7 +5779,7 @@ int ha_tokudb::rnd_pos(uchar * buf, uchar * pos) { // test rpl slave by inducing a delay before the point query THD *thd = ha_thd(); if (thd->slave_thread && (in_rpl_delete_rows || in_rpl_update_rows)) { - uint64_t delay_ms = THDVAR(thd, rpl_lookup_rows_delay); + uint64_t delay_ms = tokudb::sysvars::rpl_lookup_rows_delay(thd); if (delay_ms) usleep(delay_ms * 1000); } @@ -5664,7 +5860,7 @@ int ha_tokudb::prelock_range(const key_range *start_key, const key_range *end_ke // if (cursor) { int r = cursor->c_close(cursor); - assert(r==0); + assert_always(r==0); cursor = NULL; remove_from_trx_handler_list(); } @@ -5784,7 +5980,7 @@ int ha_tokudb::info(uint flag) { DB_TXN* txn = NULL; if (flag & HA_STATUS_VARIABLE) { // Just to get optimizations right - stats.records = share->rows + share->rows_from_locked_table; + stats.records = share->row_count() + share->rows_from_locked_table; if (stats.records == 0) { stats.records++; } @@ -5795,30 +5991,35 @@ int ha_tokudb::info(uint flag) { memset(&frag_info, 0, sizeof frag_info); error = txn_begin(db_env, NULL, &txn, DB_READ_UNCOMMITTED, ha_thd()); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } // we should always have a primary key - assert(share->file != NULL); + assert_always(share->file != NULL); error = estimate_num_rows(share->file,&num_rows, txn); if (error == 0) { - share->rows = num_rows; + share->set_row_count(num_rows, false); stats.records = num_rows; if (stats.records == 0) { stats.records++; } - } - else { + } else { goto cleanup; } error = share->file->get_fragmentation(share->file, &frag_info); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } stats.delete_length = frag_info.unused_bytes; DB_BTREE_STAT64 dict_stats; error = share->file->stat64(share->file, txn, &dict_stats); - if (error) { goto cleanup; } - + if (error) { + goto cleanup; + } + stats.create_time = dict_stats.bt_create_time_sec; stats.update_time = dict_stats.bt_modify_time_sec; stats.check_time = dict_stats.bt_verify_time_sec; @@ -5828,18 +6029,24 @@ int ha_tokudb::info(uint flag) { // in this case, we have a hidden primary key, do not // want to report space taken up by the hidden primary key to the user // - uint64_t hpk_space = TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH*dict_stats.bt_ndata; - stats.data_file_length = (hpk_space > stats.data_file_length) ? 0 : stats.data_file_length - hpk_space; - } - else { + uint64_t hpk_space = + TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH * dict_stats.bt_ndata; + stats.data_file_length = + (hpk_space > stats.data_file_length) ? + 0 : stats.data_file_length - hpk_space; + } else { // // one infinity byte per key needs to be subtracted // uint64_t inf_byte_space = dict_stats.bt_ndata; - stats.data_file_length = (inf_byte_space > stats.data_file_length) ? 0 : stats.data_file_length - inf_byte_space; + stats.data_file_length = + (inf_byte_space > stats.data_file_length) ? + 0 : stats.data_file_length - inf_byte_space; } - stats.mean_rec_length = stats.records ? (ulong)(stats.data_file_length/stats.records) : 0; + stats.mean_rec_length = + stats.records ? + (ulong)(stats.data_file_length/stats.records) : 0; stats.index_file_length = 0; // curr_num_DBs is the number of keys we have, according // to the mysql layer. if drop index is running concurrently @@ -5858,37 +6065,42 @@ int ha_tokudb::info(uint flag) { if (i == primary_key || share->key_file[i] == NULL) { continue; } - error = share->key_file[i]->stat64( - share->key_file[i], - txn, - &dict_stats - ); - if (error) { goto cleanup; } + error = + share->key_file[i]->stat64( + share->key_file[i], + txn, + &dict_stats); + if (error) { + goto cleanup; + } stats.index_file_length += dict_stats.bt_dsize; - error = share->file->get_fragmentation( - share->file, - &frag_info - ); - if (error) { goto cleanup; } + error = + share->file->get_fragmentation( + share->file, + &frag_info); + if (error) { + goto cleanup; + } stats.delete_length += frag_info.unused_bytes; } } } if ((flag & HA_STATUS_CONST)) { - stats.max_data_file_length= 9223372036854775807ULL; - tokudb::set_card_in_key_info(table, share->n_rec_per_key, share->rec_per_key); + stats.max_data_file_length = 9223372036854775807ULL; + share->set_cardinality_counts_in_table(table); } /* Don't return key if we got an error for the internal primary key */ if (flag & HA_STATUS_ERRKEY && last_dup_key < table_share->keys) { errkey = last_dup_key; - } + } - if (flag & HA_STATUS_AUTO && table->found_next_number_field) { - THD *thd= table->in_use; - struct system_variables *variables= &thd->variables; - stats.auto_increment_value = share->last_auto_increment + variables->auto_increment_increment; + if (flag & HA_STATUS_AUTO && table->found_next_number_field) { + THD* thd = table->in_use; + struct system_variables* variables = &thd->variables; + stats.auto_increment_value = + share->last_auto_increment + variables->auto_increment_increment; } error = 0; cleanup: @@ -5935,7 +6147,7 @@ int ha_tokudb::extra(enum ha_extra_function operation) { TOKUDB_HANDLER_DBUG_RETURN(0); } -int ha_tokudb::reset(void) { +int ha_tokudb::reset() { TOKUDB_HANDLER_DBUG_ENTER(""); key_read = false; using_ignore = false; @@ -5959,14 +6171,13 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) { TOKUDB_HANDLER_DBUG_ENTER("%p %s", trans, lt == lock_read ? "r" : "w"); int error = ENOSYS; if (!num_DBs_locked_in_bulk) { - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); } uint curr_num_DBs = share->num_DBs; if (lt == lock_read) { error = 0; goto cleanup; - } - else if (lt == lock_write) { + } else if (lt == lock_write) { for (uint i = 0; i < curr_num_DBs; i++) { DB* db = share->key_file[i]; error = db->pre_acquire_table_lock(db, trans); @@ -5974,11 +6185,9 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) { TOKUDB_HANDLER_TRACE("%d db=%p trans=%p", i, db, trans); if (error) break; } - if (tokudb_debug & TOKUDB_DEBUG_LOCK) - TOKUDB_HANDLER_TRACE("error=%d", error); + TOKUDB_HANDLER_TRACE_FOR_FLAGS(TOKUDB_DEBUG_LOCK, "error=%d", error); if (error) goto cleanup; - } - else { + } else { error = ENOSYS; goto cleanup; } @@ -5986,7 +6195,7 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) { error = 0; cleanup: if (!num_DBs_locked_in_bulk) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -6017,17 +6226,19 @@ int ha_tokudb::create_txn(THD* thd, tokudb_trx_data* trx) { if ((error = txn_begin(db_env, NULL, &trx->all, txn_begin_flags, thd))) { goto cleanup; } - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("created master %p", trx->all); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "created master %p", + trx->all); trx->sp_level = trx->all; trans_register_ha(thd, true, tokudb_hton); } DBUG_PRINT("trans", ("starting transaction stmt")); if (trx->stmt) { - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("warning:stmt=%p", trx->stmt); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "warning:stmt=%p", + trx->stmt); } uint32_t txn_begin_flags; if (trx->all == NULL) { @@ -6042,21 +6253,25 @@ int ha_tokudb::create_txn(THD* thd, tokudb_trx_data* trx) { if (txn_begin_flags == 0 && is_autocommit && thd_sql_command(thd) == SQLCOM_SELECT) { txn_begin_flags = DB_TXN_SNAPSHOT; } - if (is_autocommit && thd_sql_command(thd) == SQLCOM_SELECT && !thd->in_sub_stmt && lock.type <= TL_READ_NO_INSERT && !thd->lex->uses_stored_routines()) { + if (is_autocommit && thd_sql_command(thd) == SQLCOM_SELECT && + !thd->in_sub_stmt && lock.type <= TL_READ_NO_INSERT && + !thd->lex->uses_stored_routines()) { txn_begin_flags |= DB_TXN_READ_ONLY; } - } - else { + } else { txn_begin_flags = DB_INHERIT_ISOLATION; } - if ((error = txn_begin(db_env, trx->sp_level, &trx->stmt, txn_begin_flags, thd))) { + error = txn_begin(db_env, trx->sp_level, &trx->stmt, txn_begin_flags, thd); + if (error) { /* We leave the possible master transaction open */ goto cleanup; } trx->sub_sp_level = trx->stmt; - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("created stmt %p sp_level %p", trx->sp_level, trx->stmt); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "created stmt %p sp_level %p", + trx->sp_level, + trx->stmt); reset_stmt_progress(&trx->stmt_progress); trans_register_ha(thd, false, tokudb_hton); cleanup: @@ -6087,26 +6302,40 @@ static const char *lock_type_str(int lock_type) { // error otherwise // int ha_tokudb::external_lock(THD * thd, int lock_type) { - TOKUDB_HANDLER_DBUG_ENTER("cmd %d lock %d %s %s", thd_sql_command(thd), lock_type, lock_type_str(lock_type), share->table_name); - if (!(tokudb_debug & TOKUDB_DEBUG_ENTER) && (tokudb_debug & TOKUDB_DEBUG_LOCK)) { - TOKUDB_HANDLER_TRACE("cmd %d lock %d %s %s", thd_sql_command(thd), lock_type, lock_type_str(lock_type), share->table_name); - } - if (tokudb_debug & TOKUDB_DEBUG_LOCK) { - TOKUDB_HANDLER_TRACE("q %s", thd->query()); - } + TOKUDB_HANDLER_DBUG_ENTER( + "cmd %d lock %d %s %s", + thd_sql_command(thd), + lock_type, + lock_type_str(lock_type), + share->full_table_name()); + if (TOKUDB_UNLIKELY(!TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ENTER) && + TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_LOCK))) { + TOKUDB_HANDLER_TRACE( + "cmd %d lock %d %s %s", + thd_sql_command(thd), + lock_type, + lock_type_str(lock_type), + share->full_table_name()); + } + TOKUDB_HANDLER_TRACE_FOR_FLAGS(TOKUDB_DEBUG_LOCK, "q %s", thd->query()); int error = 0; - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); if (!trx) { error = create_tokudb_trx_data_instance(&trx); if (error) { goto cleanup; } thd_set_ha_data(thd, tokudb_hton, trx); } - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("trx %p %p %p %p %u %u", trx->all, trx->stmt, trx->sp_level, trx->sub_sp_level, - trx->tokudb_lock_count, trx->create_lock_count); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "trx %p %p %p %p %u %u", + trx->all, + trx->stmt, + trx->sp_level, + trx->sub_sp_level, + trx->tokudb_lock_count, + trx->create_lock_count); if (trx->all == NULL) { trx->sp_level = NULL; @@ -6126,19 +6355,11 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) { } transaction = trx->sub_sp_level; trx->tokudb_lock_count++; - } - else { - tokudb_pthread_mutex_lock(&share->mutex); - // hate dealing with comparison of signed vs unsigned, so doing this - if (deleted_rows > added_rows && share->rows < (deleted_rows - added_rows)) { - share->rows = 0; - } - else { - share->rows += (added_rows - deleted_rows); - } - tokudb_pthread_mutex_unlock(&share->mutex); + } else { + share->update_row_count(thd, added_rows, deleted_rows, updated_rows); added_rows = 0; deleted_rows = 0; + updated_rows = 0; share->rows_from_locked_table = 0; if (trx->tokudb_lock_count > 0) { if (--trx->tokudb_lock_count <= trx->create_lock_count) { @@ -6160,8 +6381,7 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) { } } cleanup: - if (tokudb_debug & TOKUDB_DEBUG_LOCK) - TOKUDB_HANDLER_TRACE("error=%d", error); + TOKUDB_HANDLER_TRACE_FOR_FLAGS(TOKUDB_DEBUG_LOCK, "error=%d", error); TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -6170,24 +6390,32 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) { TABLE LOCK is done. Under LOCK TABLES, each used tables will force a call to start_stmt. */ -int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) { - TOKUDB_HANDLER_DBUG_ENTER("cmd %d lock %d %s", thd_sql_command(thd), lock_type, share->table_name); - if (tokudb_debug & TOKUDB_DEBUG_LOCK) { - TOKUDB_HANDLER_TRACE("q %s", thd->query()); - } +int ha_tokudb::start_stmt(THD* thd, thr_lock_type lock_type) { + TOKUDB_HANDLER_DBUG_ENTER( + "cmd %d lock %d %s", + thd_sql_command(thd), + lock_type, + share->full_table_name()); + + TOKUDB_HANDLER_TRACE_FOR_FLAGS(TOKUDB_DEBUG_LOCK, "q %s", thd->query()); int error = 0; - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); if (!trx) { error = create_tokudb_trx_data_instance(&trx); if (error) { goto cleanup; } thd_set_ha_data(thd, tokudb_hton, trx); } - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("trx %p %p %p %p %u %u", trx->all, trx->stmt, trx->sp_level, trx->sub_sp_level, - trx->tokudb_lock_count, trx->create_lock_count); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "trx %p %p %p %p %u %u", + trx->all, + trx->stmt, + trx->sp_level, + trx->sub_sp_level, + trx->tokudb_lock_count, + trx->create_lock_count); /* note that trx->stmt may have been already initialized as start_stmt() @@ -6200,11 +6428,11 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) { goto cleanup; } trx->create_lock_count = trx->tokudb_lock_count; - } - else { - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_HANDLER_TRACE("trx->stmt %p already existed", trx->stmt); - } + } else { + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "trx->stmt %p already existed", + trx->stmt); } if (added_rows > deleted_rows) { share->rows_from_locked_table = added_rows - deleted_rows; @@ -6278,27 +6506,40 @@ uint32_t ha_tokudb::get_cursor_isolation_flags(enum thr_lock_type lock_type, THD time). In the future we will probably try to remove this. */ -THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_lock_type lock_type) { - TOKUDB_HANDLER_DBUG_ENTER("lock_type=%d cmd=%d", lock_type, thd_sql_command(thd)); - if (tokudb_debug & TOKUDB_DEBUG_LOCK) { - TOKUDB_HANDLER_TRACE("lock_type=%d cmd=%d", lock_type, thd_sql_command(thd)); - } +THR_LOCK_DATA* *ha_tokudb::store_lock( + THD* thd, + THR_LOCK_DATA** to, + enum thr_lock_type lock_type) { + + TOKUDB_HANDLER_DBUG_ENTER( + "lock_type=%d cmd=%d", + lock_type, + thd_sql_command(thd)); + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_LOCK, + "lock_type=%d cmd=%d", + lock_type, + thd_sql_command(thd)); if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { enum_sql_command sql_command = (enum_sql_command) thd_sql_command(thd); if (!thd->in_lock_tables) { - if (sql_command == SQLCOM_CREATE_INDEX && get_create_index_online(thd)) { + if (sql_command == SQLCOM_CREATE_INDEX && + tokudb::sysvars::create_index_online(thd)) { // hot indexing - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); if (share->num_DBs == (table->s->keys + tokudb_test(hidden_primary_key))) { lock_type = TL_WRITE_ALLOW_WRITE; } - rw_unlock(&share->num_DBs_lock); - } else if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) && - sql_command != SQLCOM_TRUNCATE && !thd_tablespace_op(thd)) { + share->_num_DBs_lock.unlock(); + } else if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && + lock_type <= TL_WRITE) && + sql_command != SQLCOM_TRUNCATE && + !thd_tablespace_op(thd)) { // allow concurrent writes lock_type = TL_WRITE_ALLOW_WRITE; - } else if (sql_command == SQLCOM_OPTIMIZE && lock_type == TL_READ_NO_INSERT) { + } else if (sql_command == SQLCOM_OPTIMIZE && + lock_type == TL_READ_NO_INSERT) { // hot optimize table lock_type = TL_READ; } @@ -6306,88 +6547,130 @@ THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_l lock.type = lock_type; } *to++ = &lock; - if (tokudb_debug & TOKUDB_DEBUG_LOCK) - TOKUDB_HANDLER_TRACE("lock_type=%d", lock_type); - DBUG_RETURN(to); + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_LOCK, + "lock_type=%d", + lock_type); + TOKUDB_HANDLER_DBUG_RETURN_PTR(to); } -static toku_compression_method get_compression_method(DB *file) { +static toku_compression_method get_compression_method(DB* file) { enum toku_compression_method method; int r = file->get_compression_method(file, &method); - assert(r == 0); + assert_always(r == 0); return method; } #if TOKU_INCLUDE_ROW_TYPE_COMPRESSION -enum row_type ha_tokudb::get_row_type(void) const { +enum row_type ha_tokudb::get_row_type() const { toku_compression_method compression_method = get_compression_method(share->file); return toku_compression_method_to_row_type(compression_method); } #endif static int create_sub_table( - const char *table_name, - DBT* row_descriptor, - DB_TXN* txn, - uint32_t block_size, + const char* table_name, + DBT* row_descriptor, + DB_TXN* txn, + uint32_t block_size, uint32_t read_block_size, toku_compression_method compression_method, bool is_hot_index, - uint32_t fanout - ) -{ + uint32_t fanout) { + TOKUDB_DBUG_ENTER(""); int error; DB *file = NULL; uint32_t create_flags; - - + + error = db_create(&file, db_env, 0); if (error) { DBUG_PRINT("error", ("Got error: %d when creating table", error)); my_errno = error; goto exit; } - + if (block_size != 0) { error = file->set_pagesize(file, block_size); if (error != 0) { - DBUG_PRINT("error", ("Got error: %d when setting block size %u for table '%s'", error, block_size, table_name)); + DBUG_PRINT( + "error", + ("Got error: %d when setting block size %u for table '%s'", + error, + block_size, + table_name)); goto exit; } } if (read_block_size != 0) { error = file->set_readpagesize(file, read_block_size); if (error != 0) { - DBUG_PRINT("error", ("Got error: %d when setting read block size %u for table '%s'", error, read_block_size, table_name)); + DBUG_PRINT( + "error", + ("Got error: %d when setting read block size %u for table '%s'", + error, + read_block_size, + table_name)); goto exit; } } if (fanout != 0) { error = file->set_fanout(file, fanout); if (error != 0) { - DBUG_PRINT("error", ("Got error: %d when setting fanout %u for table '%s'", - error, fanout, table_name)); + DBUG_PRINT( + "error", + ("Got error: %d when setting fanout %u for table '%s'", + error, + fanout, + table_name)); goto exit; } } error = file->set_compression_method(file, compression_method); if (error != 0) { - DBUG_PRINT("error", ("Got error: %d when setting compression type %u for table '%s'", error, compression_method, table_name)); + DBUG_PRINT( + "error", + ("Got error: %d when setting compression type %u for table '%s'", + error, + compression_method, + table_name)); goto exit; } - create_flags = DB_THREAD | DB_CREATE | DB_EXCL | (is_hot_index ? DB_IS_HOT_INDEX : 0); - error = file->open(file, txn, table_name, NULL, DB_BTREE, create_flags, my_umask); + create_flags = + DB_THREAD | DB_CREATE | DB_EXCL | (is_hot_index ? DB_IS_HOT_INDEX : 0); + error = + file->open( + file, + txn, + table_name, + NULL, + DB_BTREE, + create_flags, + my_umask); if (error) { - DBUG_PRINT("error", ("Got error: %d when opening table '%s'", error, table_name)); + DBUG_PRINT( + "error", + ("Got error: %d when opening table '%s'", error, table_name)); goto exit; } - error = file->change_descriptor(file, txn, row_descriptor, (is_hot_index ? DB_IS_HOT_INDEX | DB_UPDATE_CMP_DESCRIPTOR : DB_UPDATE_CMP_DESCRIPTOR)); + error = + file->change_descriptor( + file, + txn, + row_descriptor, + (is_hot_index ? DB_IS_HOT_INDEX | + DB_UPDATE_CMP_DESCRIPTOR : + DB_UPDATE_CMP_DESCRIPTOR)); if (error) { - DBUG_PRINT("error", ("Got error: %d when setting row descriptor for table '%s'", error, table_name)); + DBUG_PRINT( + "error", + ("Got error: %d when setting row descriptor for table '%s'", + error, + table_name)); goto exit; } @@ -6395,7 +6678,7 @@ static int create_sub_table( exit: if (file) { int r = file->close(file, 0); - assert(r==0); + assert_always(r==0); } TOKUDB_DBUG_RETURN(error); } @@ -6413,7 +6696,8 @@ void ha_tokudb::update_create_info(HA_CREATE_INFO* create_info) { // show create table asks us to update this create_info, this makes it // so we'll always show what compression type we're using create_info->row_type = get_row_type(); - if (create_info->row_type == ROW_TYPE_TOKU_ZLIB && THDVAR(ha_thd(), hide_default_row_format) != 0) { + if (create_info->row_type == ROW_TYPE_TOKU_ZLIB && + tokudb::sysvars::hide_default_row_format(ha_thd()) != 0) { create_info->row_type = ROW_TYPE_DEFAULT; } } @@ -6477,27 +6761,43 @@ int ha_tokudb::write_key_name_to_status(DB* status_block, char* key_name, DB_TXN } // -// some tracing moved out of ha_tokudb::create, because ::create was getting cluttered +// some tracing moved out of ha_tokudb::create, because ::create was +// getting cluttered // void ha_tokudb::trace_create_table_info(const char *name, TABLE * form) { uint i; // // tracing information about what type of table we are creating // - if (tokudb_debug & TOKUDB_DEBUG_OPEN) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_OPEN))) { for (i = 0; i < form->s->fields; i++) { Field *field = form->s->field[i]; - TOKUDB_HANDLER_TRACE("field:%d:%s:type=%d:flags=%x", i, field->field_name, field->type(), field->flags); + TOKUDB_HANDLER_TRACE( + "field:%d:%s:type=%d:flags=%x", + i, + field->field_name, + field->type(), + field->flags); } for (i = 0; i < form->s->keys; i++) { KEY *key = &form->s->key_info[i]; - TOKUDB_HANDLER_TRACE("key:%d:%s:%d", i, key->name, get_key_parts(key)); + TOKUDB_HANDLER_TRACE( + "key:%d:%s:%d", + i, + key->name, + get_key_parts(key)); uint p; for (p = 0; p < get_key_parts(key); p++) { - KEY_PART_INFO *key_part = &key->key_part[p]; - Field *field = key_part->field; - TOKUDB_HANDLER_TRACE("key:%d:%d:length=%d:%s:type=%d:flags=%x", - i, p, key_part->length, field->field_name, field->type(), field->flags); + KEY_PART_INFO* key_part = &key->key_part[p]; + Field* field = key_part->field; + TOKUDB_HANDLER_TRACE( + "key:%d:%d:length=%d:%s:type=%d:flags=%x", + i, + p, + key_part->length, + field->field_name, + field->type(), + field->flags); } } } @@ -6505,9 +6805,12 @@ void ha_tokudb::trace_create_table_info(const char *name, TABLE * form) { static uint32_t get_max_desc_size(KEY_AND_COL_INFO* kc_info, TABLE* form) { uint32_t max_row_desc_buff_size; - max_row_desc_buff_size = 2*(form->s->fields * 6)+10; // upper bound of key comparison descriptor - max_row_desc_buff_size += get_max_secondary_key_pack_desc_size(kc_info); // upper bound for sec. key part - max_row_desc_buff_size += get_max_clustering_val_pack_desc_size(form->s); // upper bound for clustering val part + // upper bound of key comparison descriptor + max_row_desc_buff_size = 2*(form->s->fields * 6)+10; + // upper bound for sec. key part + max_row_desc_buff_size += get_max_secondary_key_pack_desc_size(kc_info); + // upper bound for clustering val part + max_row_desc_buff_size += get_max_clustering_val_pack_desc_size(form->s); return max_row_desc_buff_size; } @@ -6519,9 +6822,8 @@ static uint32_t create_secondary_key_descriptor( TABLE* form, uint primary_key, uint32_t keynr, - KEY_AND_COL_INFO* kc_info - ) -{ + KEY_AND_COL_INFO* kc_info) { + uchar* ptr = NULL; ptr = buf; @@ -6560,23 +6862,25 @@ static uint32_t create_secondary_key_descriptor( // creates dictionary for secondary index, with key description key_info, all using txn // int ha_tokudb::create_secondary_dictionary( - const char* name, TABLE* form, - KEY* key_info, - DB_TXN* txn, - KEY_AND_COL_INFO* kc_info, + const char* name, + TABLE* form, + KEY* key_info, + DB_TXN* txn, + KEY_AND_COL_INFO* kc_info, uint32_t keynr, bool is_hot_index, - toku_compression_method compression_method - ) -{ + toku_compression_method compression_method) { + int error; DBT row_descriptor; uchar* row_desc_buff = NULL; char* newname = NULL; + size_t newname_len = 0; KEY* prim_key = NULL; char dict_name[MAX_DICT_NAME_LEN]; uint32_t max_row_desc_buff_size; - uint hpk= (form->s->primary_key >= MAX_KEY) ? TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH : 0; + uint hpk= (form->s->primary_key >= MAX_KEY) ? + TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH : 0; uint32_t block_size; uint32_t read_block_size; uint32_t fanout; @@ -6586,14 +6890,23 @@ int ha_tokudb::create_secondary_dictionary( max_row_desc_buff_size = get_max_desc_size(kc_info,form); - row_desc_buff = (uchar *)tokudb_my_malloc(max_row_desc_buff_size, MYF(MY_WME)); - if (row_desc_buff == NULL){ error = ENOMEM; goto cleanup;} + row_desc_buff = (uchar*)tokudb::memory::malloc( + max_row_desc_buff_size, + MYF(MY_WME)); + if (row_desc_buff == NULL) { + error = ENOMEM; + goto cleanup; + } - newname = (char *)tokudb_my_malloc(get_max_dict_name_path_length(name),MYF(MY_WME)); - if (newname == NULL){ error = ENOMEM; goto cleanup;} + newname_len = get_max_dict_name_path_length(name); + newname = (char*)tokudb::memory::malloc(newname_len, MYF(MY_WME)); + if (newname == NULL) { + error = ENOMEM; + goto cleanup; + } sprintf(dict_name, "key-%s", key_info->name); - make_name(newname, name, dict_name); + make_name(newname, newname_len, name, dict_name); prim_key = (hpk) ? NULL : &form->s->key_info[primary_key]; @@ -6612,20 +6925,25 @@ int ha_tokudb::create_secondary_dictionary( form, primary_key, keynr, - kc_info - ); - assert(row_descriptor.size <= max_row_desc_buff_size); + kc_info); + assert_always(row_descriptor.size <= max_row_desc_buff_size); - block_size = get_tokudb_block_size(thd); - read_block_size = get_tokudb_read_block_size(thd); - fanout = get_tokudb_fanout(thd); + block_size = tokudb::sysvars::block_size(thd); + read_block_size = tokudb::sysvars::read_block_size(thd); + fanout = tokudb::sysvars::fanout(thd); - error = create_sub_table(newname, &row_descriptor, txn, block_size, - read_block_size, compression_method, is_hot_index, - fanout); + error = create_sub_table( + newname, + &row_descriptor, + txn, + block_size, + read_block_size, + compression_method, + is_hot_index, + fanout); cleanup: - tokudb_my_free(newname); - tokudb_my_free(row_desc_buff); + tokudb::memory::free(newname); + tokudb::memory::free(row_desc_buff); return error; } @@ -6636,21 +6954,17 @@ static uint32_t create_main_key_descriptor( uint hpk, uint primary_key, TABLE* form, - KEY_AND_COL_INFO* kc_info - ) -{ + KEY_AND_COL_INFO* kc_info) { + uchar* ptr = buf; ptr += create_toku_key_descriptor( ptr, hpk, prim_key, false, - NULL - ); + NULL); - ptr += create_toku_main_key_pack_descriptor( - ptr - ); + ptr += create_toku_main_key_pack_descriptor(ptr); ptr += create_toku_clustering_val_pack_descriptor( ptr, @@ -6658,8 +6972,7 @@ static uint32_t create_main_key_descriptor( form->s, kc_info, primary_key, - false - ); + false); return ptr - buf; } @@ -6667,14 +6980,21 @@ static uint32_t create_main_key_descriptor( // create and close the main dictionarr with name of "name" using table form, all within // transaction txn. // -int ha_tokudb::create_main_dictionary(const char* name, TABLE* form, DB_TXN* txn, KEY_AND_COL_INFO* kc_info, toku_compression_method compression_method) { +int ha_tokudb::create_main_dictionary( + const char* name, + TABLE* form, + DB_TXN* txn, + KEY_AND_COL_INFO* kc_info, + toku_compression_method compression_method) { + int error; DBT row_descriptor; uchar* row_desc_buff = NULL; char* newname = NULL; + size_t newname_len = 0; KEY* prim_key = NULL; uint32_t max_row_desc_buff_size; - uint hpk= (form->s->primary_key >= MAX_KEY) ? TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH : 0; + uint hpk = (form->s->primary_key >= MAX_KEY) ? TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH : 0; uint32_t block_size; uint32_t read_block_size; uint32_t fanout; @@ -6683,13 +7003,22 @@ int ha_tokudb::create_main_dictionary(const char* name, TABLE* form, DB_TXN* txn memset(&row_descriptor, 0, sizeof(row_descriptor)); max_row_desc_buff_size = get_max_desc_size(kc_info, form); - row_desc_buff = (uchar *)tokudb_my_malloc(max_row_desc_buff_size, MYF(MY_WME)); - if (row_desc_buff == NULL){ error = ENOMEM; goto cleanup;} + row_desc_buff = (uchar*)tokudb::memory::malloc( + max_row_desc_buff_size, + MYF(MY_WME)); + if (row_desc_buff == NULL) { + error = ENOMEM; + goto cleanup; + } - newname = (char *)tokudb_my_malloc(get_max_dict_name_path_length(name),MYF(MY_WME)); - if (newname == NULL){ error = ENOMEM; goto cleanup;} + newname_len = get_max_dict_name_path_length(name); + newname = (char*)tokudb::memory::malloc(newname_len, MYF(MY_WME)); + if (newname == NULL) { + error = ENOMEM; + goto cleanup; + } - make_name(newname, name, "main"); + make_name(newname, newname_len, name, "main"); prim_key = (hpk) ? NULL : &form->s->key_info[primary_key]; @@ -6706,21 +7035,26 @@ int ha_tokudb::create_main_dictionary(const char* name, TABLE* form, DB_TXN* txn hpk, primary_key, form, - kc_info - ); - assert(row_descriptor.size <= max_row_desc_buff_size); + kc_info); + assert_always(row_descriptor.size <= max_row_desc_buff_size); - block_size = get_tokudb_block_size(thd); - read_block_size = get_tokudb_read_block_size(thd); - fanout = get_tokudb_fanout(thd); + block_size = tokudb::sysvars::block_size(thd); + read_block_size = tokudb::sysvars::read_block_size(thd); + fanout = tokudb::sysvars::fanout(thd); /* Create the main table that will hold the real rows */ - error = create_sub_table(newname, &row_descriptor, txn, block_size, - read_block_size, compression_method, false, - fanout); + error = create_sub_table( + newname, + &row_descriptor, + txn, + block_size, + read_block_size, + compression_method, + false, + fanout); cleanup: - tokudb_my_free(newname); - tokudb_my_free(row_desc_buff); + tokudb::memory::free(newname); + tokudb::memory::free(row_desc_buff); return error; } @@ -6734,7 +7068,11 @@ int ha_tokudb::create_main_dictionary(const char* name, TABLE* form, DB_TXN* txn // 0 on success // error otherwise // -int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_info) { +int ha_tokudb::create( + const char* name, + TABLE* form, + HA_CREATE_INFO* create_info) { + TOKUDB_HANDLER_DBUG_ENTER("%s", name); int error; @@ -6744,6 +7082,7 @@ int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_in DB_TXN* txn = NULL; bool do_commit = false; char* newname = NULL; + size_t newname_len = 0; KEY_AND_COL_INFO kc_info; tokudb_trx_data *trx = NULL; THD* thd = ha_thd(); @@ -6759,15 +7098,18 @@ int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_in #endif #if TOKU_INCLUDE_OPTION_STRUCTS - const srv_row_format_t row_format = (srv_row_format_t) form->s->option_struct->row_format; + const tokudb::sysvars::format_t row_format = + (tokudb::sysvars::row_format_t)form->s->option_struct->row_format; #else - const srv_row_format_t row_format = (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) + const tokudb::sysvars::row_format_t row_format = + (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) ? row_type_to_row_format(create_info->row_type) - : get_row_format(thd); + : tokudb::sysvars::row_format(thd); #endif - const toku_compression_method compression_method = row_format_to_toku_compression_method(row_format); + const toku_compression_method compression_method = + row_format_to_toku_compression_method(row_format); - bool create_from_engine= (create_info->table_options & HA_OPTION_CREATE_FROM_ENGINE); + bool create_from_engine = (create_info->table_options & HA_OPTION_CREATE_FROM_ENGINE); if (create_from_engine) { // table already exists, nothing to do error = 0; @@ -6792,17 +7134,23 @@ int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_in } } - newname = (char *)tokudb_my_malloc(get_max_dict_name_path_length(name),MYF(MY_WME)); - if (newname == NULL){ error = ENOMEM; goto cleanup;} + newname_len = get_max_dict_name_path_length(name); + newname = (char*)tokudb::memory::malloc(newname_len, MYF(MY_WME)); + if (newname == NULL) { + error = ENOMEM; + goto cleanup; + } trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton); - if (trx && trx->sub_sp_level && thd_sql_command(thd) == SQLCOM_CREATE_TABLE) { + if (trx && trx->sub_sp_level && + thd_sql_command(thd) == SQLCOM_CREATE_TABLE) { txn = trx->sub_sp_level; - } - else { + } else { do_commit = true; error = txn_begin(db_env, 0, &txn, 0, thd); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } } primary_key = form->s->primary_key; @@ -6815,45 +7163,76 @@ int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_in trace_create_table_info(name,form); /* Create status.tokudb and save relevant metadata */ - make_name(newname, name, "status"); + make_name(newname, newname_len, name, "status"); - error = tokudb::create_status(db_env, &status_block, newname, txn); + error = tokudb::metadata::create(db_env, &status_block, newname, txn); if (error) { goto cleanup; } version = HA_TOKU_VERSION; - error = write_to_status(status_block, hatoku_new_version,&version,sizeof(version), txn); - if (error) { goto cleanup; } + error = write_to_status( + status_block, + hatoku_new_version, + &version, + sizeof(version), + txn); + if (error) { + goto cleanup; + } capabilities = HA_TOKU_CAP; - error = write_to_status(status_block, hatoku_capabilities,&capabilities,sizeof(capabilities), txn); - if (error) { goto cleanup; } + error = write_to_status( + status_block, + hatoku_capabilities, + &capabilities, + sizeof(capabilities), + txn); + if (error) { + goto cleanup; + } - error = write_auto_inc_create(status_block, create_info->auto_increment_value, txn); - if (error) { goto cleanup; } + error = write_auto_inc_create( + status_block, + create_info->auto_increment_value, + txn); + if (error) { + goto cleanup; + } #if WITH_PARTITION_STORAGE_ENGINE if (TOKU_PARTITION_WRITE_FRM_DATA || form->part_info == NULL) { error = write_frm_data(status_block, txn, form->s->path.str); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } } #else error = write_frm_data(status_block, txn, form->s->path.str); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } #endif error = allocate_key_and_col_info(form->s, &kc_info); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } error = initialize_key_and_col_info( - form->s, + form->s, form, &kc_info, hidden_primary_key, - primary_key - ); - if (error) { goto cleanup; } + primary_key); + if (error) { + goto cleanup; + } - error = create_main_dictionary(name, form, txn, &kc_info, compression_method); + error = create_main_dictionary( + name, + form, + txn, + &kc_info, + compression_method); if (error) { goto cleanup; } @@ -6861,32 +7240,44 @@ int ha_tokudb::create(const char *name, TABLE * form, HA_CREATE_INFO * create_in for (uint i = 0; i < form->s->keys; i++) { if (i != primary_key) { - error = create_secondary_dictionary(name, form, &form->key_info[i], txn, &kc_info, i, false, compression_method); + error = create_secondary_dictionary( + name, + form, + &form->key_info[i], + txn, + &kc_info, + i, + false, + compression_method); if (error) { goto cleanup; } - error = write_key_name_to_status(status_block, form->s->key_info[i].name, txn); - if (error) { goto cleanup; } + error = write_key_name_to_status( + status_block, + form->s->key_info[i].name, + txn); + if (error) { + goto cleanup; + } } } error = 0; cleanup: if (status_block != NULL) { - int r = tokudb::close_status(&status_block); - assert(r==0); + int r = tokudb::metadata::close(&status_block); + assert_always(r==0); } free_key_and_col_info(&kc_info); if (do_commit && txn) { if (error) { abort_txn(txn); - } - else { + } else { commit_txn(txn,0); } } - tokudb_my_free(newname); + tokudb::memory::free(newname); TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -6909,27 +7300,36 @@ int ha_tokudb::discard_or_import_tablespace(my_bool discard) { // is_key specifies if it is a secondary index (and hence a "key-" needs to be prepended) or // if it is not a secondary index // -int ha_tokudb::delete_or_rename_dictionary( const char* from_name, const char* to_name, const char* secondary_name, bool is_key, DB_TXN* txn, bool is_delete) { +int ha_tokudb::delete_or_rename_dictionary( + const char* from_name, + const char* to_name, + const char* secondary_name, + bool is_key, + DB_TXN* txn, + bool is_delete) { + int error; char dict_name[MAX_DICT_NAME_LEN]; char* new_from_name = NULL; + size_t new_from_name_len = 0; char* new_to_name = NULL; - assert(txn); + size_t new_to_name_len = 0; + assert_always(txn); - new_from_name = (char *)tokudb_my_malloc( - get_max_dict_name_path_length(from_name), - MYF(MY_WME) - ); + new_from_name_len = get_max_dict_name_path_length(from_name); + new_from_name = (char*)tokudb::memory::malloc( + new_from_name_len, + MYF(MY_WME)); if (new_from_name == NULL) { error = ENOMEM; goto cleanup; } if (!is_delete) { - assert(to_name); - new_to_name = (char *)tokudb_my_malloc( - get_max_dict_name_path_length(to_name), - MYF(MY_WME) - ); + assert_always(to_name); + new_to_name_len = get_max_dict_name_path_length(to_name); + new_to_name = (char*)tokudb::memory::malloc( + new_to_name_len, + MYF(MY_WME)); if (new_to_name == NULL) { error = ENOMEM; goto cleanup; @@ -6938,32 +7338,37 @@ int ha_tokudb::delete_or_rename_dictionary( const char* from_name, const char* t if (is_key) { sprintf(dict_name, "key-%s", secondary_name); - make_name(new_from_name, from_name, dict_name); - } - else { - make_name(new_from_name, from_name, secondary_name); + make_name(new_from_name, new_from_name_len, from_name, dict_name); + } else { + make_name(new_from_name, new_from_name_len, from_name, secondary_name); } if (!is_delete) { if (is_key) { sprintf(dict_name, "key-%s", secondary_name); - make_name(new_to_name, to_name, dict_name); - } - else { - make_name(new_to_name, to_name, secondary_name); + make_name(new_to_name, new_to_name_len, to_name, dict_name); + } else { + make_name(new_to_name, new_to_name_len, to_name, secondary_name); } } if (is_delete) { error = db_env->dbremove(db_env, txn, new_from_name, NULL, 0); + } else { + error = db_env->dbrename( + db_env, + txn, + new_from_name, + NULL, + new_to_name, + 0); } - else { - error = db_env->dbrename(db_env, txn, new_from_name, NULL, new_to_name, 0); + if (error) { + goto cleanup; } - if (error) { goto cleanup; } cleanup: - tokudb_my_free(new_from_name); - tokudb_my_free(new_to_name); + tokudb::memory::free(new_from_name); + tokudb::memory::free(new_to_name); return error; } @@ -7029,12 +7434,12 @@ int ha_tokudb::delete_or_rename_table (const char* from_name, const char* to_nam if (error) { goto cleanup; } error = status_cursor->c_close(status_cursor); - assert(error==0); + assert_always(error==0); status_cursor = NULL; if (error) { goto cleanup; } error = status_db->close(status_db, 0); - assert(error == 0); + assert_always(error == 0); status_db = NULL; // @@ -7047,11 +7452,11 @@ int ha_tokudb::delete_or_rename_table (const char* from_name, const char* to_nam cleanup: if (status_cursor) { int r = status_cursor->c_close(status_cursor); - assert(r==0); + assert_always(r==0); } if (status_db) { int r = status_db->close(status_db, 0); - assert(r==0); + assert_always(r==0); } if (txn) { if (error) { @@ -7075,12 +7480,25 @@ int ha_tokudb::delete_or_rename_table (const char* from_name, const char* to_nam // int ha_tokudb::delete_table(const char *name) { TOKUDB_HANDLER_DBUG_ENTER("%s", name); + TOKUDB_SHARE* share = TOKUDB_SHARE::get_share(name, NULL, NULL, false); + if (share) { + share->unlock(); + share->release(); + // this should be enough to handle locking as the higher level MDL + // on this table should prevent any new analyze tasks. + share->cancel_background_jobs(); + TOKUDB_SHARE::drop_share(share); + } + int error; error = delete_or_rename_table(name, NULL, true); - if (error == DB_LOCK_NOTGRANTED && ((tokudb_debug & TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0)) { - sql_print_error("Could not delete table %s because \ -another transaction has accessed the table. \ -To drop the table, make sure no transactions touch the table.", name); + if (TOKUDB_LIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0) && + error == DB_LOCK_NOTGRANTED) { + sql_print_error( + "Could not delete table %s because another transaction has " + "accessed the table. To drop the table, make sure no " + "transactions touch the table.", + name); } TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -7097,12 +7515,25 @@ To drop the table, make sure no transactions touch the table.", name); // int ha_tokudb::rename_table(const char *from, const char *to) { TOKUDB_HANDLER_DBUG_ENTER("%s %s", from, to); + TOKUDB_SHARE* share = TOKUDB_SHARE::get_share(from, NULL, NULL, false); + if (share) { + share->unlock(); + share->release(); + // this should be enough to handle locking as the higher level MDL + // on this table should prevent any new analyze tasks. + share->cancel_background_jobs(); + TOKUDB_SHARE::drop_share(share); + } int error; error = delete_or_rename_table(from, to, false); - if (error == DB_LOCK_NOTGRANTED && ((tokudb_debug & TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0)) { - sql_print_error("Could not rename table from %s to %s because \ -another transaction has accessed the table. \ -To rename the table, make sure no transactions touch the table.", from, to); + if (TOKUDB_LIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0) && + error == DB_LOCK_NOTGRANTED) { + sql_print_error( + "Could not rename table from %s to %s because another transaction " + "has accessed the table. To rename the table, make sure no " + "transactions touch the table.", + from, + to); } TOKUDB_HANDLER_DBUG_RETURN(error); } @@ -7117,9 +7548,11 @@ To rename the table, make sure no transactions touch the table.", from, to); double ha_tokudb::scan_time() { TOKUDB_HANDLER_DBUG_ENTER(""); double ret_val = (double)stats.records / 3; - if (tokudb_debug & TOKUDB_DEBUG_RETURN) { - TOKUDB_HANDLER_TRACE("return %" PRIu64 " %f", (uint64_t) stats.records, ret_val); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_RETURN, + "return %" PRIu64 " %f", + (uint64_t)stats.records, + ret_val); DBUG_RETURN(ret_val); } @@ -7143,10 +7576,7 @@ double ha_tokudb::keyread_time(uint index, uint ranges, ha_rows rows) (table->key_info[index].key_length + ref_length) + 1); ret_val = (rows + keys_per_block - 1)/ keys_per_block; - if (tokudb_debug & TOKUDB_DEBUG_RETURN) { - TOKUDB_HANDLER_TRACE("return %f", ret_val); - } - DBUG_RETURN(ret_val); + TOKUDB_HANDLER_DBUG_RETURN_DOUBLE(ret_val); } // @@ -7208,19 +7638,13 @@ double ha_tokudb::read_time( ret_val = is_clustering ? ret_val + 0.00001 : ret_val; cleanup: - if (tokudb_debug & TOKUDB_DEBUG_RETURN) { - TOKUDB_HANDLER_TRACE("return %f", ret_val); - } - DBUG_RETURN(ret_val); + TOKUDB_HANDLER_DBUG_RETURN_DOUBLE(ret_val); } double ha_tokudb::index_only_read_time(uint keynr, double records) { TOKUDB_HANDLER_DBUG_ENTER("%u %f", keynr, records); double ret_val = keyread_time(keynr, 1, (ha_rows)records); - if (tokudb_debug & TOKUDB_DEBUG_RETURN) { - TOKUDB_HANDLER_TRACE("return %f", ret_val); - } - DBUG_RETURN(ret_val); + TOKUDB_HANDLER_DBUG_RETURN_DOUBLE(ret_val); } // @@ -7293,9 +7717,11 @@ ha_rows ha_tokudb::records_in_range(uint keynr, key_range* start_key, key_range* ret_val = (ha_rows) (rows <= 1 ? 1 : rows); cleanup: - if (tokudb_debug & TOKUDB_DEBUG_RETURN) { - TOKUDB_HANDLER_TRACE("return %" PRIu64 " %" PRIu64, (uint64_t) ret_val, rows); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_RETURN, + "return %" PRIu64 " %" PRIu64, + (uint64_t)ret_val, + rows); DBUG_RETURN(ret_val); } @@ -7351,24 +7777,30 @@ void ha_tokudb::init_auto_increment() { commit_txn(txn, 0); } - if (tokudb_debug & TOKUDB_DEBUG_AUTO_INCREMENT) { - TOKUDB_HANDLER_TRACE("init auto increment:%lld", share->last_auto_increment); - } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_AUTO_INCREMENT, + "init auto increment:%lld", + share->last_auto_increment); } -void ha_tokudb::get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong * first_value, ulonglong * nb_reserved_values) { +void ha_tokudb::get_auto_increment( + ulonglong offset, + ulonglong increment, + ulonglong nb_desired_values, + ulonglong* first_value, + ulonglong* nb_reserved_values) { + TOKUDB_HANDLER_DBUG_ENTER(""); ulonglong nr; bool over; - tokudb_pthread_mutex_lock(&share->mutex); + share->lock(); if (share->auto_inc_create_value > share->last_auto_increment) { nr = share->auto_inc_create_value; over = false; share->last_auto_increment = share->auto_inc_create_value; - } - else { + } else { nr = share->last_auto_increment + increment; over = nr < share->last_auto_increment; if (over) @@ -7378,19 +7810,23 @@ void ha_tokudb::get_auto_increment(ulonglong offset, ulonglong increment, ulongl share->last_auto_increment = nr + (nb_desired_values - 1)*increment; if (delay_updating_ai_metadata) { ai_metadata_update_required = true; - } - else { - update_max_auto_inc(share->status_block, share->last_auto_increment); - } - } - - if (tokudb_debug & TOKUDB_DEBUG_AUTO_INCREMENT) { - TOKUDB_HANDLER_TRACE("get_auto_increment(%lld,%lld,%lld):got:%lld:%lld", - offset, increment, nb_desired_values, nr, nb_desired_values); - } + } else { + update_max_auto_inc( + share->status_block, + share->last_auto_increment); + } + } + TOKUDB_HANDLER_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_AUTO_INCREMENT, + "get_auto_increment(%lld,%lld,%lld): got:%lld:%lld", + offset, + increment, + nb_desired_values, + nr, + nb_desired_values); *first_value = nr; *nb_reserved_values = nb_desired_values; - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); TOKUDB_HANDLER_DBUG_VOID_RETURN; } @@ -7419,16 +7855,15 @@ bool ha_tokudb::is_auto_inc_singleton(){ // 0 on success, error otherwise // int ha_tokudb::tokudb_add_index( - TABLE *table_arg, - KEY *key_info, - uint num_of_keys, - DB_TXN* txn, + TABLE* table_arg, + KEY* key_info, + uint num_of_keys, + DB_TXN* txn, bool* inc_num_DBs, - bool* modified_DBs - ) -{ + bool* modified_DBs) { + TOKUDB_HANDLER_DBUG_ENTER(""); - assert(txn); + assert_always(txn); int error; uint curr_index = 0; @@ -7438,7 +7873,7 @@ int ha_tokudb::tokudb_add_index( THD* thd = ha_thd(); DB_LOADER* loader = NULL; DB_INDEXER* indexer = NULL; - bool loader_save_space = get_load_save_space(thd); + bool loader_save_space = tokudb::sysvars::load_save_space(thd); bool use_hot_index = (lock.type == TL_WRITE_ALLOW_WRITE); uint32_t loader_flags = loader_save_space ? LOADER_COMPRESS_INTERMEDIATES : 0; uint32_t indexer_flags = 0; @@ -7468,14 +7903,17 @@ int ha_tokudb::tokudb_add_index( // // get the row type to use for the indexes we're adding // - toku_compression_method compression_method = get_compression_method(share->file); + toku_compression_method compression_method = + get_compression_method(share->file); // // status message to be shown in "show process list" // const char *orig_proc_info = tokudb_thd_get_proc_info(thd); - char status_msg[MAX_ALIAS_NAME + 200]; //buffer of 200 should be a good upper bound. - ulonglong num_processed = 0; //variable that stores number of elements inserted thus far + // buffer of 200 should be a good upper bound. + char status_msg[MAX_ALIAS_NAME + 200]; + // variable that stores number of elements inserted thus far + ulonglong num_processed = 0; thd_proc_info(thd, "Adding indexes"); // @@ -7500,13 +7938,15 @@ int ha_tokudb::tokudb_add_index( } } - rw_wrlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_write(); rw_lock_taken = true; // // open all the DB files and set the appropriate variables in share // they go to the end of share->key_file // - creating_hot_index = use_hot_index && num_of_keys == 1 && (key_info[0].flags & HA_NOSAME) == 0; + creating_hot_index = + use_hot_index && num_of_keys == 1 && + (key_info[0].flags & HA_NOSAME) == 0; if (use_hot_index && (share->num_DBs > curr_num_DBs)) { // // already have hot index in progress, get out @@ -7522,35 +7962,47 @@ int ha_tokudb::tokudb_add_index( &share->kc_info.key_filters[curr_index], &key_info[i], table_arg, - false - ); + false); if (!hidden_primary_key) { set_key_filter( &share->kc_info.key_filters[curr_index], &table_arg->key_info[primary_key], table_arg, - false - ); + false); } - error = initialize_col_pack_info(&share->kc_info,table_arg->s,curr_index); + error = initialize_col_pack_info( + &share->kc_info, + table_arg->s, + curr_index); if (error) { goto cleanup; } } - error = create_secondary_dictionary(share->table_name, table_arg, &key_info[i], txn, &share->kc_info, curr_index, creating_hot_index, compression_method); - if (error) { goto cleanup; } + error = create_secondary_dictionary( + share->full_table_name(), + table_arg, + &key_info[i], + txn, + &share->kc_info, + curr_index, + creating_hot_index, + compression_method); + if (error) { + goto cleanup; + } error = open_secondary_dictionary( - &share->key_file[curr_index], + &share->key_file[curr_index], &key_info[i], - share->table_name, + share->full_table_name(), false, - txn - ); - if (error) { goto cleanup; } + txn); + if (error) { + goto cleanup; + } } if (creating_hot_index) { @@ -7564,17 +8016,22 @@ int ha_tokudb::tokudb_add_index( num_of_keys, &share->key_file[curr_num_DBs], mult_db_flags, - indexer_flags - ); - if (error) { goto cleanup; } + indexer_flags); + if (error) { + goto cleanup; + } error = indexer->set_poll_function(indexer, ai_poll_fun, &lc); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } error = indexer->set_error_callback(indexer, loader_ai_err_fun, &lc); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); rw_lock_taken = false; #ifdef HA_TOKUDB_HAS_THD_PROGRESS @@ -7585,17 +8042,20 @@ int ha_tokudb::tokudb_add_index( error = indexer->build(indexer); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } - rw_wrlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_write(); error = indexer->close(indexer); - rw_unlock(&share->num_DBs_lock); - if (error) { goto cleanup; } + share->_num_DBs_lock.unlock(); + if (error) { + goto cleanup; + } indexer = NULL; - } - else { + } else { DBUG_ASSERT(table->mdl_ticket->get_type() >= MDL_SHARED_NO_WRITE); - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); rw_lock_taken = false; prelocked_right_range_size = 0; prelocked_left_range_size = 0; @@ -7608,27 +8068,37 @@ int ha_tokudb::tokudb_add_index( bf_info.key_to_compare = NULL; error = db_env->create_loader( - db_env, - txn, - &loader, + db_env, + txn, + &loader, NULL, // no src_db needed - num_of_keys, - &share->key_file[curr_num_DBs], + num_of_keys, + &share->key_file[curr_num_DBs], mult_put_flags, mult_dbt_flags, - loader_flags - ); - if (error) { goto cleanup; } + loader_flags); + if (error) { + goto cleanup; + } error = loader->set_poll_function(loader, loader_poll_fun, &lc); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } error = loader->set_error_callback(loader, loader_ai_err_fun, &lc); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } // // scan primary table, create each secondary key, add to each DB // - if ((error = share->file->cursor(share->file, txn, &tmp_cursor, DB_SERIALIZABLE))) { + error = share->file->cursor( + share->file, + txn, + &tmp_cursor, + DB_SERIALIZABLE); + if (error) { tmp_cursor = NULL; // Safety goto cleanup; } @@ -7643,16 +8113,21 @@ int ha_tokudb::tokudb_add_index( share->file->dbt_neg_infty(), share->file->dbt_pos_infty(), true, - 0 - ); - if (error) { goto cleanup; } + 0); + if (error) { + goto cleanup; + } // set the bulk fetch iteration to its max so that adding an // index fills the bulk fetch buffer every time. we do not // want it to grow exponentially fast. rows_fetched_using_bulk_fetch = 0; bulk_fetch_iteration = HA_TOKU_BULK_FETCH_ITERATION_MAX; - cursor_ret_val = tmp_cursor->c_getf_next(tmp_cursor, DB_PRELOCKED,smart_dbt_bf_callback, &bf_info); + cursor_ret_val = tmp_cursor->c_getf_next( + tmp_cursor, + DB_PRELOCKED, + smart_dbt_bf_callback, + &bf_info); #ifdef HA_TOKUDB_HAS_THD_PROGRESS // initialize a two phase progress report. @@ -7660,21 +8135,30 @@ int ha_tokudb::tokudb_add_index( thd_progress_init(thd, 2); #endif - while (cursor_ret_val != DB_NOTFOUND || ((bytes_used_in_range_query_buff - curr_range_query_buff_offset) > 0)) { - if ((bytes_used_in_range_query_buff - curr_range_query_buff_offset) == 0) { + while (cursor_ret_val != DB_NOTFOUND || + ((bytes_used_in_range_query_buff - + curr_range_query_buff_offset) > 0)) { + if ((bytes_used_in_range_query_buff - + curr_range_query_buff_offset) == 0) { invalidate_bulk_fetch(); // reset the buffers - cursor_ret_val = tmp_cursor->c_getf_next(tmp_cursor, DB_PRELOCKED, smart_dbt_bf_callback, &bf_info); + cursor_ret_val = tmp_cursor->c_getf_next( + tmp_cursor, + DB_PRELOCKED, + smart_dbt_bf_callback, + &bf_info); if (cursor_ret_val != DB_NOTFOUND && cursor_ret_val != 0) { error = cursor_ret_val; goto cleanup; } } - // do this check in case the the c_getf_next did not put anything into the buffer because - // there was no more data - if ((bytes_used_in_range_query_buff - curr_range_query_buff_offset) == 0) { + // do this check in case the the c_getf_next did not put anything + // into the buffer because there was no more data + if ((bytes_used_in_range_query_buff - + curr_range_query_buff_offset) == 0) { break; } - // at this point, we know the range query buffer has at least one key/val pair + // at this point, we know the range query buffer has at least one + // key/val pair uchar* curr_pos = range_query_buff+curr_range_query_buff_offset; uint32_t key_size = *(uint32_t *)curr_pos; @@ -7694,17 +8178,26 @@ int ha_tokudb::tokudb_add_index( curr_range_query_buff_offset = curr_pos - range_query_buff; error = loader->put(loader, &curr_pk_key, &curr_pk_val); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } num_processed++; if ((num_processed % 1000) == 0) { - sprintf(status_msg, "Adding indexes: Fetched %llu of about %llu rows, loading of data still remains.", - num_processed, (long long unsigned) share->rows); + sprintf( + status_msg, + "Adding indexes: Fetched %llu of about %llu rows, loading " + "of data still remains.", + num_processed, + (long long unsigned)share->row_count()); thd_proc_info(thd, status_msg); #ifdef HA_TOKUDB_HAS_THD_PROGRESS - thd_progress_report(thd, num_processed, (long long unsigned) share->rows); + thd_progress_report( + thd, + num_processed, + (long long unsigned)share->rows); #endif if (thd_killed(thd)) { @@ -7714,7 +8207,7 @@ int ha_tokudb::tokudb_add_index( } } error = tmp_cursor->c_close(tmp_cursor); - assert(error==0); + assert_always(error==0); tmp_cursor = NULL; #ifdef HA_TOKUDB_HAS_THD_PROGRESS @@ -7732,9 +8225,14 @@ int ha_tokudb::tokudb_add_index( for (uint i = 0; i < num_of_keys; i++, curr_index++) { if (key_info[i].flags & HA_NOSAME) { bool is_unique; - error = is_index_unique(&is_unique, txn, share->key_file[curr_index], &key_info[i], - creating_hot_index ? 0 : DB_PRELOCKED_WRITE); - if (error) goto cleanup; + error = is_index_unique( + &is_unique, + txn, + share->key_file[curr_index], + &key_info[i], + creating_hot_index ? 0 : DB_PRELOCKED_WRITE); + if (error) + goto cleanup; if (!is_unique) { error = HA_ERR_FOUND_DUPP_KEY; last_dup_key = i; @@ -7743,22 +8241,20 @@ int ha_tokudb::tokudb_add_index( } } + share->lock(); // // We have an accurate row count, might as well update share->rows // if(!creating_hot_index) { - tokudb_pthread_mutex_lock(&share->mutex); - share->rows = num_processed; - tokudb_pthread_mutex_unlock(&share->mutex); + share->set_row_count(num_processed, true); } // // now write stuff to status.tokudb // - tokudb_pthread_mutex_lock(&share->mutex); for (uint i = 0; i < num_of_keys; i++) { write_key_name_to_status(share->status_block, key_info[i].name, txn); } - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); error = 0; cleanup: @@ -7766,12 +8262,12 @@ int ha_tokudb::tokudb_add_index( thd_progress_end(thd); #endif if (rw_lock_taken) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); rw_lock_taken = false; } if (tmp_cursor) { int r = tmp_cursor->c_close(tmp_cursor); - assert(r==0); + assert_always(r==0); tmp_cursor = NULL; } if (loader != NULL) { @@ -7782,14 +8278,17 @@ int ha_tokudb::tokudb_add_index( if (indexer != NULL) { sprintf(status_msg, "aborting creation of indexes."); thd_proc_info(thd, status_msg); - rw_wrlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_write(); indexer->abort(indexer); - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } - if (error == DB_LOCK_NOTGRANTED && ((tokudb_debug & TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0)) { - sql_print_error("Could not add indexes to table %s because \ -another transaction has accessed the table. \ -To add indexes, make sure no transactions touch the table.", share->table_name); + if (TOKUDB_LIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0) && + error == DB_LOCK_NOTGRANTED) { + sql_print_error( + "Could not add indexes to table %s because another transaction has " + "accessed the table. To add indexes, make sure no transactions " + "touch the table.", + share->full_table_name()); } thd_proc_info(thd, orig_proc_info); TOKUDB_HANDLER_DBUG_RETURN(error ? error : loader_error); @@ -7799,7 +8298,12 @@ To add indexes, make sure no transactions touch the table.", share->table_name); // Internal function called by ha_tokudb::add_index and ha_tokudb::alter_table_phase2 // Closes added indexes in case of error in error path of add_index and alter_table_phase2 // -void ha_tokudb::restore_add_index(TABLE* table_arg, uint num_of_keys, bool incremented_numDBs, bool modified_DBs) { +void ha_tokudb::restore_add_index( + TABLE* table_arg, + uint num_of_keys, + bool incremented_numDBs, + bool modified_DBs) { + uint curr_num_DBs = table_arg->s->keys + tokudb_test(hidden_primary_key); uint curr_index = 0; @@ -7808,7 +8312,7 @@ void ha_tokudb::restore_add_index(TABLE* table_arg, uint num_of_keys, bool incre // so that there is not a window // if (incremented_numDBs) { - rw_wrlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_write(); share->num_DBs--; } if (modified_DBs) { @@ -7821,15 +8325,14 @@ void ha_tokudb::restore_add_index(TABLE* table_arg, uint num_of_keys, bool incre if (share->key_file[curr_index]) { int r = share->key_file[curr_index]->close( share->key_file[curr_index], - 0 - ); - assert(r==0); + 0); + assert_always(r==0); share->key_file[curr_index] = NULL; } } } if (incremented_numDBs) { - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); } } @@ -7837,14 +8340,22 @@ void ha_tokudb::restore_add_index(TABLE* table_arg, uint num_of_keys, bool incre // Internal function called by ha_tokudb::prepare_drop_index and ha_tokudb::alter_table_phase2 // With a transaction, drops dictionaries associated with indexes in key_num // -int ha_tokudb::drop_indexes(TABLE *table_arg, uint *key_num, uint num_of_keys, KEY *key_info, DB_TXN* txn) { +int ha_tokudb::drop_indexes( + TABLE* table_arg, + uint* key_num, + uint num_of_keys, + KEY* key_info, + DB_TXN* txn) { + TOKUDB_HANDLER_DBUG_ENTER(""); - assert(txn); + assert_always(txn); int error = 0; for (uint i = 0; i < num_of_keys; i++) { uint curr_index = key_num[i]; - error = share->key_file[curr_index]->pre_acquire_fileops_lock(share->key_file[curr_index],txn); + error = share->key_file[curr_index]->pre_acquire_fileops_lock( + share->key_file[curr_index], + txn); if (error != 0) { goto cleanup; } @@ -7852,30 +8363,51 @@ int ha_tokudb::drop_indexes(TABLE *table_arg, uint *key_num, uint num_of_keys, K for (uint i = 0; i < num_of_keys; i++) { uint curr_index = key_num[i]; int r = share->key_file[curr_index]->close(share->key_file[curr_index],0); - assert(r==0); + assert_always(r==0); share->key_file[curr_index] = NULL; - error = remove_key_name_from_status(share->status_block, key_info[curr_index].name, txn); - if (error) { goto cleanup; } + error = remove_key_name_from_status( + share->status_block, + key_info[curr_index].name, + txn); + if (error) { + goto cleanup; + } - error = delete_or_rename_dictionary(share->table_name, NULL, key_info[curr_index].name, true, txn, true); - if (error) { goto cleanup; } + error = delete_or_rename_dictionary( + share->full_table_name(), + NULL, + key_info[curr_index].name, + true, + txn, + true); + if (error) { + goto cleanup; + } } cleanup: - if (error == DB_LOCK_NOTGRANTED && ((tokudb_debug & TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0)) { - sql_print_error("Could not drop indexes from table %s because \ -another transaction has accessed the table. \ -To drop indexes, make sure no transactions touch the table.", share->table_name); + if (TOKUDB_LIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0) && + error == DB_LOCK_NOTGRANTED) { + sql_print_error( + "Could not drop indexes from table %s because another transaction " + "has accessed the table. To drop indexes, make sure no " + "transactions touch the table.", + share->full_table_name()); } TOKUDB_HANDLER_DBUG_RETURN(error); } // -// Internal function called by ha_tokudb::prepare_drop_index and ha_tokudb::alter_table_phase2 -// Restores dropped indexes in case of error in error path of prepare_drop_index and alter_table_phase2 +// Internal function called by ha_tokudb::prepare_drop_index and +// ha_tokudb::alter_table_phase2 +// Restores dropped indexes in case of error in error path of +// prepare_drop_index and alter_table_phase2 // -void ha_tokudb::restore_drop_indexes(TABLE *table_arg, uint *key_num, uint num_of_keys) { +void ha_tokudb::restore_drop_indexes( + TABLE* table_arg, + uint* key_num, + uint num_of_keys) { // // reopen closed dictionaries @@ -7885,13 +8417,12 @@ void ha_tokudb::restore_drop_indexes(TABLE *table_arg, uint *key_num, uint num_o uint curr_index = key_num[i]; if (share->key_file[curr_index] == NULL) { r = open_secondary_dictionary( - &share->key_file[curr_index], + &share->key_file[curr_index], &table_share->key_info[curr_index], - share->table_name, - false, // - NULL - ); - assert(!r); + share->full_table_name(), + false, + NULL); + assert_always(!r); } } } @@ -7937,56 +8468,65 @@ void ha_tokudb::print_error(int error, myf errflag) { // does so by deleting and then recreating the dictionary in the context // of a transaction // -int ha_tokudb::truncate_dictionary( uint keynr, DB_TXN* txn ) { +int ha_tokudb::truncate_dictionary(uint keynr, DB_TXN* txn) { int error; bool is_pk = (keynr == primary_key); - toku_compression_method compression_method = get_compression_method(share->key_file[keynr]); + toku_compression_method compression_method = + get_compression_method(share->key_file[keynr]); error = share->key_file[keynr]->close(share->key_file[keynr], 0); - assert(error == 0); + assert_always(error == 0); share->key_file[keynr] = NULL; - if (is_pk) { share->file = NULL; } + if (is_pk) { + share->file = NULL; + } if (is_pk) { error = delete_or_rename_dictionary( - share->table_name, + share->full_table_name(), NULL, - "main", + "main", false, //is_key txn, - true // is a delete - ); - if (error) { goto cleanup; } - } - else { + true); // is a delete + if (error) { + goto cleanup; + } + } else { error = delete_or_rename_dictionary( - share->table_name, + share->full_table_name(), NULL, - table_share->key_info[keynr].name, + table_share->key_info[keynr].name, true, //is_key txn, - true // is a delete - ); - if (error) { goto cleanup; } + true); // is a delete + if (error) { + goto cleanup; + } } if (is_pk) { - error = create_main_dictionary(share->table_name, table, txn, &share->kc_info, compression_method); - } - else { + error = create_main_dictionary( + share->full_table_name(), + table, + txn, + &share->kc_info, + compression_method); + } else { error = create_secondary_dictionary( - share->table_name, - table, - &table_share->key_info[keynr], + share->full_table_name(), + table, + &table_share->key_info[keynr], txn, &share->kc_info, keynr, false, - compression_method - ); + compression_method); + } + if (error) { + goto cleanup; } - if (error) { goto cleanup; } cleanup: return error; @@ -8026,39 +8566,44 @@ int ha_tokudb::delete_all_rows_internal() { DB_TXN* txn = NULL; error = txn_begin(db_env, 0, &txn, 0, ha_thd()); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); for (uint i = 0; i < curr_num_DBs; i++) { error = share->key_file[i]->pre_acquire_fileops_lock( - share->key_file[i], - txn - ); - if (error) { goto cleanup; } + share->key_file[i], + txn); + if (error) { + goto cleanup; + } error = share->key_file[i]->pre_acquire_table_lock( - share->key_file[i], - txn - ); - if (error) { goto cleanup; } + share->key_file[i], + txn); + if (error) { + goto cleanup; + } } for (uint i = 0; i < curr_num_DBs; i++) { error = truncate_dictionary(i, txn); - if (error) { goto cleanup; } + if (error) { + goto cleanup; + } } // zap the row count if (error == 0) { - share->rows = 0; - // update auto increment - share->last_auto_increment = 0; - // calling write_to_status directly because we need to use txn - write_to_status( - share->status_block, + share->set_row_count(0, false); + // update auto increment + share->last_auto_increment = 0; + // calling write_to_status directly because we need to use txn + write_to_status( + share->status_block, hatoku_max_ai, - &share->last_auto_increment, - sizeof(share->last_auto_increment), - txn - ); + &share->last_auto_increment, + sizeof(share->last_auto_increment), + txn); } share->try_table_lock = true; @@ -8066,16 +8611,19 @@ int ha_tokudb::delete_all_rows_internal() { if (txn) { if (error) { abort_txn(txn); - } - else { + } else { commit_txn(txn,0); } } - if (error == DB_LOCK_NOTGRANTED && ((tokudb_debug & TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0)) { - sql_print_error("Could not truncate table %s because another transaction has accessed the \ - table. To truncate the table, make sure no transactions touch the table.", - share->table_name); + if (TOKUDB_LIKELY(TOKUDB_DEBUG_FLAGS( + TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS) == 0) && + error == DB_LOCK_NOTGRANTED) { + sql_print_error( + "Could not truncate table %s because another transaction has " + "accessed the table. To truncate the table, make sure no " + "transactions touch the table.", + share->full_table_name()); } // // regardless of errors, need to reopen the DB's @@ -8085,21 +8633,18 @@ int ha_tokudb::delete_all_rows_internal() { if (share->key_file[i] == NULL) { if (i != primary_key) { r = open_secondary_dictionary( - &share->key_file[i], - &table_share->key_info[i], - share->table_name, - false, // - NULL - ); - assert(!r); - } - else { + &share->key_file[i], + &table_share->key_info[i], + share->full_table_name(), + false, + NULL); + assert_always(!r); + } else { r = open_main_dictionary( - share->table_name, - false, - NULL - ); - assert(!r); + share->full_table_name(), + false, + NULL); + assert_always(!r); } } } @@ -8111,7 +8656,7 @@ void ha_tokudb::set_loader_error(int err) { } void ha_tokudb::set_dup_value_for_pk(DBT* key) { - assert(!hidden_primary_key); + assert_always(!hidden_primary_key); unpack_key(table->record[0],key,primary_key); last_dup_key = primary_key; } @@ -8147,18 +8692,20 @@ Item* ha_tokudb::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) { void ha_tokudb::cleanup_txn(DB_TXN *txn) { if (transaction == txn && cursor) { int r = cursor->c_close(cursor); - assert(r == 0); + assert_always(r == 0); cursor = NULL; } } void ha_tokudb::add_to_trx_handler_list() { - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton); + tokudb_trx_data* trx = + (tokudb_trx_data*)thd_get_ha_data(ha_thd(), tokudb_hton); trx->handlers = list_add(trx->handlers, &trx_handler_list); } void ha_tokudb::remove_from_trx_handler_list() { - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(ha_thd(), tokudb_hton); + tokudb_trx_data* trx = + (tokudb_trx_data*)thd_get_ha_data(ha_thd(), tokudb_hton); trx->handlers = list_delete(trx->handlers, &trx_handler_list); } @@ -8190,7 +8737,7 @@ bool ha_tokudb::rpl_lookup_rows() { if (!in_rpl_delete_rows && !in_rpl_update_rows) return true; else - return THDVAR(ha_thd(), rpl_lookup_rows); + return tokudb::sysvars::rpl_lookup_rows(ha_thd()); } // table admin diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h index e263cabb0d1be..8783836fbf054 100644 --- a/storage/tokudb/ha_tokudb.h +++ b/storage/tokudb/ha_tokudb.h @@ -23,11 +23,12 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." -#if !defined(HA_TOKUDB_H) -#define HA_TOKUDB_H +#ifndef _HA_TOKUDB_H +#define _HA_TOKUDB_H -#include +#include "hatoku_hton.h" #include "hatoku_cmp.h" +#include "tokudb_background.h" #define HA_TOKU_ORIG_VERSION 4 #define HA_TOKU_VERSION 4 @@ -45,84 +46,359 @@ typedef struct loader_context { } *LOADER_CONTEXT; // -// This object stores table information that is to be shared +// This class stores table information that is to be shared // among all ha_tokudb objects. -// There is one instance per table, shared among threads. +// There is one instance per table, shared among handlers. // Some of the variables here are the DB* pointers to indexes, // and auto increment information. // +// When the last user releases it's reference on the share, +// it closes all of its database handles and releases all info +// The share instance stays around though so some data can be transiently +// kept across open-close-open-close cycles. These data will be explicitly +// noted below. +// class TOKUDB_SHARE { public: - void init(void); - void destroy(void); + enum share_state_t { + CLOSED, + OPENED, + ERROR + }; + + // one time, start up init + static void static_init(); + + // one time, shutdown destroy + static void static_destroy(); + + // retuns a locked, properly reference counted share + // callers must check to ensure share is in correct state for callers use + // and unlock the share. + // if create_new is set, a new "CLOSED" share will be created if one + // doesn't exist, otherwise will return NULL if an existing is not found. + static TOKUDB_SHARE* get_share( + const char* table_name, + TABLE_SHARE* table_share, + THR_LOCK_DATA* data, + bool create_new); + + // removes a share entirely from the pool, call to rename/deleta a table + // caller must hold ddl_mutex on this share and the share MUST have + // exactly 0 _use_count + static void drop_share(TOKUDB_SHARE* share); + + void* operator new(size_t sz); + void operator delete(void* p); + + TOKUDB_SHARE(); + + // increases the ref count and waits for any currently executing state + // transition to complete + // returns current state and leaves share locked + // callers must check to ensure share is in correct state for callers use + // and unlock the share. + share_state_t addref(); + + // decreases the ref count and potentially closes the share + // caller must not have ownership of mutex, will lock and release + int release(); + + // returns the current use count + // no locking requirements + inline int use_count() const; + + // locks the share + inline void lock() const; + + // unlocks the share + inline void unlock() const; + + // returns the current state of the share + // no locking requirements + inline share_state_t state() const; + + // sets the state of the share + // caller must hold mutex on this share + inline void set_state(share_state_t state); + + // returns the full MySQL table name of the table ex: + // ./database/table + // no locking requirements + inline const char* full_table_name() const; + + // returns the strlen of the full table name + // no locking requirements + inline uint full_table_name_length() const; + + // returns the parsed database name this table resides in + // no locking requirements + inline const char* database_name() const; + + // returns the strlen of the database name + // no locking requirements + inline uint database_name_length() const; + + // returns the parsed table name of this table + // no locking requirements + inline const char* table_name() const; + + // returns the strlen of the the table name + // no locking requirements + inline uint table_name_length() const; + + // sets the estimated number of rows in the table + // should be called only during share initialization and info call + // caller must hold mutex on this share unless specified by 'locked' + inline void set_row_count(uint64_t rows, bool locked); + + // updates tracked row count and ongoing table change delta tracking + // called from any ha_tokudb operation that inserts/modifies/deletes rows + // may spawn background analysis if enabled, allowed and threshold hit + // caller must not have ownership of mutex, will lock and release + void update_row_count( + THD* thd, + uint64_t added, + uint64_t deleted, + uint64_t updated); + + // returns the current row count estimate + // no locking requirements + inline ha_rows row_count() const; + + // initializes cardinality statistics, takes ownership of incoming buffer + // caller must hold mutex on this share + inline void init_cardinality_counts( + uint32_t rec_per_keys, + uint64_t* rec_per_key); + + // update the cardinality statistics. number of records must match + // caller must hold mutex on this share + inline void update_cardinality_counts( + uint32_t rec_per_keys, + const uint64_t* rec_per_key); + + // disallow any auto analysis from taking place + // caller must hold mutex on this share + inline void disallow_auto_analysis(); + + // allow any auto analysis to take place + // pass in true for 'reset_deltas' to reset delta counting to 0 + // caller must hold mutex on this share + inline void allow_auto_analysis(bool reset_deltas); + + // cancels all background jobs for this share + // no locking requirements + inline void cancel_background_jobs() const; + + // copies cardinality statistics into TABLE counter set + // caller must not have ownership of mutex, will lock and release + void set_cardinality_counts_in_table(TABLE* table); + + // performs table analysis on underlying indices and produces estimated + // cardinality statistics. + // on success updates cardinality counts in status database and this share + // MUST pass a valid THD to access session variables. + // MAY pass txn. If txn is passed, assumes an explicit user scheduled + // ANALYZE and not an auto ANALYZE resulting from delta threshold + // uses session variables: + // tokudb_analyze_in_background, tokudb_analyze_throttle, + // tokudb_analyze_time, and tokudb_analyze_delete_fraction + // caller must hold mutex on this share + int analyze_standard(THD* thd, DB_TXN* txn); + + // performs table scan and updates the internal FT logical row count value + // on success also updates share row count estimate. + // MUST pass a valid THD to access session variables. + // MAY pass txn. If txn is passed, assumes an explicit user scheduled + // uses session variables: + // tokudb_analyze_in_background, and tokudb_analyze_throttle + // caller must not have ownership of mutex, will lock and release + int analyze_recount_rows(THD* thd, DB_TXN* txn); public: - char *table_name; - uint table_name_length, use_count; - pthread_mutex_t mutex; - THR_LOCK lock; - + //********************************* + // Destroyed and recreated on open-close-open ulonglong auto_ident; ulonglong last_auto_increment, auto_inc_create_value; - // - // estimate on number of rows in table - // - ha_rows rows; - // + // estimate on number of rows added in the process of a locked tables // this is so we can better estimate row count during a lock table - // ha_rows rows_from_locked_table; - DB *status_block; - // + DB* status_block; + // DB that is indexed on the primary key - // - DB *file; - // + DB* file; + // array of all DB's that make up table, includes DB that // is indexed on the primary key, add 1 in case primary // key is hidden - // - DB *key_file[MAX_KEY +1]; - rw_lock_t key_file_lock; + DB* key_file[MAX_KEY + 1]; uint status, version, capabilities; uint ref_length; - // + // whether table has an auto increment column - // bool has_auto_inc; - // + // index of auto increment column in table->field, if auto_inc exists - // uint ai_field_index; - // + // whether the primary key has a string - // bool pk_has_string; KEY_AND_COL_INFO kc_info; - - // + + // key info copied from TABLE_SHARE, used by background jobs that have no + // access to a handler instance + uint _keys; + uint _max_key_parts; + struct key_descriptor_t { + uint _parts; + bool _is_unique; + char* _name; + }; + key_descriptor_t* _key_descriptors; + // we want the following optimization for bulk loads, if the table is empty, // attempt to grab a table lock. emptiness check can be expensive, // so we try it once for a table. After that, we keep this variable around - // to tell us to not try it again. - // - bool try_table_lock; + // to tell us to not try it again. + bool try_table_lock; bool has_unique_keys; bool replace_into_fast; - rw_lock_t num_DBs_lock; + tokudb::thread::rwlock_t _num_DBs_lock; uint32_t num_DBs; - pthread_cond_t m_openclose_cond; - enum { CLOSED, OPENING, OPENED, CLOSING, ERROR } m_state; - int m_error; - int m_initialize_count; +private: + static HASH _open_tables; + static tokudb::thread::mutex_t _open_tables_mutex; + + static uchar* hash_get_key( + TOKUDB_SHARE* share, + size_t* length, + TOKUDB_UNUSED(my_bool not_used)); + + static void hash_free_element(TOKUDB_SHARE* share); - uint n_rec_per_key; - uint64_t *rec_per_key; + //********************************* + // Spans open-close-open + mutable tokudb::thread::mutex_t _mutex; + mutable tokudb::thread::mutex_t _ddl_mutex; + uint _use_count; + + share_state_t _state; + + ulonglong _row_delta_activity; + bool _allow_auto_analysis; + + String _full_table_name; + String _database_name; + String _table_name; + + //********************************* + // Destroyed and recreated on open-close-open + THR_LOCK _thr_lock; + + // estimate on number of rows in table + ha_rows _rows; + + // cardinality counts + uint32_t _rec_per_keys; + uint64_t* _rec_per_key; + bool _card_changed; + + void init(const char* table_name); + void destroy(); }; +inline int TOKUDB_SHARE::use_count() const { + return _use_count; +} +inline void TOKUDB_SHARE::lock() const { + _mutex.lock(); +} +inline void TOKUDB_SHARE::unlock() const { + _mutex.unlock(); +} +inline TOKUDB_SHARE::share_state_t TOKUDB_SHARE::state() const { + return _state; +} +inline void TOKUDB_SHARE::set_state(TOKUDB_SHARE::share_state_t state) { + assert_debug(_mutex.is_owned_by_me()); + _state = state; +} +inline const char* TOKUDB_SHARE::full_table_name() const { + return _full_table_name.ptr(); +} +inline uint TOKUDB_SHARE::full_table_name_length() const { + return _full_table_name.length(); +} +inline const char* TOKUDB_SHARE::database_name() const { + return _database_name.ptr(); +} +inline uint TOKUDB_SHARE::database_name_length() const { + return _database_name.length(); +} +inline const char* TOKUDB_SHARE::table_name() const { + return _table_name.ptr(); +} +inline uint TOKUDB_SHARE::table_name_length() const { + return _table_name.length(); +} +inline void TOKUDB_SHARE::set_row_count(uint64_t rows, bool locked) { + if (!locked) { + lock(); + } else { + assert_debug(_mutex.is_owned_by_me()); + } + if (_rows && rows == 0) + _row_delta_activity = 0; + + _rows = rows; + if (!locked) { + unlock(); + } +} +inline ha_rows TOKUDB_SHARE::row_count() const { + return _rows; +} +inline void TOKUDB_SHARE::init_cardinality_counts( + uint32_t rec_per_keys, + uint64_t* rec_per_key) { + + assert_debug(_mutex.is_owned_by_me()); + // can not change number of keys live + assert_always(_rec_per_key == NULL && _rec_per_keys == 0); + _rec_per_keys = rec_per_keys; + _rec_per_key = rec_per_key; + _card_changed = true; +} +inline void TOKUDB_SHARE::update_cardinality_counts( + uint32_t rec_per_keys, + const uint64_t* rec_per_key) { + + assert_debug(_mutex.is_owned_by_me()); + // can not change number of keys live + assert_always(rec_per_keys == _rec_per_keys); + assert_always(rec_per_key != NULL); + memcpy(_rec_per_key, rec_per_key, _rec_per_keys * sizeof(uint64_t)); + _card_changed = true; +} +inline void TOKUDB_SHARE::disallow_auto_analysis() { + assert_debug(_mutex.is_owned_by_me()); + _allow_auto_analysis = false; +} +inline void TOKUDB_SHARE::allow_auto_analysis(bool reset_deltas) { + assert_debug(_mutex.is_owned_by_me()); + _allow_auto_analysis = true; + if (reset_deltas) + _row_delta_activity = 0; +} +inline void TOKUDB_SHARE::cancel_background_jobs() const { + tokudb::background::_job_manager->cancel_job(full_table_name()); +} + + typedef struct st_filter_key_part_info { uint offset; @@ -278,6 +554,7 @@ class ha_tokudb : public handler { // ulonglong added_rows; ulonglong deleted_rows; + ulonglong updated_rows; uint last_dup_key; @@ -438,7 +715,7 @@ class ha_tokudb : public handler { // Returns a bit mask of capabilities of storage engine. Capabilities // defined in sql/handler.h // - ulonglong table_flags(void) const; + ulonglong table_flags() const; ulong index_flags(uint inx, uint part, bool all_parts) const; @@ -482,7 +759,7 @@ class ha_tokudb : public handler { double index_only_read_time(uint keynr, double records); int open(const char *name, int mode, uint test_if_locked); - int close(void); + int close(); void update_create_info(HA_CREATE_INFO* create_info); int create(const char *name, TABLE * form, HA_CREATE_INFO * create_info); int delete_table(const char *name); @@ -528,7 +805,7 @@ class ha_tokudb : public handler { void position(const uchar * record); int info(uint); int extra(enum ha_extra_function operation); - int reset(void); + int reset(); int external_lock(THD * thd, int lock_type); int start_stmt(THD * thd, thr_lock_type lock_type); @@ -540,12 +817,17 @@ class ha_tokudb : public handler { int get_status(DB_TXN* trans); void init_hidden_prim_key_info(DB_TXN *txn); inline void get_auto_primary_key(uchar * to) { - tokudb_pthread_mutex_lock(&share->mutex); + share->lock(); share->auto_ident++; hpk_num_to_char(to, share->auto_ident); - tokudb_pthread_mutex_unlock(&share->mutex); + share->unlock(); } - virtual void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong * first_value, ulonglong * nb_reserved_values); + virtual void get_auto_increment( + ulonglong offset, + ulonglong increment, + ulonglong nb_desired_values, + ulonglong* first_value, + ulonglong* nb_reserved_values); bool is_optimize_blocking(); bool is_auto_inc_singleton(); void print_error(int error, myf errflag); @@ -772,5 +1054,5 @@ static inline bool key_is_clustering(const KEY *key) { } #endif -#endif +#endif // _HA_TOKUDB_H diff --git a/storage/tokudb/ha_tokudb_admin.cc b/storage/tokudb/ha_tokudb_admin.cc index 996ce49d85ffd..7fa17945f1593 100644 --- a/storage/tokudb/ha_tokudb_admin.cc +++ b/storage/tokudb/ha_tokudb_admin.cc @@ -23,132 +23,800 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." +#include "tokudb_sysvars.h" #include "toku_time.h" -struct analyze_progress_extra { - THD *thd; - TOKUDB_SHARE *share; - TABLE_SHARE *table_share; - uint key_i; - const char *key_name; - time_t t_start; - char *write_status_msg; +namespace tokudb { +namespace analyze { + +class recount_rows_t : public tokudb::background::job_manager_t::job_t { +public: + void* operator new(size_t sz); + void operator delete(void* p); + + recount_rows_t( + bool user_schedued, + THD* thd, + TOKUDB_SHARE* share, + DB_TXN* txn); + + virtual ~recount_rows_t(); + + virtual const char* key(); + + virtual void status( + char* database, + char* table, + char* type, + char* params, + char* status); + +protected: + virtual void on_run(); + + virtual void on_destroy(); + +private: + // to be provided by the initiator of recount rows + THD* _thd; + TOKUDB_SHARE* _share; + DB_TXN* _txn; + ulonglong _throttle; + + // for recount rows status reporting + int _result; + ulonglong _recount_start; // in microseconds + ulonglong _total_elapsed_time; // in microseconds + + bool _local_txn; + ulonglong _rows; + ulonglong _deleted_rows; + ulonglong _ticks; + + static int analyze_recount_rows_progress( + uint64_t count, + uint64_t deleted, + void* extra); + int analyze_recount_rows_progress(uint64_t count, uint64_t deleted); + void get_analyze_status(char*); }; -static int analyze_progress(void *v_extra, uint64_t rows) { - struct analyze_progress_extra *extra = (struct analyze_progress_extra *) v_extra; - THD *thd = extra->thd; - if (thd_killed(thd)) - return ER_ABORTING_CONNECTION; +void* recount_rows_t::operator new(size_t sz) { + return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE)); +} +void recount_rows_t::operator delete(void* p) { + tokudb::memory::free(p); +} +recount_rows_t::recount_rows_t( + bool user_scheduled, + THD* thd, + TOKUDB_SHARE* share, + DB_TXN* txn) : + tokudb::background::job_manager_t::job_t(user_scheduled), + _share(share), + _result(HA_ADMIN_OK), + _recount_start(0), + _total_elapsed_time(0), + _local_txn(false), + _rows(0), + _deleted_rows(0), + _ticks(0) { + + assert_debug(thd != NULL); + assert_debug(share != NULL); + + if (tokudb::sysvars::analyze_in_background(thd)) { + _thd = NULL; + _txn = NULL; + } else { + _thd = thd; + _txn = txn; + } + + _throttle = tokudb::sysvars::analyze_throttle(thd); +} +recount_rows_t::~recount_rows_t() { +} +void recount_rows_t::on_run() { + _recount_start = tokudb::time::microsec(); + _total_elapsed_time = 0; + + if (_txn == NULL) { + _result = db_env->txn_begin(db_env, NULL, &_txn, DB_READ_UNCOMMITTED); + + if (_result != 0) { + _txn = NULL; + _result = HA_ADMIN_FAILED; + goto error; + } + _local_txn = true; + } else { + _local_txn = false; + } + + _result = + _share->file->recount_rows( + _share->file, + analyze_recount_rows_progress, + this); + + if (_result != 0) { + if (_local_txn) { + _txn->abort(_txn); + _txn = NULL; + } + _result = HA_ADMIN_FAILED; + goto error; + } + + DB_BTREE_STAT64 dict_stats; + _result = _share->file->stat64(_share->file, _txn, &dict_stats); + if (_result == 0) { + _share->set_row_count(dict_stats.bt_ndata, false); + } + if (_result != 0) + _result = HA_ADMIN_FAILED; + + if (_local_txn) { + if (_result == HA_ADMIN_OK) { + _txn->commit(_txn, 0); + } else { + _txn->abort(_txn); + } + _txn = NULL; + } + + sql_print_information( + "tokudb analyze recount rows %d counted %lld", + _result, + _share->row_count()); +error: + return; +} +void recount_rows_t::on_destroy() { + _share->release(); +} +const char* recount_rows_t::key() { + return _share->full_table_name(); +} +void recount_rows_t::status( + char* database, + char* table, + char* type, + char* params, + char* status) { + + strcpy(database, _share->database_name()); + strcpy(table, _share->table_name()); + strcpy(type, "TOKUDB_ANALYZE_MODE_RECOUNT_ROWS"); + sprintf(params, "TOKUDB_ANALYZE_THROTTLE=%llu;", _throttle); + get_analyze_status(status); +} +int recount_rows_t::analyze_recount_rows_progress( + uint64_t count, + uint64_t deleted, + void* extra) { + + recount_rows_t* context = (recount_rows_t*)extra; + return context->analyze_recount_rows_progress(count, deleted); +} +int recount_rows_t::analyze_recount_rows_progress( + uint64_t count, + uint64_t deleted) { + + _rows = count; + _deleted_rows += deleted; + deleted > 0 ? _ticks += deleted : _ticks++; + + if (_ticks > 1000) { + _ticks = 0; + uint64_t now = tokudb::time::microsec(); + _total_elapsed_time = now - _recount_start; + if ((_thd && thd_killed(_thd)) || cancelled()) { + // client killed + return ER_ABORTING_CONNECTION; + } + + // report + if (_thd) { + char status[256]; + get_analyze_status(status); + thd_proc_info(_thd, status); + } + + // throttle + // given the throttle value, lets calculate the maximum number of rows + // we should have seen so far in a .1 sec resolution + if (_throttle > 0) { + uint64_t estimated_rows = _total_elapsed_time / 100000; + estimated_rows = estimated_rows * (_throttle / 10); + if (_rows + _deleted_rows > estimated_rows) { + // sleep for 1/10 of a second + tokudb::time::sleep_microsec(100000); + } + } + } + return 0; +} +void recount_rows_t::get_analyze_status(char* msg) { + sprintf( + msg, + "recount_rows %s.%s counted %llu rows and %llu deleted in %llu " + "seconds.", + _share->database_name(), + _share->table_name(), + _rows, + _deleted_rows, + _total_elapsed_time / tokudb::time::MICROSECONDS); +} + + +class standard_t : public tokudb::background::job_manager_t::job_t { +public: + void* operator new(size_t sz); + void operator delete(void* p); + + standard_t(bool user_scheduled, THD* thd, TOKUDB_SHARE* share, DB_TXN* txn); + + virtual ~standard_t(); + + virtual const char* key(void); + + virtual void status( + char* database, + char* table, + char* type, + char* params, + char* status); + +protected: + virtual void on_run(); + + virtual void on_destroy(); + +private: + // to be provided by initiator of analyze + THD* _thd; + TOKUDB_SHARE* _share; + DB_TXN* _txn; + ulonglong _throttle; // in microseconds + ulonglong _time_limit; // in microseconds + double _delete_fraction; + + // for analyze status reporting, may also use other state + int _result; + ulonglong _analyze_start; // in microseconds + ulonglong _total_elapsed_time; // in microseconds + + // for analyze internal use, pretty much these are per-key/index + ulonglong _current_key; + bool _local_txn; + ulonglong _half_time; + ulonglong _half_rows; + ulonglong _rows; + ulonglong _deleted_rows; + ulonglong _ticks; + ulonglong _analyze_key_start; // in microseconds + ulonglong _key_elapsed_time; // in microseconds + uint _scan_direction; + + static bool analyze_standard_cursor_callback( + void* extra, + uint64_t deleted_rows); + bool analyze_standard_cursor_callback(uint64_t deleted_rows); + + void get_analyze_status(char*); + int analyze_key_progress(); + int analyze_key(uint64_t* rec_per_key_part); +}; + +void* standard_t::operator new(size_t sz) { + return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE)); +} +void standard_t::operator delete(void* p) { + tokudb::memory::free(p); +} +standard_t::standard_t( + bool user_scheduled, + THD* thd, + TOKUDB_SHARE* share, + DB_TXN* txn) : + tokudb::background::job_manager_t::job_t(user_scheduled), + _share(share), + _result(HA_ADMIN_OK), + _analyze_start(0), + _total_elapsed_time(0), + _current_key(0), + _local_txn(false), + _half_time(0), + _half_rows(0), + _rows(0), + _deleted_rows(0), + _ticks(0), + _analyze_key_start(0), + _key_elapsed_time(0), + _scan_direction(0) { + + assert_debug(thd != NULL); + assert_debug(share != NULL); + + if (tokudb::sysvars::analyze_in_background(thd)) { + _thd = NULL; + _txn = NULL; + } else { + _thd = thd; + _txn = txn; + } + _throttle = tokudb::sysvars::analyze_throttle(thd); + _time_limit = + tokudb::sysvars::analyze_time(thd) * tokudb::time::MICROSECONDS; + _delete_fraction = tokudb::sysvars::analyze_delete_fraction(thd); +} +standard_t::~standard_t() { +} +void standard_t::on_run() { + DB_BTREE_STAT64 stat64; + uint64_t rec_per_key_part[_share->_max_key_parts]; + uint64_t total_key_parts = 0; + _analyze_start = tokudb::time::microsec(); + _half_time = _time_limit > 0 ? _time_limit/2 : 0; + + if (_txn == NULL) { + _result = db_env->txn_begin(db_env, NULL, &_txn, DB_READ_UNCOMMITTED); + + if (_result != 0) { + _txn = NULL; + _result = HA_ADMIN_FAILED; + goto error; + } + _local_txn = true; + } else { + _local_txn = false; + } + + _result = _share->key_file[0]->stat64(_share->key_file[0], _txn, &stat64); + if (_result != 0) { + _result = HA_ADMIN_FAILED; + goto cleanup; + } + _half_rows = stat64.bt_ndata / 2; + + for (ulonglong current_key = 0; + _result == HA_ADMIN_OK && current_key < _share->_keys; + current_key++) { + + _current_key = current_key; + _rows = _deleted_rows = _ticks = 0; + _result = analyze_key(&rec_per_key_part[total_key_parts]); + + if ((_result != 0 && _result != ETIME) || + (_result != 0 && _rows == 0 && _deleted_rows > 0)) { + _result = HA_ADMIN_FAILED; + } + if (_thd && (_result == HA_ADMIN_FAILED || + (double)_deleted_rows > + _delete_fraction * (_rows + _deleted_rows))) { + + char name[256]; int namelen; + namelen = + snprintf( + name, + sizeof(name), + "%s.%s.%s", + _share->database_name(), + _share->table_name(), + _share->_key_descriptors[_current_key]._name); + _thd->protocol->prepare_for_resend(); + _thd->protocol->store(name, namelen, system_charset_info); + _thd->protocol->store("analyze", 7, system_charset_info); + _thd->protocol->store("info", 4, system_charset_info); + char rowmsg[256]; + int rowmsglen; + rowmsglen = + snprintf( + rowmsg, + sizeof(rowmsg), + "rows processed %llu rows deleted %llu", + _rows, + _deleted_rows); + _thd->protocol->store(rowmsg, rowmsglen, system_charset_info); + _thd->protocol->write(); + + sql_print_information( + "tokudb analyze on %.*s %.*s", + namelen, + name, + rowmsglen, + rowmsg); + } + + total_key_parts += _share->_key_descriptors[_current_key]._parts; + } + if (_result == HA_ADMIN_OK) { + int error = + tokudb::set_card_in_status( + _share->status_block, + _txn, + total_key_parts, + rec_per_key_part); + if (error) + _result = HA_ADMIN_FAILED; + + _share->lock(); + _share->update_cardinality_counts(total_key_parts, rec_per_key_part); + _share->allow_auto_analysis(true); + _share->unlock(); + } + +cleanup: + if (_local_txn) { + if (_result == HA_ADMIN_OK) { + _txn->commit(_txn, 0); + } else { + _txn->abort(_txn); + } + _txn = NULL; + } + +error: + return; + +} +void standard_t::on_destroy() { + _share->lock(); + _share->allow_auto_analysis(false); + _share->unlock(); + _share->release(); +} +const char* standard_t::key() { + return _share->full_table_name(); +} +void standard_t::status( + char* database, + char* table, + char* type, + char* params, + char* status) { + + strcpy(database, _share->database_name()); + strcpy(table, _share->table_name()); + strcpy(type, "TOKUDB_ANALYZE_MODE_STANDARD"); + sprintf( + params, + "TOKUDB_ANALYZE_DELETE_FRACTION=%f; " + "TOKUDB_ANALYZE_TIME=%llu; TOKUDB_ANALYZE_THROTTLE=%llu;", + _delete_fraction, + _time_limit / tokudb::time::MICROSECONDS, + _throttle); + get_analyze_status(status); +} +bool standard_t::analyze_standard_cursor_callback( + void* extra, + uint64_t deleted_rows) { + standard_t* context = (standard_t*)extra; + return context->analyze_standard_cursor_callback(deleted_rows); +} +bool standard_t::analyze_standard_cursor_callback(uint64_t deleted_rows) { + _deleted_rows += deleted_rows; + _ticks += deleted_rows; + return analyze_key_progress() != 0; +} +void standard_t::get_analyze_status(char* msg) { + static const char* scan_direction_str[] = { + "not scanning", + "scanning forward", + "scanning backward", + "scan unknown" + }; + + const char* scan_direction = NULL; + switch (_scan_direction) { + case 0: scan_direction = scan_direction_str[0]; break; + case DB_NEXT: scan_direction = scan_direction_str[1]; break; + case DB_PREV: scan_direction = scan_direction_str[2]; break; + default: scan_direction = scan_direction_str[3]; break; + } - time_t t_now = time(0); - time_t t_limit = THDVAR(thd, analyze_time); - time_t t_start = extra->t_start; - if (t_limit > 0 && t_now - t_start > t_limit) - return ETIME; float progress_rows = 0.0; - TOKUDB_SHARE *share = extra->share; - if (share->rows > 0) - progress_rows = (float) rows / (float) share->rows; + if (_share->row_count() > 0) + progress_rows = (float) _rows / (float) _share->row_count(); float progress_time = 0.0; - if (t_limit > 0) - progress_time = (float) (t_now - t_start) / (float) t_limit; - char *write_status_msg = extra->write_status_msg; - TABLE_SHARE *table_share = extra->table_share; - sprintf(write_status_msg, "%.*s.%.*s.%s %u of %u %.lf%% rows %.lf%% time", - (int) table_share->db.length, table_share->db.str, - (int) table_share->table_name.length, table_share->table_name.str, - extra->key_name, extra->key_i, table_share->keys, progress_rows * 100.0, progress_time * 100.0); - thd_proc_info(thd, write_status_msg); + if (_time_limit > 0) + progress_time = (float) _key_elapsed_time / (float) _time_limit; + sprintf( + msg, + "analyze table standard %s.%s.%s %llu of %u %.lf%% rows %.lf%% time, " + "%s", + _share->database_name(), + _share->table_name(), + _share->_key_descriptors[_current_key]._name, + _current_key, + _share->_keys, + progress_rows * 100.0, + progress_time * 100.0, + scan_direction); +} +int standard_t::analyze_key_progress(void) { + if (_ticks > 1000) { + _ticks = 0; + uint64_t now = tokudb::time::microsec(); + _total_elapsed_time = now - _analyze_start; + _key_elapsed_time = now - _analyze_key_start; + if ((_thd && thd_killed(_thd)) || cancelled()) { + // client killed + return ER_ABORTING_CONNECTION; + } else if(_time_limit > 0 && + (uint64_t)_key_elapsed_time > _time_limit) { + // time limit reached + return ETIME; + } + + // report + if (_thd) { + char status[256]; + get_analyze_status(status); + thd_proc_info(_thd, status); + } + + // throttle + // given the throttle value, lets calculate the maximum number of rows + // we should have seen so far in a .1 sec resolution + if (_throttle > 0) { + uint64_t estimated_rows = _key_elapsed_time / 100000; + estimated_rows = estimated_rows * (_throttle / 10); + if (_rows + _deleted_rows > estimated_rows) { + // sleep for 1/10 of a second + tokudb::time::sleep_microsec(100000); + } + } + } return 0; } +int standard_t::analyze_key(uint64_t* rec_per_key_part) { + int error = 0; + DB* db = _share->key_file[_current_key]; + uint64_t num_key_parts = _share->_key_descriptors[_current_key]._parts; + uint64_t unique_rows[num_key_parts]; + bool is_unique = _share->_key_descriptors[_current_key]._is_unique; + DBC* cursor = NULL; + int close_error = 0; + DBT key, prev_key; + bool copy_key = false; + + _analyze_key_start = tokudb::time::microsec(); + _key_elapsed_time = 0; + _scan_direction = DB_NEXT; + + if (is_unique && num_key_parts == 1) { + // don't compute for unique keys with a single part. we already know + // the answer. + _rows = unique_rows[0] = 1; + goto done; + } + + for (uint64_t i = 0; i < num_key_parts; i++) + unique_rows[i] = 1; + + // stop looking when the entire dictionary was analyzed, or a + // cap on execution time was reached, or the analyze was killed. + while (1) { + if (cursor == NULL) { + error = db->cursor(db, _txn, &cursor, 0); + if (error != 0) + goto done; + + cursor->c_set_check_interrupt_callback( + cursor, + analyze_standard_cursor_callback, + this); + + memset(&key, 0, sizeof(DBT)); key.flags = DB_DBT_REALLOC; + memset(&prev_key, 0, sizeof(DBT)); prev_key.flags = DB_DBT_REALLOC; + copy_key = true; + } + + error = cursor->c_get(cursor, &key, 0, _scan_direction); + if (error != 0) { + if (error == DB_NOTFOUND || error == TOKUDB_INTERRUPTED) + error = 0; // not an error + break; + } else if (cancelled()) { + error = ER_ABORTING_CONNECTION; + break; + } + + _rows++; + _ticks++; + + // if copy_key is false at this pont, we have some value sitting in + // prev_key that we can compare to + // if the comparison reveals a unique key, we must set copy_key to true + // so the code following can copy he current key into prev_key for the + // next iteration + if (copy_key == false) { + // compare this key with the previous key. ignore + // appended PK for SK's. + // TODO if a prefix is different, then all larger keys + // that include the prefix are also different. + // TODO if we are comparing the entire primary key or + // the entire unique secondary key, then the cardinality + // must be 1, so we can avoid computing it. + for (uint64_t i = 0; i < num_key_parts; i++) { + int cmp = tokudb_cmp_dbt_key_parts(db, &prev_key, &key, i+1); + if (cmp != 0) { + unique_rows[i]++; + copy_key = true; + } + } + } + + // prev_key = key or prev_key is NULL + if (copy_key) { + prev_key.data = + tokudb::memory::realloc( + prev_key.data, + key.size, + MYF(MY_WME|MY_ZEROFILL|MY_FAE)); + assert_always(prev_key.data); + prev_key.size = key.size; + memcpy(prev_key.data, key.data, prev_key.size); + copy_key = false; + } + + error = analyze_key_progress(); + if (error == ETIME) { + error = 0; + break; + } else if (error) { + break; + } + + // if we have a time limit, are scanning forward and have exceed the + // _half_time and not passed the _half_rows number of the rows in the + // index: clean up the keys, close the cursor and reverse direction. + if (TOKUDB_UNLIKELY(_half_time > 0 && + _scan_direction == DB_NEXT && + _key_elapsed_time >= _half_time && + _rows < _half_rows)) { + + tokudb::memory::free(key.data); key.data = NULL; + tokudb::memory::free(prev_key.data); prev_key.data = NULL; + close_error = cursor->c_close(cursor); + assert_always(close_error == 0); + cursor = NULL; + _scan_direction = DB_PREV; + } + } + // cleanup + if (key.data) tokudb::memory::free(key.data); + if (prev_key.data) tokudb::memory::free(prev_key.data); + if (cursor) close_error = cursor->c_close(cursor); + assert_always(close_error == 0); + +done: + // return cardinality + for (uint64_t i = 0; i < num_key_parts; i++) { + rec_per_key_part[i] = _rows / unique_rows[i]; + } + return error; +} + +} // namespace analyze +} // namespace tokudb + int ha_tokudb::analyze(THD *thd, HA_CHECK_OPT *check_opt) { - TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name); + TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name()); + int result = HA_ADMIN_OK; + tokudb::sysvars::analyze_mode_t mode = tokudb::sysvars::analyze_mode(thd); + + switch (mode) { + case tokudb::sysvars::TOKUDB_ANALYZE_RECOUNT_ROWS: + result = share->analyze_recount_rows(thd, transaction); + break; + case tokudb::sysvars::TOKUDB_ANALYZE_STANDARD: + share->lock(); + result = share->analyze_standard(thd, transaction); + share->unlock(); + break; + case tokudb::sysvars::TOKUDB_ANALYZE_CANCEL: + share->cancel_background_jobs(); + break; + default: + break; // no-op + } + TOKUDB_HANDLER_DBUG_RETURN(result); +} + +int TOKUDB_SHARE::analyze_recount_rows(THD* thd,DB_TXN* txn) { + TOKUDB_HANDLER_DBUG_ENTER("%s", table_name()); + + assert_always(thd != NULL); + const char *orig_proc_info = tokudb_thd_get_proc_info(thd); - uint64_t rec_per_key[table_share->key_parts]; + int result = HA_ADMIN_OK; + + tokudb::analyze::recount_rows_t* job + = new tokudb::analyze::recount_rows_t(true, thd, this, txn); + assert_always(job != NULL); + + // job->destroy will drop the ref + addref(); + unlock(); + + bool ret = tokudb::background::_job_manager-> + run_job(job, tokudb::sysvars::analyze_in_background(thd)); + + if (!ret) { + job->destroy(); + delete job; + result = HA_ADMIN_FAILED; + } + + thd_proc_info(thd, orig_proc_info); + + TOKUDB_HANDLER_DBUG_RETURN(result); +} + +// on entry, if txn is !NULL, it is a user session invoking ANALYZE directly +// and no lock will be held on 'this', else if txn is NULL it is an auto and +// 'this' will be locked. +int TOKUDB_SHARE::analyze_standard(THD* thd, DB_TXN* txn) { + TOKUDB_HANDLER_DBUG_ENTER("%s", table_name()); + + assert_always(thd != NULL); + assert_debug(_mutex.is_owned_by_me() == true); + int result = HA_ADMIN_OK; // stub out analyze if optimize is remapped to alter recreate + analyze - if (thd_sql_command(thd) != SQLCOM_ANALYZE && thd_sql_command(thd) != SQLCOM_ALTER_TABLE) { + // when not auto analyze + if (txn && + thd_sql_command(thd) != SQLCOM_ANALYZE && + thd_sql_command(thd) != SQLCOM_ALTER_TABLE) { TOKUDB_HANDLER_DBUG_RETURN(result); } - DB_TXN *txn = transaction; - if (!txn) { + const char *orig_proc_info = tokudb_thd_get_proc_info(thd); + + tokudb::analyze::standard_t* job + = new tokudb::analyze::standard_t(txn == NULL ? false : true, thd, + this, txn); + assert_always(job != NULL); + + // akin to calling addref, but we know, right here, right now, everything + // in the share is set up, files open, etc... + // job->destroy will drop the ref + _use_count++; + + // don't want any autos kicking off while we are analyzing + disallow_auto_analysis(); + + unlock(); + + bool ret = + tokudb::background::_job_manager->run_job( + job, + tokudb::sysvars::analyze_in_background(thd)); + + if (!ret) { + job->destroy(); + delete job; result = HA_ADMIN_FAILED; } - uint total_key_parts = 0; - if (result == HA_ADMIN_OK) { - // compute cardinality for each key - for (uint i = 0; result == HA_ADMIN_OK && i < table_share->keys; i++) { - KEY *key_info = &table_share->key_info[i]; - uint64_t num_key_parts = get_key_parts(key_info); - const char *key_name = i == primary_key ? "primary" : key_info->name; - struct analyze_progress_extra analyze_progress_extra = { - thd, share, table_share, i, key_name, time(0), write_status_msg - }; - bool is_unique = false; - if (i == primary_key || (key_info->flags & HA_NOSAME)) - is_unique = true; - uint64_t rows = 0; - uint64_t deleted_rows = 0; - int error = tokudb::analyze_card(share->key_file[i], txn, is_unique, num_key_parts, &rec_per_key[total_key_parts], - tokudb_cmp_dbt_key_parts, analyze_progress, &analyze_progress_extra, - &rows, &deleted_rows); - sql_print_information("tokudb analyze %d %" PRIu64 " %" PRIu64, error, rows, deleted_rows); - if (error != 0 && error != ETIME) { - result = HA_ADMIN_FAILED; - } - if (error != 0 && rows == 0 && deleted_rows > 0) { - result = HA_ADMIN_FAILED; - } - double f = THDVAR(thd, analyze_delete_fraction); - if (result == HA_ADMIN_FAILED || (double) deleted_rows > f * (rows + deleted_rows)) { - char name[256]; int namelen; - namelen = snprintf(name, sizeof name, "%.*s.%.*s.%s", - (int) table_share->db.length, table_share->db.str, - (int) table_share->table_name.length, table_share->table_name.str, - key_name); - thd->protocol->prepare_for_resend(); - thd->protocol->store(name, namelen, system_charset_info); - thd->protocol->store("analyze", 7, system_charset_info); - thd->protocol->store("info", 4, system_charset_info); - char rowmsg[256]; int rowmsglen; - rowmsglen = snprintf(rowmsg, sizeof rowmsg, "rows processed %" PRIu64 " rows deleted %" PRIu64, rows, deleted_rows); - thd->protocol->store(rowmsg, rowmsglen, system_charset_info); - thd->protocol->write(); - - sql_print_information("tokudb analyze on %.*s %.*s", - namelen, name, rowmsglen, rowmsg); - } - if (tokudb_debug & TOKUDB_DEBUG_ANALYZE) { - char name[256]; int namelen; - namelen = snprintf(name, sizeof name, "%.*s.%.*s.%s", - (int) table_share->db.length, table_share->db.str, - (int) table_share->table_name.length, table_share->table_name.str, - key_name); - TOKUDB_HANDLER_TRACE("%.*s rows %" PRIu64 " deleted %" PRIu64, - namelen, name, rows, deleted_rows); - for (uint j = 0; j < num_key_parts; j++) - TOKUDB_HANDLER_TRACE("%lu", rec_per_key[total_key_parts+j]); - } - total_key_parts += num_key_parts; - } - } - if (result == HA_ADMIN_OK) { - int error = tokudb::set_card_in_status(share->status_block, txn, total_key_parts, rec_per_key); - if (error) - result = HA_ADMIN_FAILED; - } + + lock(); + thd_proc_info(thd, orig_proc_info); + TOKUDB_HANDLER_DBUG_RETURN(result); } + typedef struct hot_optimize_context { - THD *thd; + THD* thd; char* write_status_msg; - ha_tokudb *ha; + ha_tokudb* ha; uint progress_stage; uint current_table; uint num_tables; @@ -160,11 +828,18 @@ typedef struct hot_optimize_context { static int hot_optimize_progress_fun(void *extra, float progress) { HOT_OPTIMIZE_CONTEXT context = (HOT_OPTIMIZE_CONTEXT)extra; if (thd_killed(context->thd)) { - sprintf(context->write_status_msg, "The process has been killed, aborting hot optimize."); + sprintf( + context->write_status_msg, + "The process has been killed, aborting hot optimize."); return ER_ABORTING_CONNECTION; } float percentage = progress * 100; - sprintf(context->write_status_msg, "Optimization of index %u of %u about %.lf%% done", context->current_table + 1, context->num_tables, percentage); + sprintf( + context->write_status_msg, + "Optimization of index %u of %u about %.lf%% done", + context->current_table + 1, + context->num_tables, + percentage); thd_proc_info(context->thd, context->write_status_msg); #ifdef HA_TOKUDB_HAS_THD_PROGRESS if (context->progress_stage < context->current_table) { @@ -193,10 +868,10 @@ static int hot_optimize_progress_fun(void *extra, float progress) { } // flatten all DB's in this table, to do so, peform hot optimize on each db -int ha_tokudb::do_optimize(THD *thd) { - TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name); +int ha_tokudb::do_optimize(THD* thd) { + TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name()); int error = 0; - const char *orig_proc_info = tokudb_thd_get_proc_info(thd); + const char* orig_proc_info = tokudb_thd_get_proc_info(thd); uint curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); #ifdef HA_TOKUDB_HAS_THD_PROGRESS @@ -207,10 +882,15 @@ int ha_tokudb::do_optimize(THD *thd) { // for each DB, run optimize and hot_optimize for (uint i = 0; i < curr_num_DBs; i++) { - // only optimize the index if it matches the optimize_index_name session variable - const char *optimize_index_name = THDVAR(thd, optimize_index_name); + // only optimize the index if it matches the optimize_index_name + // session variable + const char* optimize_index_name = + tokudb::sysvars::optimize_index_name(thd); if (optimize_index_name) { - const char *this_index_name = i >= table_share->keys ? "primary" : table_share->key_info[i].name; + const char* this_index_name = + i >= table_share->keys ? + "primary" : + table_share->key_info[i].name; if (strcasecmp(optimize_index_name, this_index_name) != 0) { continue; } @@ -229,11 +909,18 @@ int ha_tokudb::do_optimize(THD *thd) { hc.ha = this; hc.current_table = i; hc.num_tables = curr_num_DBs; - hc.progress_limit = THDVAR(thd, optimize_index_fraction); + hc.progress_limit = tokudb::sysvars::optimize_index_fraction(thd); hc.progress_last_time = toku_current_time_microsec(); - hc.throttle = THDVAR(thd, optimize_throttle); + hc.throttle = tokudb::sysvars::optimize_throttle(thd); uint64_t loops_run; - error = db->hot_optimize(db, NULL, NULL, hot_optimize_progress_fun, &hc, &loops_run); + error = + db->hot_optimize( + db, + NULL, + NULL, + hot_optimize_progress_fun, + &hc, + &loops_run); if (error) { goto cleanup; } @@ -248,8 +935,8 @@ int ha_tokudb::do_optimize(THD *thd) { TOKUDB_HANDLER_DBUG_RETURN(error); } -int ha_tokudb::optimize(THD *thd, HA_CHECK_OPT *check_opt) { - TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name); +int ha_tokudb::optimize(THD* thd, HA_CHECK_OPT* check_opt) { + TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name()); int error; #if TOKU_OPTIMIZE_WITH_RECREATE error = HA_ADMIN_TRY_ALTER; @@ -260,23 +947,30 @@ int ha_tokudb::optimize(THD *thd, HA_CHECK_OPT *check_opt) { } struct check_context { - THD *thd; + THD* thd; }; -static int ha_tokudb_check_progress(void *extra, float progress) { - struct check_context *context = (struct check_context *) extra; +static int ha_tokudb_check_progress(void* extra, float progress) { + struct check_context* context = (struct check_context*)extra; int result = 0; if (thd_killed(context->thd)) result = ER_ABORTING_CONNECTION; return result; } -static void ha_tokudb_check_info(THD *thd, TABLE *table, const char *msg) { +static void ha_tokudb_check_info(THD* thd, TABLE* table, const char* msg) { if (thd->vio_ok()) { - char tablename[table->s->db.length + 1 + table->s->table_name.length + 1]; - snprintf(tablename, sizeof tablename, "%.*s.%.*s", - (int) table->s->db.length, table->s->db.str, - (int) table->s->table_name.length, table->s->table_name.str); + char tablename[ + table->s->db.length + 1 + + table->s->table_name.length + 1]; + snprintf( + tablename, + sizeof(tablename), + "%.*s.%.*s", + (int)table->s->db.length, + table->s->db.str, + (int)table->s->table_name.length, + table->s->table_name.str); thd->protocol->prepare_for_resend(); thd->protocol->store(tablename, strlen(tablename), system_charset_info); thd->protocol->store("check", 5, system_charset_info); @@ -286,9 +980,9 @@ static void ha_tokudb_check_info(THD *thd, TABLE *table, const char *msg) { } } -int ha_tokudb::check(THD *thd, HA_CHECK_OPT *check_opt) { - TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name); - const char *orig_proc_info = tokudb_thd_get_proc_info(thd); +int ha_tokudb::check(THD* thd, HA_CHECK_OPT* check_opt) { + TOKUDB_HANDLER_DBUG_ENTER("%s", share->table_name()); + const char* orig_proc_info = tokudb_thd_get_proc_info(thd); int result = HA_ADMIN_OK; int r; @@ -305,38 +999,72 @@ int ha_tokudb::check(THD *thd, HA_CHECK_OPT *check_opt) { result = HA_ADMIN_INTERNAL_ERROR; if (result == HA_ADMIN_OK) { uint32_t num_DBs = table_share->keys + tokudb_test(hidden_primary_key); - snprintf(write_status_msg, sizeof write_status_msg, "%s primary=%d num=%d", share->table_name, primary_key, num_DBs); - if (tokudb_debug & TOKUDB_DEBUG_CHECK) { + snprintf( + write_status_msg, + sizeof(write_status_msg), + "%s primary=%d num=%d", + share->table_name(), + primary_key, + num_DBs); + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_CHECK))) { ha_tokudb_check_info(thd, table, write_status_msg); time_t now = time(0); char timebuf[32]; - TOKUDB_HANDLER_TRACE("%.24s %s", ctime_r(&now, timebuf), write_status_msg); + TOKUDB_HANDLER_TRACE( + "%.24s %s", + ctime_r(&now, timebuf), + write_status_msg); } for (uint i = 0; i < num_DBs; i++) { DB *db = share->key_file[i]; - const char *kname = i == primary_key ? "primary" : table_share->key_info[i].name; - snprintf(write_status_msg, sizeof write_status_msg, "%s key=%s %u", share->table_name, kname, i); + const char* kname = + i == primary_key ? "primary" : table_share->key_info[i].name; + snprintf( + write_status_msg, + sizeof(write_status_msg), + "%s key=%s %u", + share->table_name(), + kname, + i); thd_proc_info(thd, write_status_msg); - if (tokudb_debug & TOKUDB_DEBUG_CHECK) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_CHECK))) { ha_tokudb_check_info(thd, table, write_status_msg); time_t now = time(0); char timebuf[32]; - TOKUDB_HANDLER_TRACE("%.24s %s", ctime_r(&now, timebuf), write_status_msg); + TOKUDB_HANDLER_TRACE( + "%.24s %s", + ctime_r(&now, timebuf), + write_status_msg); } struct check_context check_context = { thd }; - r = db->verify_with_progress(db, ha_tokudb_check_progress, &check_context, (tokudb_debug & TOKUDB_DEBUG_CHECK) != 0, keep_going); + r = db->verify_with_progress( + db, + ha_tokudb_check_progress, + &check_context, + (tokudb::sysvars::debug & TOKUDB_DEBUG_CHECK) != 0, + keep_going); if (r != 0) { char msg[32 + strlen(kname)]; sprintf(msg, "Corrupt %s", kname); ha_tokudb_check_info(thd, table, msg); } - snprintf(write_status_msg, sizeof write_status_msg, "%s key=%s %u result=%d", share->table_name, kname, i, r); + snprintf( + write_status_msg, + sizeof(write_status_msg), + "%s key=%s %u result=%d", + share->full_table_name(), + kname, + i, + r); thd_proc_info(thd, write_status_msg); - if (tokudb_debug & TOKUDB_DEBUG_CHECK) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_CHECK))) { ha_tokudb_check_info(thd, table, write_status_msg); time_t now = time(0); char timebuf[32]; - TOKUDB_HANDLER_TRACE("%.24s %s", ctime_r(&now, timebuf), write_status_msg); + TOKUDB_HANDLER_TRACE( + "%.24s %s", + ctime_r(&now, timebuf), + write_status_msg); } if (result == HA_ADMIN_OK && r != 0) { result = HA_ADMIN_CORRUPT; diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc index 724c588ed0be1..d7b3bcb802a20 100644 --- a/storage/tokudb/ha_tokudb_alter_56.cc +++ b/storage/tokudb/ha_tokudb_alter_56.cc @@ -67,7 +67,7 @@ class tokudb_alter_ctx : public inplace_alter_handler_ctx { } public: ulong handler_flags; - DB_TXN *alter_txn; + DB_TXN* alter_txn; bool add_index_changed; bool incremented_num_DBs, modified_DBs; bool drop_index_changed; @@ -79,81 +79,110 @@ class tokudb_alter_ctx : public inplace_alter_handler_ctx { bool expand_blob_update_needed; bool optimize_needed; Dynamic_array changed_fields; - KEY_AND_COL_INFO *table_kc_info; - KEY_AND_COL_INFO *altered_table_kc_info; + KEY_AND_COL_INFO* table_kc_info; + KEY_AND_COL_INFO* altered_table_kc_info; KEY_AND_COL_INFO altered_table_kc_info_base; }; // Debug function to print out an alter table operation -void ha_tokudb::print_alter_info(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { - printf("***are keys of two tables same? %d\n", tables_have_same_keys(table, altered_table, false, false)); +void ha_tokudb::print_alter_info( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + + TOKUDB_TRACE( + "***are keys of two tables same? %d", + tables_have_same_keys(table, altered_table, false, false)); if (ha_alter_info->handler_flags) { - printf("***alter flags set ***\n"); + TOKUDB_TRACE("***alter flags set ***"); for (int i = 0; i < 32; i++) { if (ha_alter_info->handler_flags & (1 << i)) - printf("%d\n", i); + TOKUDB_TRACE("%d", i); } } - // everyone calculates data by doing some default_values - record[0], but I do not see why - // that is necessary - printf("******\n"); - printf("***orig table***\n"); + // everyone calculates data by doing some default_values - record[0], but + // I do not see why that is necessary + TOKUDB_TRACE("******"); + TOKUDB_TRACE("***orig table***"); for (uint i = 0; i < table->s->fields; i++) { // // make sure to use table->field, and NOT table->s->field // Field* curr_field = table->field[i]; uint null_offset = get_null_offset(table, curr_field); - printf( - "name: %s, types: %u %u, nullable: %d, null_offset: %d, is_null_field: %d, is_null %d, pack_length %u\n", - curr_field->field_name, - curr_field->real_type(), mysql_to_toku_type(curr_field), - curr_field->null_bit, - null_offset, - curr_field->real_maybe_null(), - curr_field->real_maybe_null() ? table->s->default_values[null_offset] & curr_field->null_bit : 0xffffffff, - curr_field->pack_length() - ); + TOKUDB_TRACE( + "name: %s, types: %u %u, nullable: %d, null_offset: %d, is_null_field: " + "%d, is_null %d, pack_length %u", + curr_field->field_name, + curr_field->real_type(), + mysql_to_toku_type(curr_field), + curr_field->null_bit, + null_offset, + curr_field->real_maybe_null(), + curr_field->real_maybe_null() ? + table->s->default_values[null_offset] & curr_field->null_bit : + 0xffffffff, + curr_field->pack_length()); } - printf("******\n"); - printf("***altered table***\n"); + TOKUDB_TRACE("******"); + TOKUDB_TRACE("***altered table***"); for (uint i = 0; i < altered_table->s->fields; i++) { Field* curr_field = altered_table->field[i]; uint null_offset = get_null_offset(altered_table, curr_field); - printf( - "name: %s, types: %u %u, nullable: %d, null_offset: %d, is_null_field: %d, is_null %d, pack_length %u\n", - curr_field->field_name, - curr_field->real_type(), mysql_to_toku_type(curr_field), - curr_field->null_bit, - null_offset, - curr_field->real_maybe_null(), - curr_field->real_maybe_null() ? altered_table->s->default_values[null_offset] & curr_field->null_bit : 0xffffffff, - curr_field->pack_length() - ); + TOKUDB_TRACE( + "name: %s, types: %u %u, nullable: %d, null_offset: %d, " + "is_null_field: %d, is_null %d, pack_length %u", + curr_field->field_name, + curr_field->real_type(), + mysql_to_toku_type(curr_field), + curr_field->null_bit, + null_offset, + curr_field->real_maybe_null(), + curr_field->real_maybe_null() ? + altered_table->s->default_values[null_offset] & + curr_field->null_bit : 0xffffffff, + curr_field->pack_length()); } - printf("******\n"); + TOKUDB_TRACE("******"); } -// Given two tables with equal number of fields, find all of the fields with different types -// and return the indexes of the different fields in the changed_fields array. This function ignores field -// name differences. -static int find_changed_fields(TABLE *table_a, TABLE *table_b, Dynamic_array &changed_fields) { +// Given two tables with equal number of fields, find all of the fields with +// different types and return the indexes of the different fields in the +// changed_fields array. This function ignores field name differences. +static int find_changed_fields( + TABLE* table_a, + TABLE* table_b, + Dynamic_array& changed_fields) { + for (uint i = 0; i < table_a->s->fields; i++) { - Field *field_a = table_a->field[i]; - Field *field_b = table_b->field[i]; + Field* field_a = table_a->field[i]; + Field* field_b = table_b->field[i]; if (!fields_are_same_type(field_a, field_b)) changed_fields.append(i); } return changed_fields.elements(); } -static bool change_length_is_supported(TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, tokudb_alter_ctx *ctx); - -static bool change_type_is_supported(TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, tokudb_alter_ctx *ctx); +static bool change_length_is_supported( + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + tokudb_alter_ctx* ctx); + +static bool change_type_is_supported( + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + tokudb_alter_ctx* ctx); + +// The ha_alter_info->handler_flags can not be trusted. +// This function maps the bogus handler flags to something we like. +static ulong fix_handler_flags( + THD* thd, + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { -// The ha_alter_info->handler_flags can not be trusted. This function maps the bogus handler flags to something we like. -static ulong fix_handler_flags(THD *thd, TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info) { ulong handler_flags = ha_alter_info->handler_flags; #if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099 @@ -162,23 +191,33 @@ static ulong fix_handler_flags(THD *thd, TABLE *table, TABLE *altered_table, Alt #endif // workaround for fill_alter_inplace_info bug (#5193) - // the function erroneously sets the ADD_INDEX and DROP_INDEX flags for a column addition that does not - // change the keys. the following code turns the ADD_INDEX and DROP_INDEX flags so that we can do hot - // column addition later. - if (handler_flags & (Alter_inplace_info::ADD_COLUMN + Alter_inplace_info::DROP_COLUMN)) { - if (handler_flags & (Alter_inplace_info::ADD_INDEX + Alter_inplace_info::DROP_INDEX)) { - if (tables_have_same_keys(table, altered_table, THDVAR(thd, alter_print_error) != 0, false)) { - handler_flags &= ~(Alter_inplace_info::ADD_INDEX + Alter_inplace_info::DROP_INDEX); + // the function erroneously sets the ADD_INDEX and DROP_INDEX flags for a + // column addition that does not change the keys. + // the following code turns the ADD_INDEX and DROP_INDEX flags so that + // we can do hot column addition later. + if (handler_flags & + (Alter_inplace_info::ADD_COLUMN + Alter_inplace_info::DROP_COLUMN)) { + if (handler_flags & + (Alter_inplace_info::ADD_INDEX + Alter_inplace_info::DROP_INDEX)) { + if (tables_have_same_keys( + table, + altered_table, + tokudb::sysvars::alter_print_error(thd) != 0, false)) { + handler_flags &= + ~(Alter_inplace_info::ADD_INDEX + + Alter_inplace_info::DROP_INDEX); } } } - // always allow rename table + any other operation, so turn off the rename flag + // always allow rename table + any other operation, so turn off the + // rename flag if (handler_flags & Alter_inplace_info::TOKU_ALTER_RENAME) { handler_flags &= ~Alter_inplace_info::TOKU_ALTER_RENAME; } - // ALTER_COLUMN_TYPE may be set when no columns have been changed, so turn off the flag + // ALTER_COLUMN_TYPE may be set when no columns have been changed, + // so turn off the flag if (handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) { if (all_fields_are_same_type(table, altered_table)) { handler_flags &= ~Alter_inplace_info::ALTER_COLUMN_TYPE; @@ -191,9 +230,10 @@ static ulong fix_handler_flags(THD *thd, TABLE *table, TABLE *altered_table, Alt // Require that there is no intersection of add and drop names. static bool is_disjoint_add_drop(Alter_inplace_info *ha_alter_info) { for (uint d = 0; d < ha_alter_info->index_drop_count; d++) { - KEY *drop_key = ha_alter_info->index_drop_buffer[d]; + KEY* drop_key = ha_alter_info->index_drop_buffer[d]; for (uint a = 0; a < ha_alter_info->index_add_count; a++) { - KEY *add_key = &ha_alter_info->key_info_buffer[ha_alter_info->index_add_buffer[a]]; + KEY* add_key = + &ha_alter_info->key_info_buffer[ha_alter_info->index_add_buffer[a]]; if (strcmp(drop_key->name, add_key->name) == 0) { return false; } @@ -202,196 +242,294 @@ static bool is_disjoint_add_drop(Alter_inplace_info *ha_alter_info) { return true; } -// Return true if some bit in mask is set and no bit in ~mask is set, otherwise return false. +// Return true if some bit in mask is set and no bit in ~mask is set, +// otherwise return false. static bool only_flags(ulong bits, ulong mask) { return (bits & mask) != 0 && (bits & ~mask) == 0; } -// Check if an alter table operation on this table and described by the alter table parameters is supported inplace -// and if so, what type of locking is needed to execute it. -// return values: +// Check if an alter table operation on this table and described by the alter +// table parameters is supported inplace and if so, what type of locking is +// needed to execute it. return values: + +// HA_ALTER_INPLACE_NOT_SUPPORTED: alter operation is not supported as an +// inplace operation, a table copy is required -// HA_ALTER_INPLACE_NOT_SUPPORTED: alter operation is not supported as an inplace operation, a table copy is required // HA_ALTER_ERROR: the alter table operation should fail // HA_ALTER_INPLACE_EXCLUSIVE_LOCK: prepare and alter runs with MDL X -// HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE: prepare runs with MDL X, alter runs with MDL SNW -// HA_ALTER_INPLACE_SHARED_LOCK: prepare and alter methods called with MDL SNW, concurrent reads, no writes +// HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE: prepare runs with MDL X, +// alter runs with MDL SNW + +// HA_ALTER_INPLACE_SHARED_LOCK: prepare and alter methods called with MDL SNW, +// concurrent reads, no writes + +// HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE: prepare runs with MDL X, +// alter runs with MDL SW + +// HA_ALTER_INPLACE_NO_LOCK: prepare and alter methods called with MDL SW, +// concurrent reads, writes. +// must set WRITE_ALLOW_WRITE lock type in the external lock method to avoid +// deadlocks with the MDL lock and the table lock +enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { -// HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE: prepare runs with MDL X, alter runs with MDL SW -// HA_ALTER_INPLACE_NO_LOCK: prepare and alter methods called with MDL SW, concurrent reads, writes. -// must set WRITE_ALLOW_WRITE lock type in the external lock method to avoid deadlocks -// with the MDL lock and the table lock -enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { TOKUDB_HANDLER_DBUG_ENTER(""); - if (tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ALTER_TABLE))) { print_alter_info(altered_table, ha_alter_info); } - enum_alter_inplace_result result = HA_ALTER_INPLACE_NOT_SUPPORTED; // default is NOT inplace - THD *thd = ha_thd(); + // default is NOT inplace + enum_alter_inplace_result result = HA_ALTER_INPLACE_NOT_SUPPORTED; + THD* thd = ha_thd(); // setup context - tokudb_alter_ctx *ctx = new tokudb_alter_ctx; + tokudb_alter_ctx* ctx = new tokudb_alter_ctx; ha_alter_info->handler_ctx = ctx; - ctx->handler_flags = fix_handler_flags(thd, table, altered_table, ha_alter_info); + ctx->handler_flags = + fix_handler_flags(thd, table, altered_table, ha_alter_info); ctx->table_kc_info = &share->kc_info; ctx->altered_table_kc_info = &ctx->altered_table_kc_info_base; memset(ctx->altered_table_kc_info, 0, sizeof (KEY_AND_COL_INFO)); - if (get_disable_hot_alter(thd)) { + if (tokudb::sysvars::disable_hot_alter(thd)) { ; // do nothing - } else - // add or drop index - if (only_flags(ctx->handler_flags, Alter_inplace_info::DROP_INDEX + Alter_inplace_info::DROP_UNIQUE_INDEX + - Alter_inplace_info::ADD_INDEX + Alter_inplace_info::ADD_UNIQUE_INDEX)) { + } else if (only_flags( + ctx->handler_flags, + Alter_inplace_info::DROP_INDEX + + Alter_inplace_info::DROP_UNIQUE_INDEX + + Alter_inplace_info::ADD_INDEX + + Alter_inplace_info::ADD_UNIQUE_INDEX)) { + // add or drop index if (table->s->null_bytes == altered_table->s->null_bytes && - (ha_alter_info->index_add_count > 0 || ha_alter_info->index_drop_count > 0) && - !tables_have_same_keys(table, altered_table, THDVAR(thd, alter_print_error) != 0, false) && + (ha_alter_info->index_add_count > 0 || + ha_alter_info->index_drop_count > 0) && + !tables_have_same_keys( + table, + altered_table, + tokudb::sysvars::alter_print_error(thd) != 0, false) && is_disjoint_add_drop(ha_alter_info)) { - if (ctx->handler_flags & (Alter_inplace_info::DROP_INDEX + Alter_inplace_info::DROP_UNIQUE_INDEX)) { - // the fractal tree can not handle dropping an index concurrent with querying with the index. + if (ctx->handler_flags & + (Alter_inplace_info::DROP_INDEX + + Alter_inplace_info::DROP_UNIQUE_INDEX)) { + // the fractal tree can not handle dropping an index concurrent + // with querying with the index. // we grab an exclusive MDL for the drop index. result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } else { result = HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE; - // someday, allow multiple hot indexes via alter table add key. don't forget to change the store_lock function. - // for now, hot indexing is only supported via session variable with the create index sql command - if (ha_alter_info->index_add_count == 1 && ha_alter_info->index_drop_count == 0 && // only one add or drop - ctx->handler_flags == Alter_inplace_info::ADD_INDEX && // must be add index not add unique index - thd_sql_command(thd) == SQLCOM_CREATE_INDEX && // must be a create index command - get_create_index_online(thd)) { // must be enabled - // external_lock set WRITE_ALLOW_WRITE which allows writes concurrent with the index creation + // someday, allow multiple hot indexes via alter table add key. + // don't forget to change the store_lock function. + // for now, hot indexing is only supported via session variable + // with the create index sql command + if (ha_alter_info->index_add_count == 1 && + // only one add or drop + ha_alter_info->index_drop_count == 0 && + // must be add index not add unique index + ctx->handler_flags == Alter_inplace_info::ADD_INDEX && + // must be a create index command + thd_sql_command(thd) == SQLCOM_CREATE_INDEX && + // must be enabled + tokudb::sysvars::create_index_online(thd)) { + // external_lock set WRITE_ALLOW_WRITE which allows writes + // concurrent with the index creation result = HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE; } } } - } else - // column default - if (only_flags(ctx->handler_flags, Alter_inplace_info::ALTER_COLUMN_DEFAULT)) { + } else if (only_flags( + ctx->handler_flags, + Alter_inplace_info::ALTER_COLUMN_DEFAULT)) { + // column default if (table->s->null_bytes == altered_table->s->null_bytes) result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; - } else - // column rename - if (ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_NAME && - only_flags(ctx->handler_flags, Alter_inplace_info::ALTER_COLUMN_NAME + Alter_inplace_info::ALTER_COLUMN_DEFAULT)) { - // we have identified a possible column rename, + } else if (ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_NAME && + only_flags( + ctx->handler_flags, + Alter_inplace_info::ALTER_COLUMN_NAME + + Alter_inplace_info::ALTER_COLUMN_DEFAULT)) { + // column rename + // we have identified a possible column rename, // but let's do some more checks - + // we will only allow an hcr if there are no changes // in column positions (ALTER_COLUMN_ORDER is not set) - + // now need to verify that one and only one column // has changed only its name. If we find anything to // the contrary, we don't allow it, also check indexes if (table->s->null_bytes == altered_table->s->null_bytes) { - bool cr_supported = column_rename_supported(table, altered_table, (ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_ORDER) != 0); + bool cr_supported = + column_rename_supported( + table, + altered_table, + (ctx->handler_flags & + Alter_inplace_info::ALTER_COLUMN_ORDER) != 0); if (cr_supported) result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } else - // add column - if (ctx->handler_flags & Alter_inplace_info::ADD_COLUMN && - only_flags(ctx->handler_flags, Alter_inplace_info::ADD_COLUMN + Alter_inplace_info::ALTER_COLUMN_ORDER) && - setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { - + } else if (ctx->handler_flags & Alter_inplace_info::ADD_COLUMN && + only_flags( + ctx->handler_flags, + Alter_inplace_info::ADD_COLUMN + + Alter_inplace_info::ALTER_COLUMN_ORDER) && + setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { + + // add column uint32_t added_columns[altered_table->s->fields]; uint32_t num_added_columns = 0; - int r = find_changed_columns(added_columns, &num_added_columns, table, altered_table); + int r = + find_changed_columns( + added_columns, + &num_added_columns, + table, + altered_table); if (r == 0) { - if (tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ALTER_TABLE))) { for (uint32_t i = 0; i < num_added_columns; i++) { uint32_t curr_added_index = added_columns[i]; - Field* curr_added_field = altered_table->field[curr_added_index]; - printf("Added column: index %d, name %s\n", curr_added_index, curr_added_field->field_name); + Field* curr_added_field = + altered_table->field[curr_added_index]; + TOKUDB_TRACE( + "Added column: index %d, name %s", + curr_added_index, + curr_added_field->field_name); } } result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } else - // drop column - if (ctx->handler_flags & Alter_inplace_info::DROP_COLUMN && - only_flags(ctx->handler_flags, Alter_inplace_info::DROP_COLUMN + Alter_inplace_info::ALTER_COLUMN_ORDER) && - setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { - + } else if (ctx->handler_flags & Alter_inplace_info::DROP_COLUMN && + only_flags( + ctx->handler_flags, + Alter_inplace_info::DROP_COLUMN + + Alter_inplace_info::ALTER_COLUMN_ORDER) && + setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { + + // drop column uint32_t dropped_columns[table->s->fields]; uint32_t num_dropped_columns = 0; - int r = find_changed_columns(dropped_columns, &num_dropped_columns, altered_table, table); + int r = + find_changed_columns( + dropped_columns, + &num_dropped_columns, + altered_table, + table); if (r == 0) { - if (tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ALTER_TABLE))) { for (uint32_t i = 0; i < num_dropped_columns; i++) { uint32_t curr_dropped_index = dropped_columns[i]; Field* curr_dropped_field = table->field[curr_dropped_index]; - printf("Dropped column: index %d, name %s\n", curr_dropped_index, curr_dropped_field->field_name); + TOKUDB_TRACE( + "Dropped column: index %d, name %s", + curr_dropped_index, + curr_dropped_field->field_name); } } result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } else - // change column length - if ((ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH) && - only_flags(ctx->handler_flags, Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH + Alter_inplace_info::ALTER_COLUMN_DEFAULT) && - table->s->fields == altered_table->s->fields && - find_changed_fields(table, altered_table, ctx->changed_fields) > 0 && - setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { - - if (change_length_is_supported(table, altered_table, ha_alter_info, ctx)) { + } else if ((ctx->handler_flags & + Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH) && + only_flags( + ctx->handler_flags, + Alter_inplace_info::ALTER_COLUMN_EQUAL_PACK_LENGTH + + Alter_inplace_info::ALTER_COLUMN_DEFAULT) && + table->s->fields == altered_table->s->fields && + find_changed_fields( + table, + altered_table, + ctx->changed_fields) > 0 && + setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { + + // change column length + if (change_length_is_supported( + table, + altered_table, + ha_alter_info, ctx)) { result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } else - // change column type - if ((ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) && - only_flags(ctx->handler_flags, Alter_inplace_info::ALTER_COLUMN_TYPE + Alter_inplace_info::ALTER_COLUMN_DEFAULT) && - table->s->fields == altered_table->s->fields && - find_changed_fields(table, altered_table, ctx->changed_fields) > 0 && - setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { - - if (change_type_is_supported(table, altered_table, ha_alter_info, ctx)) { + } else if ((ctx->handler_flags & Alter_inplace_info::ALTER_COLUMN_TYPE) && + only_flags( + ctx->handler_flags, + Alter_inplace_info::ALTER_COLUMN_TYPE + + Alter_inplace_info::ALTER_COLUMN_DEFAULT) && + table->s->fields == altered_table->s->fields && + find_changed_fields( + table, + altered_table, + ctx->changed_fields) > 0 && + setup_kc_info(altered_table, ctx->altered_table_kc_info) == 0) { + + // change column type + if (change_type_is_supported( + table, + altered_table, + ha_alter_info, ctx)) { result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } else - if (only_flags(ctx->handler_flags, Alter_inplace_info::CHANGE_CREATE_OPTION)) { - HA_CREATE_INFO *create_info = ha_alter_info->create_info; + } else if (only_flags( + ctx->handler_flags, + Alter_inplace_info::CHANGE_CREATE_OPTION)) { + + HA_CREATE_INFO* create_info = ha_alter_info->create_info; #if TOKU_INCLUDE_OPTION_STRUCTS // set the USED_ROW_FORMAT flag for use later in this file for changes in the table's // compression - if (create_info->option_struct->row_format != table_share->option_struct->row_format) + if (create_info->option_struct->row_format != + table_share->option_struct->row_format) create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT; #endif // alter auto_increment if (only_flags(create_info->used_fields, HA_CREATE_USED_AUTO)) { // do a sanity check that the table is what we think it is - if (tables_have_same_keys_and_columns(table, altered_table, THDVAR(thd, alter_print_error) != 0)) { + if (tables_have_same_keys_and_columns( + table, + altered_table, + tokudb::sysvars::alter_print_error(thd) != 0)) { result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } - } - // alter row_format - else if (only_flags(create_info->used_fields, HA_CREATE_USED_ROW_FORMAT)) { + } else if (only_flags( + create_info->used_fields, + HA_CREATE_USED_ROW_FORMAT)) { + // alter row_format // do a sanity check that the table is what we think it is - if (tables_have_same_keys_and_columns(table, altered_table, THDVAR(thd, alter_print_error) != 0)) { + if (tables_have_same_keys_and_columns( + table, + altered_table, + tokudb::sysvars::alter_print_error(thd) != 0)) { result = HA_ALTER_INPLACE_EXCLUSIVE_LOCK; } } - } + } #if TOKU_OPTIMIZE_WITH_RECREATE - else if (only_flags(ctx->handler_flags, Alter_inplace_info::RECREATE_TABLE + Alter_inplace_info::ALTER_COLUMN_DEFAULT)) { + else if (only_flags( + ctx->handler_flags, + Alter_inplace_info::RECREATE_TABLE + + Alter_inplace_info::ALTER_COLUMN_DEFAULT)) { ctx->optimize_needed = true; result = HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE; } #endif - if (result != HA_ALTER_INPLACE_NOT_SUPPORTED && table->s->null_bytes != altered_table->s->null_bytes && - (tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE)) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ALTER_TABLE)) && + result != HA_ALTER_INPLACE_NOT_SUPPORTED && + table->s->null_bytes != altered_table->s->null_bytes) { + TOKUDB_HANDLER_TRACE("q %s", thd->query()); - TOKUDB_HANDLER_TRACE("null bytes %u -> %u", table->s->null_bytes, altered_table->s->null_bytes); + TOKUDB_HANDLER_TRACE( + "null bytes %u -> %u", + table->s->null_bytes, + altered_table->s->null_bytes); } - // turn a not supported result into an error if the slow alter table (copy) is disabled - if (result == HA_ALTER_INPLACE_NOT_SUPPORTED && get_disable_slow_alter(thd)) { + // turn a not supported result into an error if the slow alter table + // (copy) is disabled + if (result == HA_ALTER_INPLACE_NOT_SUPPORTED && + tokudb::sysvars::disable_slow_alter(thd)) { print_error(HA_ERR_UNSUPPORTED, MYF(0)); result = HA_ALTER_ERROR; } @@ -400,46 +538,77 @@ enum_alter_inplace_result ha_tokudb::check_if_supported_inplace_alter(TABLE *alt } // Prepare for the alter operations -bool ha_tokudb::prepare_inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +bool ha_tokudb::prepare_inplace_alter_table( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + TOKUDB_HANDLER_DBUG_ENTER(""); - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); - assert(transaction); // transaction must exist after table is locked + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); + assert_always(transaction); // transaction must exist after table is locked ctx->alter_txn = transaction; bool result = false; // success DBUG_RETURN(result); } // Execute the alter operations. -bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +bool ha_tokudb::inplace_alter_table( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + TOKUDB_HANDLER_DBUG_ENTER(""); int error = 0; - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); - HA_CREATE_INFO *create_info = ha_alter_info->create_info; - - if (error == 0 && (ctx->handler_flags & (Alter_inplace_info::DROP_INDEX + Alter_inplace_info::DROP_UNIQUE_INDEX))) { + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); + HA_CREATE_INFO* create_info = ha_alter_info->create_info; + + // this should be enough to handle locking as the higher level MDL + // on this table should prevent any new analyze tasks. + share->cancel_background_jobs(); + + if (error == 0 && + (ctx->handler_flags & + (Alter_inplace_info::DROP_INDEX + + Alter_inplace_info::DROP_UNIQUE_INDEX))) { error = alter_table_drop_index(altered_table, ha_alter_info); } - if (error == 0 && (ctx->handler_flags & (Alter_inplace_info::ADD_INDEX + Alter_inplace_info::ADD_UNIQUE_INDEX))) { + if (error == 0 && + (ctx->handler_flags & + (Alter_inplace_info::ADD_INDEX + + Alter_inplace_info::ADD_UNIQUE_INDEX))) { error = alter_table_add_index(altered_table, ha_alter_info); } - if (error == 0 && (ctx->handler_flags & (Alter_inplace_info::ADD_COLUMN + Alter_inplace_info::DROP_COLUMN))) { + if (error == 0 && + (ctx->handler_flags & + (Alter_inplace_info::ADD_COLUMN + + Alter_inplace_info::DROP_COLUMN))) { error = alter_table_add_or_drop_column(altered_table, ha_alter_info); } - if (error == 0 && (ctx->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) && (create_info->used_fields & HA_CREATE_USED_AUTO)) { - error = write_auto_inc_create(share->status_block, create_info->auto_increment_value, ctx->alter_txn); + if (error == 0 && + (ctx->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) && + (create_info->used_fields & HA_CREATE_USED_AUTO)) { + error = write_auto_inc_create( + share->status_block, + create_info->auto_increment_value, + ctx->alter_txn); } - if (error == 0 && (ctx->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) && (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { + if (error == 0 && + (ctx->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) && + (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) { // Get the current compression DB *db = share->key_file[0]; error = db->get_compression_method(db, &ctx->orig_compression_method); - assert(error == 0); + assert_always(error == 0); // Set the new compression #if TOKU_INCLUDE_OPTION_STRUCTS - toku_compression_method method = row_format_to_toku_compression_method((srv_row_format_t) create_info->option_struct->row_format); + toku_compression_method method = + row_format_to_toku_compression_method( + (tokudb::sysvars::row_format_t)create_info->option_struct->row_format); #else - toku_compression_method method = row_type_to_toku_compression_method(create_info->row_type); + toku_compression_method method = + row_type_to_toku_compression_method(create_info->row_type); #endif uint32_t curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); for (uint32_t i = 0; i < curr_num_DBs; i++) { @@ -457,13 +626,19 @@ bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha error = alter_table_expand_columns(altered_table, ha_alter_info); if (error == 0 && ctx->expand_varchar_update_needed) - error = alter_table_expand_varchar_offsets(altered_table, ha_alter_info); + error = alter_table_expand_varchar_offsets( + altered_table, + ha_alter_info); if (error == 0 && ctx->expand_blob_update_needed) error = alter_table_expand_blobs(altered_table, ha_alter_info); if (error == 0 && ctx->reset_card) { - error = tokudb::alter_card(share->status_block, ctx->alter_txn, table->s, altered_table->s); + error = tokudb::alter_card( + share->status_block, + ctx->alter_txn, + table->s, + altered_table->s); } if (error == 0 && ctx->optimize_needed) { error = do_optimize(ha_thd()); @@ -472,11 +647,15 @@ bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha #if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) #if WITH_PARTITION_STORAGE_ENGINE - if (error == 0 && (TOKU_PARTITION_WRITE_FRM_DATA || altered_table->part_info == NULL)) { + if (error == 0 && + (TOKU_PARTITION_WRITE_FRM_DATA || altered_table->part_info == NULL)) { #else if (error == 0) { #endif - error = write_frm_data(share->status_block, ctx->alter_txn, altered_table->s->path.str); + error = write_frm_data( + share->status_block, + ctx->alter_txn, + altered_table->s->path.str); } #endif @@ -489,20 +668,34 @@ bool ha_tokudb::inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha DBUG_RETURN(result); } -int ha_tokudb::alter_table_add_index(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +int ha_tokudb::alter_table_add_index( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { // sort keys in add index order - KEY *key_info = (KEY*) tokudb_my_malloc(sizeof (KEY) * ha_alter_info->index_add_count, MYF(MY_WME)); + KEY* key_info = (KEY*)tokudb::memory::malloc( + sizeof(KEY) * ha_alter_info->index_add_count, + MYF(MY_WME)); for (uint i = 0; i < ha_alter_info->index_add_count; i++) { KEY *key = &key_info[i]; *key = ha_alter_info->key_info_buffer[ha_alter_info->index_add_buffer[i]]; - for (KEY_PART_INFO *key_part= key->key_part; key_part < key->key_part + get_key_parts(key); key_part++) + for (KEY_PART_INFO* key_part = key->key_part; + key_part < key->key_part + get_key_parts(key); + key_part++) { key_part->field = table->field[key_part->fieldnr]; + } } - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); ctx->add_index_changed = true; - int error = tokudb_add_index(table, key_info, ha_alter_info->index_add_count, ctx->alter_txn, &ctx->incremented_num_DBs, &ctx->modified_DBs); + int error = tokudb_add_index( + table, + key_info, + ha_alter_info->index_add_count, + ctx->alter_txn, + &ctx->incremented_num_DBs, + &ctx->modified_DBs); if (error == HA_ERR_FOUND_DUPP_KEY) { // hack for now, in case of duplicate key error, // because at the moment we cannot display the right key @@ -511,7 +704,7 @@ int ha_tokudb::alter_table_add_index(TABLE *altered_table, Alter_inplace_info *h last_dup_key = MAX_KEY; } - tokudb_my_free(key_info); + tokudb::memory::free(key_info); if (error == 0) ctx->reset_card = true; @@ -519,7 +712,11 @@ int ha_tokudb::alter_table_add_index(TABLE *altered_table, Alter_inplace_info *h return error; } -static bool find_index_of_key(const char *key_name, TABLE *table, uint *index_offset_ptr) { +static bool find_index_of_key( + const char* key_name, + TABLE* table, + uint* index_offset_ptr) { + for (uint i = 0; i < table->s->keys; i++) { if (strcmp(key_name, table->key_info[i].name) == 0) { *index_offset_ptr = i; @@ -529,7 +726,12 @@ static bool find_index_of_key(const char *key_name, TABLE *table, uint *index_of return false; } -static bool find_index_of_key(const char *key_name, KEY *key_info, uint key_count, uint *index_offset_ptr) { +static bool find_index_of_key( + const char* key_name, + KEY* key_info, + uint key_count, + uint* index_offset_ptr) { + for (uint i = 0; i < key_count; i++) { if (strcmp(key_name, key_info[i].name) == 0) { *index_offset_ptr = i; @@ -539,26 +741,42 @@ static bool find_index_of_key(const char *key_name, KEY *key_info, uint key_coun return false; } -int ha_tokudb::alter_table_drop_index(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +int ha_tokudb::alter_table_drop_index( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + KEY *key_info = table->key_info; // translate key names to indexes into the key_info array uint index_drop_offsets[ha_alter_info->index_drop_count]; for (uint i = 0; i < ha_alter_info->index_drop_count; i++) { bool found; - found = find_index_of_key(ha_alter_info->index_drop_buffer[i]->name, table, &index_drop_offsets[i]); + found = find_index_of_key( + ha_alter_info->index_drop_buffer[i]->name, + table, + &index_drop_offsets[i]); if (!found) { // undo of add key in partition engine - found = find_index_of_key(ha_alter_info->index_drop_buffer[i]->name, ha_alter_info->key_info_buffer, ha_alter_info->key_count, &index_drop_offsets[i]); - assert(found); + found = find_index_of_key( + ha_alter_info->index_drop_buffer[i]->name, + ha_alter_info->key_info_buffer, + ha_alter_info->key_count, + &index_drop_offsets[i]); + assert_always(found); key_info = ha_alter_info->key_info_buffer; } } // drop indexes - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); ctx->drop_index_changed = true; - int error = drop_indexes(table, index_drop_offsets, ha_alter_info->index_drop_count, key_info, ctx->alter_txn); + int error = drop_indexes( + table, + index_drop_offsets, + ha_alter_info->index_drop_count, + key_info, + ctx->alter_txn); if (error == 0) ctx->reset_card = true; @@ -566,93 +784,122 @@ int ha_tokudb::alter_table_drop_index(TABLE *altered_table, Alter_inplace_info * return error; } -int ha_tokudb::alter_table_add_or_drop_column(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); +int ha_tokudb::alter_table_add_or_drop_column( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); int error; uchar *column_extra = NULL; uint32_t max_column_extra_size; uint32_t num_column_extra; uint32_t num_columns = 0; uint32_t curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); - - uint32_t columns[table->s->fields + altered_table->s->fields]; // set size such that we know it is big enough for both cases + // set size such that we know it is big enough for both cases + uint32_t columns[table->s->fields + altered_table->s->fields]; memset(columns, 0, sizeof(columns)); // generate the array of columns if (ha_alter_info->handler_flags & Alter_inplace_info::DROP_COLUMN) { find_changed_columns( - columns, - &num_columns, - altered_table, - table - ); - } else - if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN) { + columns, + &num_columns, + altered_table, + table); + } else if (ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN) { find_changed_columns( - columns, - &num_columns, - table, - altered_table - ); - } else - assert(0); + columns, + &num_columns, + table, + altered_table); + } else { + assert_unreachable(); + } max_column_extra_size = - STATIC_ROW_MUTATOR_SIZE + //max static row_mutator - 4 + num_columns*(1+1+4+1+1+4) + altered_table->s->reclength + // max dynamic row_mutator - (4 + share->kc_info.num_blobs) + // max static blob size - (num_columns*(1+4+1+4)); // max dynamic blob size - column_extra = (uchar *)tokudb_my_malloc(max_column_extra_size, MYF(MY_WME)); - if (column_extra == NULL) { error = ENOMEM; goto cleanup; } + // max static row_mutator + STATIC_ROW_MUTATOR_SIZE + + // max dynamic row_mutator + 4 + num_columns*(1+1+4+1+1+4) + altered_table->s->reclength + + // max static blob size + (4 + share->kc_info.num_blobs) + + // max dynamic blob size + (num_columns*(1+4+1+4)); + column_extra = (uchar*)tokudb::memory::malloc( + max_column_extra_size, + MYF(MY_WME)); + if (column_extra == NULL) { + error = ENOMEM; + goto cleanup; + } for (uint32_t i = 0; i < curr_num_DBs; i++) { // change to a new descriptor DBT row_descriptor; memset(&row_descriptor, 0, sizeof row_descriptor); - error = new_row_descriptor(table, altered_table, ha_alter_info, i, &row_descriptor); + error = new_row_descriptor( + table, + altered_table, + ha_alter_info, + i, + &row_descriptor); if (error) goto cleanup; - error = share->key_file[i]->change_descriptor(share->key_file[i], ctx->alter_txn, &row_descriptor, 0); - tokudb_my_free(row_descriptor.data); + error = share->key_file[i]->change_descriptor( + share->key_file[i], + ctx->alter_txn, + &row_descriptor, + 0); + tokudb::memory::free(row_descriptor.data); if (error) goto cleanup; if (i == primary_key || key_is_clustering(&table_share->key_info[i])) { num_column_extra = fill_row_mutator( - column_extra, - columns, - num_columns, - altered_table, - ctx->altered_table_kc_info, - i, - (ha_alter_info->handler_flags & Alter_inplace_info::ADD_COLUMN) != 0 // true if adding columns, otherwise is a drop - ); + column_extra, + columns, + num_columns, + altered_table, + ctx->altered_table_kc_info, + i, + // true if adding columns, otherwise is a drop + (ha_alter_info->handler_flags & + Alter_inplace_info::ADD_COLUMN) != 0); DBT column_dbt; memset(&column_dbt, 0, sizeof column_dbt); column_dbt.data = column_extra; column_dbt.size = num_column_extra; DBUG_ASSERT(num_column_extra <= max_column_extra_size); error = share->key_file[i]->update_broadcast( - share->key_file[i], - ctx->alter_txn, - &column_dbt, - DB_IS_RESETTING_OP - ); - if (error) { goto cleanup; } + share->key_file[i], + ctx->alter_txn, + &column_dbt, + DB_IS_RESETTING_OP); + if (error) { + goto cleanup; + } } } error = 0; cleanup: - tokudb_my_free(column_extra); + tokudb::memory::free(column_extra); return error; } // Commit or abort the alter operations. -// If commit then write the new frm data to the status using the alter transaction. -// If abort then abort the alter transaction and try to rollback the non-transactional changes. -bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_info *ha_alter_info, bool commit) { +// If commit then write the new frm data to the status using the alter +// transaction. +// If abort then abort the alter transaction and try to rollback the +// non-transactional changes. +bool ha_tokudb::commit_inplace_alter_table( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + bool commit) { + TOKUDB_HANDLER_DBUG_ENTER(""); - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); bool result = false; // success THD *thd = ha_thd(); @@ -671,7 +918,10 @@ bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_i #else if (true) { #endif - int error = write_frm_data(share->status_block, ctx->alter_txn, altered_table->s->path.str); + int error = write_frm_data( + share->status_block, + ctx->alter_txn, + altered_table->s->path.str); if (error) { commit = false; result = true; @@ -683,42 +933,55 @@ bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_i if (!commit) { if (table->mdl_ticket->get_type() != MDL_EXCLUSIVE && - (ctx->add_index_changed || ctx->drop_index_changed || ctx->compression_changed)) { + (ctx->add_index_changed || ctx->drop_index_changed || + ctx->compression_changed)) { // get exclusive lock no matter what #if defined(MARIADB_BASE_VERSION) killed_state saved_killed_state = thd->killed; thd->killed = NOT_KILLED; - for (volatile uint i = 0; wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED); i++) { + for (volatile uint i = 0; + wait_while_table_is_used(thd, table, HA_EXTRA_NOT_USED); + i++) { if (thd->killed != NOT_KILLED) thd->killed = NOT_KILLED; sleep(1); } - assert(table->mdl_ticket->get_type() == MDL_EXCLUSIVE); + assert_always(table->mdl_ticket->get_type() == MDL_EXCLUSIVE); if (thd->killed == NOT_KILLED) thd->killed = saved_killed_state; #else THD::killed_state saved_killed_state = thd->killed; thd->killed = THD::NOT_KILLED; - // MySQL does not handle HA_EXTRA_NOT_USED so we use HA_EXTRA_PREPARE_FOR_RENAME since it is passed through + // MySQL does not handle HA_EXTRA_NOT_USED so we use + // HA_EXTRA_PREPARE_FOR_RENAME since it is passed through // the partition storage engine and is treated as a NOP by tokudb - for (volatile uint i = 0; wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME); i++) { + for (volatile uint i = 0; + wait_while_table_is_used( + thd, + table, + HA_EXTRA_PREPARE_FOR_RENAME); + i++) { if (thd->killed != THD::NOT_KILLED) thd->killed = THD::NOT_KILLED; sleep(1); } - assert(table->mdl_ticket->get_type() == MDL_EXCLUSIVE); + assert_always(table->mdl_ticket->get_type() == MDL_EXCLUSIVE); if (thd->killed == THD::NOT_KILLED) thd->killed = saved_killed_state; #endif } - // abort the alter transaction NOW so that any alters are rolled back. this allows the following restores to work. - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); - assert(ctx->alter_txn == trx->stmt); - assert(trx->tokudb_lock_count > 0); - // for partitioned tables, we use a single transaction to do all of the partition changes. the tokudb_lock_count - // is a reference count for each of the handlers to the same transaction. obviously, we want to only abort once. + // abort the alter transaction NOW so that any alters are rolled back. + // this allows the following restores to work. + tokudb_trx_data* trx = + (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); + assert_always(ctx->alter_txn == trx->stmt); + assert_always(trx->tokudb_lock_count > 0); + // for partitioned tables, we use a single transaction to do all of the + // partition changes. the tokudb_lock_count is a reference count for + // each of the handlers to the same transaction. obviously, we want + // to only abort once. if (trx->tokudb_lock_count > 0) { if (--trx->tokudb_lock_count <= trx->create_lock_count) { trx->create_lock_count = 0; @@ -731,82 +994,125 @@ bool ha_tokudb::commit_inplace_alter_table(TABLE *altered_table, Alter_inplace_i } if (ctx->add_index_changed) { - restore_add_index(table, ha_alter_info->index_add_count, ctx->incremented_num_DBs, ctx->modified_DBs); + restore_add_index( + table, + ha_alter_info->index_add_count, + ctx->incremented_num_DBs, + ctx->modified_DBs); } if (ctx->drop_index_changed) { // translate key names to indexes into the key_info array uint index_drop_offsets[ha_alter_info->index_drop_count]; for (uint i = 0; i < ha_alter_info->index_drop_count; i++) { - bool found = find_index_of_key(ha_alter_info->index_drop_buffer[i]->name, table, &index_drop_offsets[i]); - assert(found); + bool found = find_index_of_key( + ha_alter_info->index_drop_buffer[i]->name, + table, + &index_drop_offsets[i]); + assert_always(found); } - restore_drop_indexes(table, index_drop_offsets, ha_alter_info->index_drop_count); + restore_drop_indexes( + table, + index_drop_offsets, + ha_alter_info->index_drop_count); } if (ctx->compression_changed) { - uint32_t curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); + uint32_t curr_num_DBs = + table->s->keys + tokudb_test(hidden_primary_key); for (uint32_t i = 0; i < curr_num_DBs; i++) { DB *db = share->key_file[i]; - int error = db->change_compression_method(db, ctx->orig_compression_method); - assert(error == 0); + int error = db->change_compression_method( + db, + ctx->orig_compression_method); + assert_always(error == 0); } } } - DBUG_RETURN(result); } // Setup the altered table's key and col info. -int ha_tokudb::setup_kc_info(TABLE *altered_table, KEY_AND_COL_INFO *altered_kc_info) { +int ha_tokudb::setup_kc_info( + TABLE* altered_table, + KEY_AND_COL_INFO* altered_kc_info) { + int error = allocate_key_and_col_info(altered_table->s, altered_kc_info); if (error == 0) - error = initialize_key_and_col_info(altered_table->s, altered_table, altered_kc_info, hidden_primary_key, primary_key); + error = initialize_key_and_col_info( + altered_table->s, + altered_table, + altered_kc_info, + hidden_primary_key, + primary_key); return error; } // Expand the variable length fields offsets from 1 to 2 bytes. -int ha_tokudb::alter_table_expand_varchar_offsets(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +int ha_tokudb::alter_table_expand_varchar_offsets( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + int error = 0; - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); uint32_t curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); for (uint32_t i = 0; i < curr_num_DBs; i++) { // change to a new descriptor DBT row_descriptor; memset(&row_descriptor, 0, sizeof row_descriptor); - error = new_row_descriptor(table, altered_table, ha_alter_info, i, &row_descriptor); + error = new_row_descriptor( + table, + altered_table, + ha_alter_info, + i, + &row_descriptor); if (error) break; - error = share->key_file[i]->change_descriptor(share->key_file[i], ctx->alter_txn, &row_descriptor, 0); - tokudb_my_free(row_descriptor.data); + error = share->key_file[i]->change_descriptor( + share->key_file[i], + ctx->alter_txn, + &row_descriptor, + 0); + tokudb::memory::free(row_descriptor.data); if (error) break; - // for all trees that have values, make an update variable offsets message and broadcast it into the tree + // for all trees that have values, make an update variable offsets + // message and broadcast it into the tree if (i == primary_key || key_is_clustering(&table_share->key_info[i])) { - uint32_t offset_start = table_share->null_bytes + share->kc_info.mcp_info[i].fixed_field_size; - uint32_t offset_end = offset_start + share->kc_info.mcp_info[i].len_of_offsets; + uint32_t offset_start = + table_share->null_bytes + + share->kc_info.mcp_info[i].fixed_field_size; + uint32_t offset_end = + offset_start + + share->kc_info.mcp_info[i].len_of_offsets; uint32_t number_of_offsets = offset_end - offset_start; // make the expand variable offsets message DBT expand; memset(&expand, 0, sizeof expand); - expand.size = sizeof (uchar) + sizeof offset_start + sizeof offset_end; - expand.data = tokudb_my_malloc(expand.size, MYF(MY_WME)); + expand.size = + sizeof(uchar) + sizeof(offset_start) + sizeof(offset_end); + expand.data = tokudb::memory::malloc(expand.size, MYF(MY_WME)); if (!expand.data) { error = ENOMEM; break; } - uchar *expand_ptr = (uchar *)expand.data; + uchar* expand_ptr = (uchar*)expand.data; expand_ptr[0] = UPDATE_OP_EXPAND_VARIABLE_OFFSETS; - expand_ptr += sizeof (uchar); + expand_ptr += sizeof(uchar); - memcpy(expand_ptr, &number_of_offsets, sizeof number_of_offsets); - expand_ptr += sizeof number_of_offsets; + memcpy(expand_ptr, &number_of_offsets, sizeof(number_of_offsets)); + expand_ptr += sizeof(number_of_offsets); - memcpy(expand_ptr, &offset_start, sizeof offset_start); - expand_ptr += sizeof offset_start; + memcpy(expand_ptr, &offset_start, sizeof(offset_start)); + expand_ptr += sizeof(offset_start); // and broadcast it into the tree - error = share->key_file[i]->update_broadcast(share->key_file[i], ctx->alter_txn, &expand, DB_IS_RESETTING_OP); - tokudb_my_free(expand.data); + error = share->key_file[i]->update_broadcast( + share->key_file[i], + ctx->alter_txn, + &expand, + DB_IS_RESETTING_OP); + tokudb::memory::free(expand.data); if (error) break; } @@ -834,30 +1140,49 @@ static bool field_in_key_of_table(TABLE *table, Field *field) { return false; } -// Return true if all changed varchar/varbinary field lengths can be changed inplace, otherwise return false -static bool change_varchar_length_is_supported(Field *old_field, Field *new_field, TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, tokudb_alter_ctx *ctx) { +// Return true if all changed varchar/varbinary field lengths can be changed +// inplace, otherwise return false +static bool change_varchar_length_is_supported( + Field* old_field, + Field* new_field, + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + tokudb_alter_ctx* ctx) { + if (old_field->real_type() != MYSQL_TYPE_VARCHAR || new_field->real_type() != MYSQL_TYPE_VARCHAR || old_field->binary() != new_field->binary() || old_field->charset()->number != new_field->charset()->number || old_field->field_length > new_field->field_length) return false; - if (ctx->table_kc_info->num_offset_bytes > ctx->altered_table_kc_info->num_offset_bytes) + if (ctx->table_kc_info->num_offset_bytes > + ctx->altered_table_kc_info->num_offset_bytes) return false; // shrink is not supported - if (ctx->table_kc_info->num_offset_bytes < ctx->altered_table_kc_info->num_offset_bytes) - ctx->expand_varchar_update_needed = true; // sum of varchar lengths changed from 1 to 2 + if (ctx->table_kc_info->num_offset_bytes < + ctx->altered_table_kc_info->num_offset_bytes) + // sum of varchar lengths changed from 1 to 2 + ctx->expand_varchar_update_needed = true; return true; } -// Return true if all changed field lengths can be changed inplace, otherwise return false -static bool change_length_is_supported(TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, tokudb_alter_ctx *ctx) { +// Return true if all changed field lengths can be changed inplace, otherwise +// return false +static bool change_length_is_supported( + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + tokudb_alter_ctx* ctx) { + if (table->s->fields != altered_table->s->fields) return false; if (table->s->null_bytes != altered_table->s->null_bytes) return false; if (ctx->changed_fields.elements() > 1) return false; // only support one field change - for (DYNAMIC_ARRAY_ELEMENTS_TYPE ai = 0; ai < ctx->changed_fields.elements(); ai++) { + for (DYNAMIC_ARRAY_ELEMENTS_TYPE ai = 0; + ai < ctx->changed_fields.elements(); + ai++) { uint i = ctx->changed_fields.at(ai); Field *old_field = table->field[i]; Field *new_field = altered_table->field[i]; @@ -865,9 +1190,16 @@ static bool change_length_is_supported(TABLE *table, TABLE *altered_table, Alter return false; // no type conversions if (old_field->real_type() != MYSQL_TYPE_VARCHAR) return false; // only varchar - if (field_in_key_of_table(table, old_field) || field_in_key_of_table(altered_table, new_field)) + if (field_in_key_of_table(table, old_field) || + field_in_key_of_table(altered_table, new_field)) return false; // not in any key - if (!change_varchar_length_is_supported(old_field, new_field, table, altered_table, ha_alter_info, ctx)) + if (!change_varchar_length_is_supported( + old_field, + new_field, + table, + altered_table, + ha_alter_info, + ctx)) return false; } @@ -886,13 +1218,23 @@ static bool is_sorted(Dynamic_array &a) { return r; } -int ha_tokudb::alter_table_expand_columns(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +int ha_tokudb::alter_table_expand_columns( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + int error = 0; - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); - assert(is_sorted(ctx->changed_fields)); // since we build the changed_fields array in field order, it must be sorted - for (DYNAMIC_ARRAY_ELEMENTS_TYPE ai = 0; error == 0 && ai < ctx->changed_fields.elements(); ai++) { + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); + // since we build the changed_fields array in field order, it must be sorted + assert_always(is_sorted(ctx->changed_fields)); + for (DYNAMIC_ARRAY_ELEMENTS_TYPE ai = 0; + error == 0 && ai < ctx->changed_fields.elements(); + ai++) { uint expand_field_num = ctx->changed_fields.at(ai); - error = alter_table_expand_one_column(altered_table, ha_alter_info, expand_field_num); + error = alter_table_expand_one_column( + altered_table, + ha_alter_info, + expand_field_num); } return error; @@ -903,10 +1245,15 @@ static bool is_unsigned(Field *f) { return (f->flags & UNSIGNED_FLAG) != 0; } -// Return the starting offset in the value for a particular index (selected by idx) of a -// particular field (selected by expand_field_num) +// Return the starting offset in the value for a particular index (selected by +// idx) of a particular field (selected by expand_field_num) // TODO: replace this? -static uint32_t alter_table_field_offset(uint32_t null_bytes, KEY_AND_COL_INFO *kc_info, int idx, int expand_field_num) { +static uint32_t alter_table_field_offset( + uint32_t null_bytes, + KEY_AND_COL_INFO* kc_info, + int idx, + int expand_field_num) { + uint32_t offset = null_bytes; for (int i = 0; i < expand_field_num; i++) { if (bitmap_is_set(&kc_info->key_filters[idx], i)) // skip key fields @@ -917,21 +1264,26 @@ static uint32_t alter_table_field_offset(uint32_t null_bytes, KEY_AND_COL_INFO * } // Send an expand message into all clustered indexes including the primary -int ha_tokudb::alter_table_expand_one_column(TABLE *altered_table, Alter_inplace_info *ha_alter_info, int expand_field_num) { +int ha_tokudb::alter_table_expand_one_column( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + int expand_field_num) { + int error = 0; - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); Field *old_field = table->field[expand_field_num]; TOKU_TYPE old_field_type = mysql_to_toku_type(old_field); Field *new_field = altered_table->field[expand_field_num]; TOKU_TYPE new_field_type = mysql_to_toku_type(new_field); - assert(old_field_type == new_field_type); + assert_always(old_field_type == new_field_type); uchar operation; uchar pad_char; switch (old_field_type) { case toku_type_int: - assert(is_unsigned(old_field) == is_unsigned(new_field)); + assert_always(is_unsigned(old_field) == is_unsigned(new_field)); if (is_unsigned(old_field)) operation = UPDATE_OP_EXPAND_UINT; else @@ -947,38 +1299,61 @@ int ha_tokudb::alter_table_expand_one_column(TABLE *altered_table, Alter_inplace pad_char = 0; break; default: - assert(0); + assert_unreachable(); } uint32_t curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); for (uint32_t i = 0; i < curr_num_DBs; i++) { // change to a new descriptor DBT row_descriptor; memset(&row_descriptor, 0, sizeof row_descriptor); - error = new_row_descriptor(table, altered_table, ha_alter_info, i, &row_descriptor); + error = new_row_descriptor( + table, + altered_table, + ha_alter_info, + i, + &row_descriptor); if (error) break; - error = share->key_file[i]->change_descriptor(share->key_file[i], ctx->alter_txn, &row_descriptor, 0); - tokudb_my_free(row_descriptor.data); + error = share->key_file[i]->change_descriptor( + share->key_file[i], + ctx->alter_txn, + &row_descriptor, + 0); + tokudb::memory::free(row_descriptor.data); if (error) break; - // for all trees that have values, make an expand update message and broadcast it into the tree + // for all trees that have values, make an expand update message and + // broadcast it into the tree if (i == primary_key || key_is_clustering(&table_share->key_info[i])) { - uint32_t old_offset = alter_table_field_offset(table_share->null_bytes, ctx->table_kc_info, i, expand_field_num); - uint32_t new_offset = alter_table_field_offset(table_share->null_bytes, ctx->altered_table_kc_info, i, expand_field_num); - assert(old_offset <= new_offset); - - uint32_t old_length = ctx->table_kc_info->field_lengths[expand_field_num]; - assert(old_length == old_field->pack_length()); - - uint32_t new_length = ctx->altered_table_kc_info->field_lengths[expand_field_num]; - assert(new_length == new_field->pack_length()); - - DBT expand; memset(&expand, 0, sizeof expand); - expand.size = sizeof operation + sizeof new_offset + sizeof old_length + sizeof new_length; - if (operation == UPDATE_OP_EXPAND_CHAR || operation == UPDATE_OP_EXPAND_BINARY) - expand.size += sizeof pad_char; - expand.data = tokudb_my_malloc(expand.size, MYF(MY_WME)); + uint32_t old_offset = alter_table_field_offset( + table_share->null_bytes, + ctx->table_kc_info, + i, + expand_field_num); + uint32_t new_offset = alter_table_field_offset( + table_share->null_bytes, + ctx->altered_table_kc_info, + i, + expand_field_num); + assert_always(old_offset <= new_offset); + + uint32_t old_length = + ctx->table_kc_info->field_lengths[expand_field_num]; + assert_always(old_length == old_field->pack_length()); + + uint32_t new_length = + ctx->altered_table_kc_info->field_lengths[expand_field_num]; + assert_always(new_length == new_field->pack_length()); + + DBT expand; memset(&expand, 0, sizeof(expand)); + expand.size = + sizeof(operation) + sizeof(new_offset) + + sizeof(old_length) + sizeof(new_length); + if (operation == UPDATE_OP_EXPAND_CHAR || + operation == UPDATE_OP_EXPAND_BINARY) + expand.size += sizeof(pad_char); + expand.data = tokudb::memory::malloc(expand.size, MYF(MY_WME)); if (!expand.data) { error = ENOMEM; break; @@ -987,27 +1362,34 @@ int ha_tokudb::alter_table_expand_one_column(TABLE *altered_table, Alter_inplace expand_ptr[0] = operation; expand_ptr += sizeof operation; - // for the first altered field, old_offset == new_offset. for the subsequent altered fields, the new_offset - // should be used as it includes the length changes from the previous altered fields. - memcpy(expand_ptr, &new_offset, sizeof new_offset); - expand_ptr += sizeof new_offset; + // for the first altered field, old_offset == new_offset. + // for the subsequent altered fields, the new_offset + // should be used as it includes the length changes from the + // previous altered fields. + memcpy(expand_ptr, &new_offset, sizeof(new_offset)); + expand_ptr += sizeof(new_offset); - memcpy(expand_ptr, &old_length, sizeof old_length); - expand_ptr += sizeof old_length; + memcpy(expand_ptr, &old_length, sizeof(old_length)); + expand_ptr += sizeof(old_length); - memcpy(expand_ptr, &new_length, sizeof new_length); - expand_ptr += sizeof new_length; + memcpy(expand_ptr, &new_length, sizeof(new_length)); + expand_ptr += sizeof(new_length); - if (operation == UPDATE_OP_EXPAND_CHAR || operation == UPDATE_OP_EXPAND_BINARY) { - memcpy(expand_ptr, &pad_char, sizeof pad_char); - expand_ptr += sizeof pad_char; + if (operation == UPDATE_OP_EXPAND_CHAR || + operation == UPDATE_OP_EXPAND_BINARY) { + memcpy(expand_ptr, &pad_char, sizeof(pad_char)); + expand_ptr += sizeof(pad_char); } - assert(expand_ptr == (uchar *)expand.data + expand.size); + assert_always(expand_ptr == (uchar*)expand.data + expand.size); // and broadcast it into the tree - error = share->key_file[i]->update_broadcast(share->key_file[i], ctx->alter_txn, &expand, DB_IS_RESETTING_OP); - tokudb_my_free(expand.data); + error = share->key_file[i]->update_broadcast( + share->key_file[i], + ctx->alter_txn, + &expand, + DB_IS_RESETTING_OP); + tokudb::memory::free(expand.data); if (error) break; } @@ -1016,52 +1398,85 @@ int ha_tokudb::alter_table_expand_one_column(TABLE *altered_table, Alter_inplace return error; } -static void marshall_blob_lengths(tokudb::buffer &b, uint32_t n, TABLE *table, KEY_AND_COL_INFO *kc_info) { +static void marshall_blob_lengths( + tokudb::buffer& b, + uint32_t n, + TABLE* table, + KEY_AND_COL_INFO* kc_info) { + for (uint i = 0; i < n; i++) { uint blob_field_index = kc_info->blob_fields[i]; - assert(blob_field_index < table->s->fields); - uint8_t blob_field_length = table->s->field[blob_field_index]->row_pack_length(); + assert_always(blob_field_index < table->s->fields); + uint8_t blob_field_length = + table->s->field[blob_field_index]->row_pack_length(); b.append(&blob_field_length, sizeof blob_field_length); } } -int ha_tokudb::alter_table_expand_blobs(TABLE *altered_table, Alter_inplace_info *ha_alter_info) { +int ha_tokudb::alter_table_expand_blobs( + TABLE* altered_table, + Alter_inplace_info* ha_alter_info) { + int error = 0; - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); uint32_t curr_num_DBs = table->s->keys + tokudb_test(hidden_primary_key); for (uint32_t i = 0; i < curr_num_DBs; i++) { // change to a new descriptor DBT row_descriptor; memset(&row_descriptor, 0, sizeof row_descriptor); - error = new_row_descriptor(table, altered_table, ha_alter_info, i, &row_descriptor); + error = new_row_descriptor( + table, + altered_table, + ha_alter_info, + i, + &row_descriptor); if (error) break; - error = share->key_file[i]->change_descriptor(share->key_file[i], ctx->alter_txn, &row_descriptor, 0); - tokudb_my_free(row_descriptor.data); + error = share->key_file[i]->change_descriptor( + share->key_file[i], + ctx->alter_txn, + &row_descriptor, + 0); + tokudb::memory::free(row_descriptor.data); if (error) break; - // for all trees that have values, make an update blobs message and broadcast it into the tree + // for all trees that have values, make an update blobs message and + // broadcast it into the tree if (i == primary_key || key_is_clustering(&table_share->key_info[i])) { tokudb::buffer b; uint8_t op = UPDATE_OP_EXPAND_BLOB; b.append(&op, sizeof op); - b.append_ui(table->s->null_bytes + ctx->table_kc_info->mcp_info[i].fixed_field_size); - uint32_t var_offset_bytes = ctx->table_kc_info->mcp_info[i].len_of_offsets; + b.append_ui( + table->s->null_bytes + + ctx->table_kc_info->mcp_info[i].fixed_field_size); + uint32_t var_offset_bytes = + ctx->table_kc_info->mcp_info[i].len_of_offsets; b.append_ui(var_offset_bytes); - b.append_ui(var_offset_bytes == 0 ? 0 : ctx->table_kc_info->num_offset_bytes); + b.append_ui( + var_offset_bytes == 0 ? 0 : + ctx->table_kc_info->num_offset_bytes); // add blobs info uint32_t num_blobs = ctx->table_kc_info->num_blobs; b.append_ui(num_blobs); marshall_blob_lengths(b, num_blobs, table, ctx->table_kc_info); - marshall_blob_lengths(b, num_blobs, altered_table, ctx->altered_table_kc_info); + marshall_blob_lengths( + b, + num_blobs, + altered_table, + ctx->altered_table_kc_info); // and broadcast it into the tree DBT expand; memset(&expand, 0, sizeof expand); expand.data = b.data(); expand.size = b.size(); - error = share->key_file[i]->update_broadcast(share->key_file[i], ctx->alter_txn, &expand, DB_IS_RESETTING_OP); + error = share->key_file[i]->update_broadcast( + share->key_file[i], + ctx->alter_txn, + &expand, + DB_IS_RESETTING_OP); if (error) break; } @@ -1071,7 +1486,13 @@ int ha_tokudb::alter_table_expand_blobs(TABLE *altered_table, Alter_inplace_info } // Return true if two fixed length fields can be changed inplace -static bool change_fixed_length_is_supported(TABLE *table, TABLE *altered_table, Field *old_field, Field *new_field, tokudb_alter_ctx *ctx) { +static bool change_fixed_length_is_supported( + TABLE* table, + TABLE* altered_table, + Field* old_field, + Field* new_field, + tokudb_alter_ctx* ctx) { + // no change in size is supported if (old_field->pack_length() == new_field->pack_length()) return true; @@ -1082,9 +1503,16 @@ static bool change_fixed_length_is_supported(TABLE *table, TABLE *altered_table, return true; } -static bool change_blob_length_is_supported(TABLE *table, TABLE *altered_table, Field *old_field, Field *new_field, tokudb_alter_ctx *ctx) { +static bool change_blob_length_is_supported( + TABLE* table, + TABLE* altered_table, + Field* old_field, + Field* new_field, + tokudb_alter_ctx* ctx) { + // blob -> longer or equal length blob - if (old_field->binary() && new_field->binary() && old_field->pack_length() <= new_field->pack_length()) { + if (old_field->binary() && new_field->binary() && + old_field->pack_length() <= new_field->pack_length()) { ctx->expand_blob_update_needed = true; return true; } @@ -1113,13 +1541,26 @@ static bool is_int_type(enum_field_types t) { } // Return true if two field types can be changed inplace -static bool change_field_type_is_supported(Field *old_field, Field *new_field, TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, tokudb_alter_ctx *ctx) { +static bool change_field_type_is_supported( + Field* old_field, + Field* new_field, + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + tokudb_alter_ctx* ctx) { + enum_field_types old_type = old_field->real_type(); enum_field_types new_type = new_field->real_type(); if (is_int_type(old_type)) { // int and unsigned int expansion - if (is_int_type(new_type) && is_unsigned(old_field) == is_unsigned(new_field)) - return change_fixed_length_is_supported(table, altered_table, old_field, new_field, ctx); + if (is_int_type(new_type) && + is_unsigned(old_field) == is_unsigned(new_field)) + return change_fixed_length_is_supported( + table, + altered_table, + old_field, + new_field, + ctx); else return false; } else if (old_type == MYSQL_TYPE_STRING) { @@ -1127,67 +1568,112 @@ static bool change_field_type_is_supported(Field *old_field, Field *new_field, T if (new_type == MYSQL_TYPE_STRING && old_field->binary() == new_field->binary() && old_field->charset()->number == new_field->charset()->number) - return change_fixed_length_is_supported(table, altered_table, old_field, new_field, ctx); + return change_fixed_length_is_supported( + table, + altered_table, + old_field, + new_field, + ctx); else return false; } else if (old_type == MYSQL_TYPE_VARCHAR) { - // varchar(X) -> varchar(Y) and varbinary(X) -> varbinary(Y) expansion where X < 256 <= Y - // the ALTER_COLUMN_TYPE handler flag is set for these cases - return change_varchar_length_is_supported(old_field, new_field, table, altered_table, ha_alter_info, ctx); + // varchar(X) -> varchar(Y) and varbinary(X) -> varbinary(Y) expansion + // where X < 256 <= Y the ALTER_COLUMN_TYPE handler flag is set for + // these cases + return change_varchar_length_is_supported( + old_field, + new_field, + table, + altered_table, + ha_alter_info, + ctx); } else if (old_type == MYSQL_TYPE_BLOB && new_type == MYSQL_TYPE_BLOB) { - return change_blob_length_is_supported(table, altered_table, old_field, new_field, ctx); + return change_blob_length_is_supported( + table, + altered_table, + old_field, + new_field, + ctx); } else return false; } // Return true if all changed field types can be changed inplace -static bool change_type_is_supported(TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, tokudb_alter_ctx *ctx) { +static bool change_type_is_supported( + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + tokudb_alter_ctx* ctx) { + if (table->s->null_bytes != altered_table->s->null_bytes) return false; if (table->s->fields != altered_table->s->fields) return false; if (ctx->changed_fields.elements() > 1) return false; // only support one field change - for (DYNAMIC_ARRAY_ELEMENTS_TYPE ai = 0; ai < ctx->changed_fields.elements(); ai++) { + for (DYNAMIC_ARRAY_ELEMENTS_TYPE ai = 0; + ai < ctx->changed_fields.elements(); + ai++) { uint i = ctx->changed_fields.at(ai); Field *old_field = table->field[i]; Field *new_field = altered_table->field[i]; - if (field_in_key_of_table(table, old_field) || field_in_key_of_table(altered_table, new_field)) + if (field_in_key_of_table(table, old_field) || + field_in_key_of_table(altered_table, new_field)) return false; - if (!change_field_type_is_supported(old_field, new_field, table, altered_table, ha_alter_info, ctx)) + if (!change_field_type_is_supported( + old_field, + new_field, + table, + altered_table, + ha_alter_info, + ctx)) return false; } return true; } -// Allocate and initialize a new descriptor for a dictionary in the altered table identified with idx. +// Allocate and initialize a new descriptor for a dictionary in the altered +// table identified with idx. // Return the new descriptor in the row_descriptor DBT. // Return non-zero on error. -int ha_tokudb::new_row_descriptor(TABLE *table, TABLE *altered_table, Alter_inplace_info *ha_alter_info, uint32_t idx, DBT *row_descriptor) { +int ha_tokudb::new_row_descriptor( + TABLE* table, + TABLE* altered_table, + Alter_inplace_info* ha_alter_info, + uint32_t idx, + DBT* row_descriptor) { + int error = 0; - tokudb_alter_ctx *ctx = static_cast(ha_alter_info->handler_ctx); - row_descriptor->size = get_max_desc_size(ctx->altered_table_kc_info, altered_table); - row_descriptor->data = (uchar *) tokudb_my_malloc(row_descriptor->size, MYF(MY_WME)); + tokudb_alter_ctx* ctx = + static_cast(ha_alter_info->handler_ctx); + row_descriptor->size = + get_max_desc_size(ctx->altered_table_kc_info, altered_table); + row_descriptor->data = + (uchar*)tokudb::memory::malloc(row_descriptor->size, MYF(MY_WME)); if (row_descriptor->data == NULL) { error = ENOMEM; } else { - KEY* prim_key = hidden_primary_key ? NULL : &altered_table->s->key_info[primary_key]; + KEY* prim_key = + hidden_primary_key ? NULL : + &altered_table->s->key_info[primary_key]; if (idx == primary_key) { - row_descriptor->size = create_main_key_descriptor((uchar *)row_descriptor->data, - prim_key, - hidden_primary_key, - primary_key, - altered_table, - ctx->altered_table_kc_info); + row_descriptor->size = create_main_key_descriptor( + (uchar*)row_descriptor->data, + prim_key, + hidden_primary_key, + primary_key, + altered_table, + ctx->altered_table_kc_info); } else { - row_descriptor->size = create_secondary_key_descriptor((uchar *)row_descriptor->data, - &altered_table->key_info[idx], - prim_key, - hidden_primary_key, - altered_table, - primary_key, - idx, - ctx->altered_table_kc_info); + row_descriptor->size = create_secondary_key_descriptor( + (uchar*)row_descriptor->data, + &altered_table->key_info[idx], + prim_key, + hidden_primary_key, + altered_table, + primary_key, + idx, + ctx->altered_table_kc_info); } error = 0; } diff --git a/storage/tokudb/ha_tokudb_alter_common.cc b/storage/tokudb/ha_tokudb_alter_common.cc index b2c2a2b0252b6..c58f57b4da78b 100644 --- a/storage/tokudb/ha_tokudb_alter_common.cc +++ b/storage/tokudb/ha_tokudb_alter_common.cc @@ -26,8 +26,18 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #if !defined(TOKUDB_ALTER_COMMON) #define TOKUDB_ALTER_COMMON -static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print_error, bool check_field_index) __attribute__((unused)); -static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print_error, bool check_field_index) { +TOKUDB_UNUSED(static bool tables_have_same_keys( + TABLE* table, + TABLE* altered_table, + bool print_error, + bool check_field_index)); + +static bool tables_have_same_keys( + TABLE* table, + TABLE* altered_table, + bool print_error, + bool check_field_index) { + bool retval; if (table->s->keys != altered_table->s->keys) { if (print_error) { @@ -39,10 +49,9 @@ static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print if (table->s->primary_key != altered_table->s->primary_key) { if (print_error) { sql_print_error( - "Tables have different primary keys, %d %d", + "Tables have different primary keys, %d %d", table->s->primary_key, - altered_table->s->primary_key - ); + altered_table->s->primary_key); } retval = false; goto cleanup; @@ -53,33 +62,32 @@ static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print if (strcmp(curr_orig_key->name, curr_altered_key->name)) { if (print_error) { sql_print_error( - "key %d has different name, %s %s", - i, + "key %d has different name, %s %s", + i, curr_orig_key->name, - curr_altered_key->name - ); + curr_altered_key->name); } retval = false; goto cleanup; } - if (key_is_clustering(curr_orig_key) != key_is_clustering(curr_altered_key)) { + if (key_is_clustering(curr_orig_key) != + key_is_clustering(curr_altered_key)) { if (print_error) { sql_print_error( "keys disagree on if they are clustering, %d, %d", get_key_parts(curr_orig_key), - get_key_parts(curr_altered_key) - ); + get_key_parts(curr_altered_key)); } retval = false; goto cleanup; } - if (((curr_orig_key->flags & HA_NOSAME) == 0) != ((curr_altered_key->flags & HA_NOSAME) == 0)) { + if (((curr_orig_key->flags & HA_NOSAME) == 0) != + ((curr_altered_key->flags & HA_NOSAME) == 0)) { if (print_error) { sql_print_error( "keys disagree on if they are unique, %d, %d", get_key_parts(curr_orig_key), - get_key_parts(curr_altered_key) - ); + get_key_parts(curr_altered_key)); } retval = false; goto cleanup; @@ -89,8 +97,7 @@ static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print sql_print_error( "keys have different number of parts, %d, %d", get_key_parts(curr_orig_key), - get_key_parts(curr_altered_key) - ); + get_key_parts(curr_altered_key)); } retval = false; goto cleanup; @@ -106,10 +113,9 @@ static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print if (curr_orig_part->length != curr_altered_part->length) { if (print_error) { sql_print_error( - "Key %s has different length at index %d", - curr_orig_key->name, - j - ); + "Key %s has different length at index %d", + curr_orig_key->name, + j); } retval = false; goto cleanup; @@ -123,10 +129,9 @@ static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print if (!are_fields_same) { if (print_error) { sql_print_error( - "Key %s has different field at index %d", - curr_orig_key->name, - j - ); + "Key %s has different field at index %d", + curr_orig_key->name, + j); } retval = false; goto cleanup; @@ -143,7 +148,8 @@ static bool tables_have_same_keys(TABLE* table, TABLE* altered_table, bool print // to evaluate whether a field is NULL or not. This value is a power of 2, from // 2^0 to 2^7. We return the position of the bit within the byte, which is // lg null_bit -static inline uint32_t get_null_bit_position(uint32_t null_bit) __attribute__((unused)); +TOKUDB_UNUSED(static inline uint32_t get_null_bit_position( + uint32_t null_bit)); static inline uint32_t get_null_bit_position(uint32_t null_bit) { uint32_t retval = 0; switch(null_bit) { @@ -170,23 +176,28 @@ static inline uint32_t get_null_bit_position(uint32_t null_bit) { break; case (128): retval = 7; - break; + break; default: - assert(false); + assert_unreachable(); } return retval; } // returns the index of the null bit of field. -static inline uint32_t get_overall_null_bit_position(TABLE* table, Field* field) __attribute__((unused)); -static inline uint32_t get_overall_null_bit_position(TABLE* table, Field* field) { +TOKUDB_UNUSED(static inline uint32_t get_overall_null_bit_position( + TABLE* table, + Field* field)); +static inline uint32_t get_overall_null_bit_position( + TABLE* table, + Field* field) { + uint32_t offset = get_null_offset(table, field); uint32_t null_bit = field->null_bit; return offset*8 + get_null_bit_position(null_bit); } // not static since 51 uses this and 56 does not -static bool are_null_bits_in_order(TABLE* table) __attribute__((unused)); +TOKUDB_UNUSED(static bool are_null_bits_in_order(TABLE* table)); static bool are_null_bits_in_order(TABLE* table) { uint32_t curr_null_pos = 0; bool first = true; @@ -195,10 +206,8 @@ static bool are_null_bits_in_order(TABLE* table) { Field* curr_field = table->field[i]; bool nullable = (curr_field->null_bit != 0); if (nullable) { - uint32_t pos = get_overall_null_bit_position( - table, - curr_field - ); + uint32_t pos = + get_overall_null_bit_position(table, curr_field); if (!first && pos != curr_null_pos+1){ retval = false; break; @@ -210,34 +219,38 @@ static bool are_null_bits_in_order(TABLE* table) { return retval; } -static uint32_t get_first_null_bit_pos(TABLE* table) __attribute__((unused)); +TOKUDB_UNUSED(static uint32_t get_first_null_bit_pos(TABLE* table)); static uint32_t get_first_null_bit_pos(TABLE* table) { uint32_t table_pos = 0; for (uint i = 0; i < table->s->fields; i++) { Field* curr_field = table->field[i]; bool nullable = (curr_field->null_bit != 0); if (nullable) { - table_pos = get_overall_null_bit_position( - table, - curr_field - ); + table_pos = + get_overall_null_bit_position(table, curr_field); break; } } return table_pos; } -static bool is_column_default_null(TABLE* src_table, uint32_t field_index) __attribute__((unused)); -static bool is_column_default_null(TABLE* src_table, uint32_t field_index) { +TOKUDB_UNUSED(static bool is_column_default_null( + TABLE* src_table, + uint32_t field_index)); +static bool is_column_default_null( + TABLE* src_table, + uint32_t field_index) { + Field* curr_field = src_table->field[field_index]; bool is_null_default = false; bool nullable = curr_field->null_bit != 0; if (nullable) { - uint32_t null_bit_position = get_overall_null_bit_position(src_table, curr_field); - is_null_default = is_overall_null_position_set( - src_table->s->default_values, - null_bit_position - ); + uint32_t null_bit_position = + get_overall_null_bit_position(src_table, curr_field); + is_null_default = + is_overall_null_position_set( + src_table->s->default_values, + null_bit_position); } return is_null_default; } @@ -248,9 +261,8 @@ static uint32_t fill_static_row_mutator( TABLE* altered_table, KEY_AND_COL_INFO* orig_kc_info, KEY_AND_COL_INFO* altered_kc_info, - uint32_t keynr - ) -{ + uint32_t keynr) { + // // start packing extra // @@ -258,25 +270,28 @@ static uint32_t fill_static_row_mutator( // says what the operation is pos[0] = UP_COL_ADD_OR_DROP; pos++; - + // // null byte information // memcpy(pos, &orig_table->s->null_bytes, sizeof(orig_table->s->null_bytes)); pos += sizeof(orig_table->s->null_bytes); - memcpy(pos, &altered_table->s->null_bytes, sizeof(orig_table->s->null_bytes)); + memcpy( + pos, + &altered_table->s->null_bytes, + sizeof(orig_table->s->null_bytes)); pos += sizeof(altered_table->s->null_bytes); - + // // num_offset_bytes // - assert(orig_kc_info->num_offset_bytes <= 2); + assert_always(orig_kc_info->num_offset_bytes <= 2); pos[0] = orig_kc_info->num_offset_bytes; pos++; - assert(altered_kc_info->num_offset_bytes <= 2); + assert_always(altered_kc_info->num_offset_bytes <= 2); pos[0] = altered_kc_info->num_offset_bytes; pos++; - + // // size of fixed fields // @@ -286,7 +301,7 @@ static uint32_t fill_static_row_mutator( fixed_field_size = altered_kc_info->mcp_info[keynr].fixed_field_size; memcpy(pos, &fixed_field_size, sizeof(fixed_field_size)); pos += sizeof(fixed_field_size); - + // // length of offsets // @@ -304,7 +319,7 @@ static uint32_t fill_static_row_mutator( memcpy(pos, &altered_start_null_pos, sizeof(altered_start_null_pos)); pos += sizeof(altered_start_null_pos); - assert((pos-buf) == STATIC_ROW_MUTATOR_SIZE); + assert_always((pos-buf) == STATIC_ROW_MUTATOR_SIZE); return pos - buf; } @@ -316,9 +331,8 @@ static uint32_t fill_dynamic_row_mutator( KEY_AND_COL_INFO* src_kc_info, uint32_t keynr, bool is_add, - bool* out_has_blobs - ) -{ + bool* out_has_blobs) { + uchar* pos = buf; bool has_blobs = false; uint32_t cols = num_columns; @@ -327,7 +341,7 @@ static uint32_t fill_dynamic_row_mutator( for (uint32_t i = 0; i < num_columns; i++) { uint32_t curr_index = columns[i]; Field* curr_field = src_table->field[curr_index]; - + pos[0] = is_add ? COL_ADD : COL_DROP; pos++; // @@ -338,22 +352,22 @@ static uint32_t fill_dynamic_row_mutator( if (!nullable) { pos[0] = 0; pos++; - } - else { + } else { pos[0] = 1; pos++; // write position of null byte that is to be removed - uint32_t null_bit_position = get_overall_null_bit_position(src_table, curr_field); + uint32_t null_bit_position = + get_overall_null_bit_position(src_table, curr_field); memcpy(pos, &null_bit_position, sizeof(null_bit_position)); pos += sizeof(null_bit_position); // // if adding a column, write the value of the default null_bit // if (is_add) { - is_null_default = is_overall_null_position_set( - src_table->s->default_values, - null_bit_position - ); + is_null_default = + is_overall_null_position_set( + src_table->s->default_values, + null_bit_position); pos[0] = is_null_default ? 1 : 0; pos++; } @@ -364,7 +378,8 @@ static uint32_t fill_dynamic_row_mutator( pos[0] = COL_FIXED; pos++; //store the offset - uint32_t fixed_field_offset = src_kc_info->cp_info[keynr][curr_index].col_pack_val; + uint32_t fixed_field_offset = + src_kc_info->cp_info[keynr][curr_index].col_pack_val; memcpy(pos, &fixed_field_offset, sizeof(fixed_field_offset)); pos += sizeof(fixed_field_offset); //store the number of bytes @@ -374,38 +389,35 @@ static uint32_t fill_dynamic_row_mutator( if (is_add && !is_null_default) { uint curr_field_offset = field_offset(curr_field, src_table); memcpy( - pos, - src_table->s->default_values + curr_field_offset, - num_bytes - ); + pos, + src_table->s->default_values + curr_field_offset, + num_bytes); pos += num_bytes; } - } - else if (is_variable_field(src_kc_info, curr_index)) { + } else if (is_variable_field(src_kc_info, curr_index)) { pos[0] = COL_VAR; pos++; //store the index of the variable column - uint32_t var_field_index = src_kc_info->cp_info[keynr][curr_index].col_pack_val; + uint32_t var_field_index = + src_kc_info->cp_info[keynr][curr_index].col_pack_val; memcpy(pos, &var_field_index, sizeof(var_field_index)); pos += sizeof(var_field_index); if (is_add && !is_null_default) { uint curr_field_offset = field_offset(curr_field, src_table); uint32_t len_bytes = src_kc_info->length_bytes[curr_index]; - uint32_t data_length = get_var_data_length( - src_table->s->default_values + curr_field_offset, - len_bytes - ); + uint32_t data_length = + get_var_data_length( + src_table->s->default_values + curr_field_offset, + len_bytes); memcpy(pos, &data_length, sizeof(data_length)); pos += sizeof(data_length); memcpy( pos, src_table->s->default_values + curr_field_offset + len_bytes, - data_length - ); + data_length); pos += data_length; } - } - else { + } else { pos[0] = COL_BLOB; pos++; has_blobs = true; @@ -418,9 +430,8 @@ static uint32_t fill_dynamic_row_mutator( static uint32_t fill_static_blob_row_mutator( uchar* buf, TABLE* src_table, - KEY_AND_COL_INFO* src_kc_info - ) -{ + KEY_AND_COL_INFO* src_kc_info) { + uchar* pos = buf; // copy number of blobs memcpy(pos, &src_kc_info->num_blobs, sizeof(src_kc_info->num_blobs)); @@ -430,11 +441,11 @@ static uint32_t fill_static_blob_row_mutator( uint32_t curr_field_index = src_kc_info->blob_fields[i]; Field* field = src_table->field[curr_field_index]; uint32_t len_bytes = field->row_pack_length(); - assert(len_bytes <= 4); + assert_always(len_bytes <= 4); pos[0] = len_bytes; pos++; } - + return pos-buf; } @@ -444,9 +455,8 @@ static uint32_t fill_dynamic_blob_row_mutator( uint32_t num_columns, TABLE* src_table, KEY_AND_COL_INFO* src_kc_info, - bool is_add - ) -{ + bool is_add) { + uchar* pos = buf; for (uint32_t i = 0; i < num_columns; i++) { uint32_t curr_field_index = columns[i]; @@ -461,19 +471,19 @@ static uint32_t fill_dynamic_blob_row_mutator( } } // assert we found blob in list - assert(blob_index < src_kc_info->num_blobs); + assert_always(blob_index < src_kc_info->num_blobs); pos[0] = is_add ? COL_ADD : COL_DROP; pos++; memcpy(pos, &blob_index, sizeof(blob_index)); pos += sizeof(blob_index); if (is_add) { uint32_t len_bytes = curr_field->row_pack_length(); - assert(len_bytes <= 4); + assert_always(len_bytes <= 4); pos[0] = len_bytes; pos++; - // create a zero length blob field that can be directly copied in - // for now, in MySQL, we can only have blob fields + // create a zero length blob field that can be directly copied + // in for now, in MySQL, we can only have blob fields // that have no default value memset(pos, 0, len_bytes); pos += len_bytes; @@ -487,93 +497,86 @@ static uint32_t fill_dynamic_blob_row_mutator( // TODO: namely, when do we get stuff from share->kc_info and when we get // TODO: it from altered_kc_info, and when is keynr associated with the right thing uint32_t ha_tokudb::fill_row_mutator( - uchar* buf, - uint32_t* columns, + uchar* buf, + uint32_t* columns, uint32_t num_columns, TABLE* altered_table, KEY_AND_COL_INFO* altered_kc_info, uint32_t keynr, - bool is_add - ) -{ - if (tokudb_debug & TOKUDB_DEBUG_ALTER_TABLE) { - printf("*****some info:*************\n"); - printf( - "old things: num_null_bytes %d, num_offset_bytes %d, fixed_field_size %d, fixed_field_size %d\n", + bool is_add) { + + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_ALTER_TABLE))) { + TOKUDB_HANDLER_TRACE("*****some info:*************"); + TOKUDB_HANDLER_TRACE( + "old things: num_null_bytes %d, num_offset_bytes %d, " + "fixed_field_size %d, fixed_field_size %d", table->s->null_bytes, share->kc_info.num_offset_bytes, share->kc_info.mcp_info[keynr].fixed_field_size, - share->kc_info.mcp_info[keynr].len_of_offsets - ); - printf( - "new things: num_null_bytes %d, num_offset_bytes %d, fixed_field_size %d, fixed_field_size %d\n", + share->kc_info.mcp_info[keynr].len_of_offsets); + TOKUDB_HANDLER_TRACE( + "new things: num_null_bytes %d, num_offset_bytes %d, " + "fixed_field_size %d, fixed_field_size %d", altered_table->s->null_bytes, altered_kc_info->num_offset_bytes, altered_kc_info->mcp_info[keynr].fixed_field_size, - altered_kc_info->mcp_info[keynr].len_of_offsets - ); - printf("****************************\n"); + altered_kc_info->mcp_info[keynr].len_of_offsets); + TOKUDB_HANDLER_TRACE("****************************"); } uchar* pos = buf; bool has_blobs = false; - pos += fill_static_row_mutator( - pos, - table, - altered_table, - &share->kc_info, - altered_kc_info, - keynr - ); - - if (is_add) { - pos += fill_dynamic_row_mutator( - pos, - columns, - num_columns, - altered_table, - altered_kc_info, - keynr, - is_add, - &has_blobs - ); - } - else { - pos += fill_dynamic_row_mutator( + pos += + fill_static_row_mutator( pos, - columns, - num_columns, table, + altered_table, &share->kc_info, - keynr, - is_add, - &has_blobs - ); - } - if (has_blobs) { - pos += fill_static_blob_row_mutator( - pos, - table, - &share->kc_info - ); - if (is_add) { - pos += fill_dynamic_blob_row_mutator( + altered_kc_info, + keynr); + + if (is_add) { + pos += + fill_dynamic_row_mutator( pos, columns, num_columns, altered_table, altered_kc_info, - is_add - ); - } - else { - pos += fill_dynamic_blob_row_mutator( + keynr, + is_add, + &has_blobs); + } else { + pos += + fill_dynamic_row_mutator( pos, columns, num_columns, table, &share->kc_info, - is_add - ); + keynr, + is_add, + &has_blobs); + } + if (has_blobs) { + pos += fill_static_blob_row_mutator(pos, table, &share->kc_info); + if (is_add) { + pos += + fill_dynamic_blob_row_mutator( + pos, + columns, + num_columns, + altered_table, + altered_kc_info, + is_add); + } else { + pos += + fill_dynamic_blob_row_mutator( + pos, + columns, + num_columns, + table, + &share->kc_info, + is_add); } } return pos-buf; @@ -583,16 +586,23 @@ static bool all_fields_are_same_type(TABLE *table_a, TABLE *table_b) { if (table_a->s->fields != table_b->s->fields) return false; for (uint i = 0; i < table_a->s->fields; i++) { - Field *field_a = table_a->field[i]; - Field *field_b = table_b->field[i]; + Field* field_a = table_a->field[i]; + Field* field_b = table_b->field[i]; if (!fields_are_same_type(field_a, field_b)) return false; } return true; } -static bool column_rename_supported(TABLE* orig_table, TABLE* new_table, bool alter_column_order) __attribute__((unused)); -static bool column_rename_supported(TABLE* orig_table, TABLE* new_table, bool alter_column_order) { +TOKUDB_UNUSED(static bool column_rename_supported( + TABLE* orig_table, + TABLE* new_table, + bool alter_column_order)); +static bool column_rename_supported( + TABLE* orig_table, + TABLE* new_table, + bool alter_column_order) { + bool retval = false; bool keys_same_for_cr; uint num_fields_with_different_names = 0; @@ -622,20 +632,20 @@ static bool column_rename_supported(TABLE* orig_table, TABLE* new_table, bool al retval = false; goto cleanup; } - assert(field_with_different_name < orig_table->s->fields); + assert_always(field_with_different_name < orig_table->s->fields); // // at this point, we have verified that the two tables have - // the same field types and with ONLY one field with a different name. + // the same field types and with ONLY one field with a different name. // We have also identified the field with the different name // // Now we need to check the indexes // - keys_same_for_cr = tables_have_same_keys( - orig_table, - new_table, - false, - true - ); + keys_same_for_cr = + tables_have_same_keys( + orig_table, + new_table, + false, + true); if (!keys_same_for_cr) { retval = false; goto cleanup; @@ -645,12 +655,21 @@ static bool column_rename_supported(TABLE* orig_table, TABLE* new_table, bool al return retval; } -static int find_changed_columns(uint32_t* changed_columns, uint32_t* num_changed_columns, TABLE* smaller_table, TABLE* bigger_table) __attribute__((unused)); -static int find_changed_columns(uint32_t* changed_columns, uint32_t* num_changed_columns, TABLE* smaller_table, TABLE* bigger_table) { +TOKUDB_UNUSED(static int find_changed_columns( + uint32_t* changed_columns, + uint32_t* num_changed_columns, + TABLE* smaller_table, + TABLE* bigger_table)); +static int find_changed_columns( + uint32_t* changed_columns, + uint32_t* num_changed_columns, + TABLE* smaller_table, + TABLE* bigger_table) { + int retval; uint curr_new_col_index = 0; uint32_t curr_num_changed_columns=0; - assert(bigger_table->s->fields > smaller_table->s->fields); + assert_always(bigger_table->s->fields > smaller_table->s->fields); for (uint i = 0; i < smaller_table->s->fields; i++, curr_new_col_index++) { if (curr_new_col_index >= bigger_table->s->fields) { sql_print_error("error in determining changed columns"); @@ -670,15 +689,15 @@ static int find_changed_columns(uint32_t* changed_columns, uint32_t* num_changed goto cleanup; } } - // at this point, curr_field_in_orig and curr_field_in_new should be the same, let's verify - // make sure the two fields that have the same name are ok + // at this point, curr_field_in_orig and curr_field_in_new should be + // the same, let's verify make sure the two fields that have the same + // name are ok if (!are_two_fields_same(curr_field_in_orig, curr_field_in_new)) { sql_print_error( - "Two fields that were supposedly the same are not: \ - %s in original, %s in new", + "Two fields that were supposedly the same are not: %s in " + "original, %s in new", curr_field_in_orig->field_name, - curr_field_in_new->field_name - ); + curr_field_in_new->field_name); retval = 1; goto cleanup; } @@ -693,17 +712,23 @@ static int find_changed_columns(uint32_t* changed_columns, uint32_t* num_changed return retval; } -static bool tables_have_same_keys_and_columns(TABLE* first_table, TABLE* second_table, bool print_error) __attribute__((unused)); -static bool tables_have_same_keys_and_columns(TABLE* first_table, TABLE* second_table, bool print_error) { +TOKUDB_UNUSED(static bool tables_have_same_keys_and_columns( + TABLE* first_table, + TABLE* second_table, + bool print_error)); +static bool tables_have_same_keys_and_columns( + TABLE* first_table, + TABLE* second_table, + bool print_error) { + bool retval; if (first_table->s->null_bytes != second_table->s->null_bytes) { retval = false; if (print_error) { sql_print_error( - "tables have different number of null bytes, %d, %d", - first_table->s->null_bytes, - second_table->s->null_bytes - ); + "tables have different number of null bytes, %d, %d", + first_table->s->null_bytes, + second_table->s->null_bytes); } goto exit; } @@ -711,10 +736,9 @@ static bool tables_have_same_keys_and_columns(TABLE* first_table, TABLE* second_ retval = false; if (print_error) { sql_print_error( - "tables have different number of fields, %d, %d", - first_table->s->fields, - second_table->s->fields - ); + "tables have different number of fields, %d, %d", + first_table->s->fields, + second_table->s->fields); } goto exit; } @@ -724,9 +748,8 @@ static bool tables_have_same_keys_and_columns(TABLE* first_table, TABLE* second_ if (!are_two_fields_same(a,b)) { retval = false; sql_print_error( - "tables have different fields at position %d", - i - ); + "tables have different fields at position %d", + i); goto exit; } } @@ -741,21 +764,29 @@ static bool tables_have_same_keys_and_columns(TABLE* first_table, TABLE* second_ } #if TOKU_INCLUDE_WRITE_FRM_DATA -// write the new frm data to the status dictionary using the alter table transaction -int ha_tokudb::write_frm_data(const uchar *frm_data, size_t frm_len) { +// write the new frm data to the status dictionary using the alter table +// transaction +int ha_tokudb::write_frm_data(const uchar* frm_data, size_t frm_len) { TOKUDB_DBUG_ENTER("write_frm_data"); int error = 0; if (TOKU_PARTITION_WRITE_FRM_DATA || table->part_info == NULL) { // write frmdata to status - THD *thd = ha_thd(); - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); - assert(trx); - DB_TXN *txn = trx->stmt; // use alter table transaction - assert(txn); - error = write_to_status(share->status_block, hatoku_frm_data, (void *)frm_data, (uint)frm_len, txn); + THD* thd = ha_thd(); + tokudb_trx_data* trx = + (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); + assert_always(trx); + DB_TXN* txn = trx->stmt; // use alter table transaction + assert_always(txn); + error = + write_to_status( + share->status_block, + hatoku_frm_data, + (void*)frm_data, + (uint)frm_len, + txn); } - + TOKUDB_DBUG_RETURN(error); } #endif diff --git a/storage/tokudb/ha_tokudb_update.cc b/storage/tokudb/ha_tokudb_update.cc index 1e2d6c0cdbf2a..fabd1a82d0c78 100644 --- a/storage/tokudb/ha_tokudb_update.cc +++ b/storage/tokudb/ha_tokudb_update.cc @@ -53,14 +53,19 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. // Replace field_offset // Debug function to dump an Item -static void dump_item(Item *item) { +static void dump_item(Item* item) { fprintf(stderr, "%u", item->type()); switch (item->type()) { case Item::FUNC_ITEM: { - Item_func *func = static_cast(item); + Item_func* func = static_cast(item); uint n = func->argument_count(); - Item **arguments = func->arguments(); - fprintf(stderr, ":func=%u,%s,%u(", func->functype(), func->func_name(), n); + Item** arguments = func->arguments(); + fprintf( + stderr, + ":func=%u,%s,%u(", + func->functype(), + func->func_name(), + n); for (uint i = 0; i < n ; i++) { dump_item(arguments[i]); if (i < n-1) @@ -70,25 +75,30 @@ static void dump_item(Item *item) { break; } case Item::INT_ITEM: { - Item_int *int_item = static_cast(item); + Item_int* int_item = static_cast(item); fprintf(stderr, ":int=%lld", int_item->val_int()); break; } case Item::STRING_ITEM: { - Item_string *str_item = static_cast(item); + Item_string* str_item = static_cast(item); fprintf(stderr, ":str=%s", str_item->val_str(NULL)->c_ptr()); break; } case Item::FIELD_ITEM: { - Item_field *field_item = static_cast(item); - fprintf(stderr, ":field=%s.%s.%s", field_item->db_name, field_item->table_name, field_item->field_name); + Item_field* field_item = static_cast(item); + fprintf( + stderr, + ":field=%s.%s.%s", + field_item->db_name, + field_item->table_name, + field_item->field_name); break; } case Item::COND_ITEM: { - Item_cond *cond_item = static_cast(item); + Item_cond* cond_item = static_cast(item); fprintf(stderr, ":cond=%s(\n", cond_item->func_name()); List_iterator li(*cond_item->argument_list()); - Item *list_item; + Item* list_item; while ((list_item = li++)) { dump_item(list_item); fprintf(stderr, "\n"); @@ -97,7 +107,7 @@ static void dump_item(Item *item) { break; } case Item::INSERT_VALUE_ITEM: { - Item_insert_value *value_item = static_cast(item); + Item_insert_value* value_item = static_cast(item); fprintf(stderr, ":insert_value"); dump_item(value_item->arg); break; @@ -109,10 +119,10 @@ static void dump_item(Item *item) { } // Debug function to dump an Item list -static void dump_item_list(const char *h, List &l) { +static void dump_item_list(const char* h, List &l) { fprintf(stderr, "%s elements=%u\n", h, l.elements); List_iterator li(l); - Item *item; + Item* item; while ((item = li++) != NULL) { dump_item(item); fprintf(stderr, "\n"); @@ -120,10 +130,10 @@ static void dump_item_list(const char *h, List &l) { } // Find a Field by its Item name -static Field *find_field_by_name(TABLE *table, Item *item) { +static Field* find_field_by_name(TABLE* table, Item* item) { if (item->type() != Item::FIELD_ITEM) return NULL; - Item_field *field_item = static_cast(item); + Item_field* field_item = static_cast(item); #if 0 if (strcmp(table->s->db.str, field_item->db_name) != 0 || strcmp(table->s->table_name.str, field_item->table_name) != 0) @@ -146,7 +156,12 @@ static Field *find_field_by_name(TABLE *table, Item *item) { // Return the starting offset in the value for a particular index (selected by idx) of a // particular field (selected by expand_field_num). // This only works for fixed length fields -static uint32_t fixed_field_offset(uint32_t null_bytes, KEY_AND_COL_INFO *kc_info, uint idx, uint expand_field_num) { +static uint32_t fixed_field_offset( + uint32_t null_bytes, + KEY_AND_COL_INFO* kc_info, + uint idx, + uint expand_field_num) { + uint32_t offset = null_bytes; for (uint i = 0; i < expand_field_num; i++) { if (bitmap_is_set(&kc_info->key_filters[idx], i)) @@ -156,8 +171,13 @@ static uint32_t fixed_field_offset(uint32_t null_bytes, KEY_AND_COL_INFO *kc_inf return offset; } -static uint32_t var_field_index(TABLE *table, KEY_AND_COL_INFO *kc_info, uint idx, uint field_num) { - assert(field_num < table->s->fields); +static uint32_t var_field_index( + TABLE* table, + KEY_AND_COL_INFO* kc_info, + uint idx, + uint field_num) { + + assert_always(field_num < table->s->fields); uint v_index = 0; for (uint i = 0; i < table->s->fields; i++) { if (bitmap_is_set(&kc_info->key_filters[idx], i)) @@ -171,26 +191,37 @@ static uint32_t var_field_index(TABLE *table, KEY_AND_COL_INFO *kc_info, uint id return v_index; } -static uint32_t blob_field_index(TABLE *table, KEY_AND_COL_INFO *kc_info, uint idx, uint field_num) { - assert(field_num < table->s->fields); +static uint32_t blob_field_index( + TABLE* table, + KEY_AND_COL_INFO* kc_info, + uint idx, + uint field_num) { + + assert_always(field_num < table->s->fields); uint b_index; for (b_index = 0; b_index < kc_info->num_blobs; b_index++) { if (kc_info->blob_fields[b_index] == field_num) break; } - assert(b_index < kc_info->num_blobs); + assert_always(b_index < kc_info->num_blobs); return b_index; } // Determine if an update operation can be offloaded to the storage engine. -// The update operation consists of a list of update expressions (fields[i] = values[i]), and a list -// of where conditions (conds). The function returns 0 if the update is handled in the storage engine. +// The update operation consists of a list of update expressions +// (fields[i] = values[i]), and a list of where conditions (conds). +// The function returns 0 if the update is handled in the storage engine. // Otherwise, an error is returned. -int ha_tokudb::fast_update(THD *thd, List &update_fields, List &update_values, Item *conds) { +int ha_tokudb::fast_update( + THD* thd, + List& update_fields, + List& update_values, + Item* conds) { + TOKUDB_HANDLER_DBUG_ENTER(""); int error = 0; - if (tokudb_debug & TOKUDB_DEBUG_UPSERT) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_UPSERT))) { dump_item_list("fields", update_fields); dump_item_list("values", update_values); if (conds) { @@ -198,7 +229,8 @@ int ha_tokudb::fast_update(THD *thd, List &update_fields, List &upda } } - if (update_fields.elements < 1 || update_fields.elements != update_values.elements) { + if (update_fields.elements < 1 || + update_fields.elements != update_values.elements) { error = ENOTSUP; // something is fishy with the parameters goto return_error; } @@ -208,14 +240,18 @@ int ha_tokudb::fast_update(THD *thd, List &update_fields, List &upda goto check_error; } - error = send_update_message(update_fields, update_values, conds, transaction); + error = send_update_message( + update_fields, + update_values, + conds, + transaction); if (error != 0) { goto check_error; } check_error: if (error != 0) { - if (THDVAR(thd, disable_slow_update) != 0) + if (tokudb::sysvars::disable_slow_update(thd) != 0) error = HA_ERR_UNSUPPORTED; if (error != ENOTSUP) print_error(error, MYF(0)); @@ -225,18 +261,20 @@ int ha_tokudb::fast_update(THD *thd, List &update_fields, List &upda TOKUDB_HANDLER_DBUG_RETURN(error); } -// Return true if an expression is a simple int expression or a simple function of +- int expression. -static bool check_int_result(Item *item) { +// Return true if an expression is a simple int expression or a simple function +// of +- int expression. +static bool check_int_result(Item* item) { Item::Type t = item->type(); if (t == Item::INT_ITEM) { return true; } else if (t == Item::FUNC_ITEM) { - Item_func *item_func = static_cast(item); - if (strcmp(item_func->func_name(), "+") != 0 && strcmp(item_func->func_name(), "-") != 0) + Item_func* item_func = static_cast(item); + if (strcmp(item_func->func_name(), "+") != 0 && + strcmp(item_func->func_name(), "-") != 0) return false; if (item_func->argument_count() != 1) return false; - Item **arguments = item_func->arguments(); + Item** arguments = item_func->arguments(); if (arguments[0]->type() != Item::INT_ITEM) return false; return true; @@ -245,36 +283,43 @@ static bool check_int_result(Item *item) { } // check that an item is an insert value item with the same field name -static bool check_insert_value(Item *item, const char *field_name) { +static bool check_insert_value(Item* item, const char* field_name) { if (item->type() != Item::INSERT_VALUE_ITEM) return false; - Item_insert_value *value_item = static_cast(item); + Item_insert_value* value_item = static_cast(item); if (value_item->arg->type() != Item::FIELD_ITEM) return false; - Item_field *arg = static_cast(value_item->arg); + Item_field* arg = static_cast(value_item->arg); if (strcmp(field_name, arg->field_name) != 0) return false; return true; } // Return true if an expression looks like field_name op constant. -static bool check_x_op_constant(const char *field_name, Item *item, const char *op, Item **item_constant, bool allow_insert_value) { +static bool check_x_op_constant( + const char* field_name, + Item* item, + const char* op, + Item** item_constant, + bool allow_insert_value) { + if (item->type() != Item::FUNC_ITEM) return false; - Item_func *item_func = static_cast(item); + Item_func* item_func = static_cast(item); if (strcmp(item_func->func_name(), op) != 0) return false; - Item **arguments = item_func->arguments(); + Item** arguments = item_func->arguments(); uint n = item_func->argument_count(); if (n != 2) return false; if (arguments[0]->type() != Item::FIELD_ITEM) return false; - Item_field *arg0 = static_cast(arguments[0]); + Item_field* arg0 = static_cast(arguments[0]); if (strcmp(field_name, arg0->field_name) != 0) return false; if (!check_int_result(arguments[1])) - if (!(allow_insert_value && check_insert_value(arguments[1], field_name))) + if (!(allow_insert_value && + check_insert_value(arguments[1], field_name))) return false; *item_constant = arguments[1]; return true; @@ -282,33 +327,35 @@ static bool check_x_op_constant(const char *field_name, Item *item, const char * // Return true if an expression looks like field_name = constant static bool check_x_equal_0(const char *field_name, Item *item) { - Item *item_constant; + Item* item_constant; if (!check_x_op_constant(field_name, item, "=", &item_constant, false)) return false; - if (item_constant->type() != Item::INT_ITEM || item_constant->val_int() != 0) + if (item_constant->type() != Item::INT_ITEM || + item_constant->val_int() != 0) return false; return true; } // Return true if an expression looks like fieldname - 1 -static bool check_x_minus_1(const char *field_name, Item *item) { - Item *item_constant; +static bool check_x_minus_1(const char* field_name, Item* item) { + Item* item_constant; if (!check_x_op_constant(field_name, item, "-", &item_constant, false)) return false; - if (item_constant->type() != Item::INT_ITEM || item_constant->val_int() != 1) + if (item_constant->type() != Item::INT_ITEM || + item_constant->val_int() != 1) return false; return true; } // Return true if an expression looks like if(fieldname=0, 0, fieldname-1) and // the field named by fieldname is an unsigned int. -static bool check_decr_floor_expression(Field *lhs_field, Item *item) { +static bool check_decr_floor_expression(Field* lhs_field, Item* item) { if (item->type() != Item::FUNC_ITEM) return false; - Item_func *item_func = static_cast(item); + Item_func* item_func = static_cast(item); if (strcmp(item_func->func_name(), "if") != 0) return false; - Item **arguments = item_func->arguments(); + Item** arguments = item_func->arguments(); uint n = item_func->argument_count(); if (n != 3) return false; @@ -324,8 +371,13 @@ static bool check_decr_floor_expression(Field *lhs_field, Item *item) { } // Check if lhs = rhs expression is simple. Return true if it is. -static bool check_update_expression(Item *lhs_item, Item *rhs_item, TABLE *table, bool allow_insert_value) { - Field *lhs_field = find_field_by_name(table, lhs_item); +static bool check_update_expression( + Item* lhs_item, + Item* rhs_item, + TABLE* table, + bool allow_insert_value) { + + Field* lhs_field = find_field_by_name(table, lhs_item); if (lhs_field == NULL) return false; if (!lhs_field->part_of_key.is_clear_all()) @@ -340,16 +392,26 @@ static bool check_update_expression(Item *lhs_item, Item *rhs_item, TABLE *table case MYSQL_TYPE_LONGLONG: if (check_int_result(rhs_item)) return true; - Item *item_constant; - if (check_x_op_constant(lhs_field->field_name, rhs_item, "+", &item_constant, allow_insert_value)) + Item* item_constant; + if (check_x_op_constant( + lhs_field->field_name, + rhs_item, + "+", + &item_constant, + allow_insert_value)) return true; - if (check_x_op_constant(lhs_field->field_name, rhs_item, "-", &item_constant, allow_insert_value)) + if (check_x_op_constant( + lhs_field->field_name, + rhs_item, + "-", + &item_constant, + allow_insert_value)) return true; if (check_decr_floor_expression(lhs_field, rhs_item)) return true; break; case MYSQL_TYPE_STRING: - if (rhs_type == Item::INT_ITEM || rhs_type == Item::STRING_ITEM) + if (rhs_type == Item::INT_ITEM || rhs_type == Item::STRING_ITEM) return true; break; case MYSQL_TYPE_VARCHAR: @@ -364,26 +426,35 @@ static bool check_update_expression(Item *lhs_item, Item *rhs_item, TABLE *table } // Check that all update expressions are simple. Return true if they are. -static bool check_all_update_expressions(List &fields, List &values, TABLE *table, bool allow_insert_value) { +static bool check_all_update_expressions( + List& fields, + List& values, + TABLE* table, + bool allow_insert_value) { + List_iterator lhs_i(fields); List_iterator rhs_i(values); while (1) { - Item *lhs_item = lhs_i++; + Item* lhs_item = lhs_i++; if (lhs_item == NULL) break; - Item *rhs_item = rhs_i++; - assert(rhs_item != NULL); - if (!check_update_expression(lhs_item, rhs_item, table, allow_insert_value)) + Item* rhs_item = rhs_i++; + assert_always(rhs_item != NULL); + if (!check_update_expression( + lhs_item, + rhs_item, + table, + allow_insert_value)) return false; } return true; } -static bool full_field_in_key(TABLE *table, Field *field) { - assert(table->s->primary_key < table->s->keys); - KEY *key = &table->s->key_info[table->s->primary_key]; +static bool full_field_in_key(TABLE* table, Field* field) { + assert_always(table->s->primary_key < table->s->keys); + KEY* key = &table->s->key_info[table->s->primary_key]; for (uint i = 0; i < get_key_parts(key); i++) { - KEY_PART_INFO *key_part = &key->key_part[i]; + KEY_PART_INFO* key_part = &key->key_part[i]; if (strcmp(field->field_name, key_part->field->field_name) == 0) { return key_part->length == field->field_length; } @@ -391,19 +462,24 @@ static bool full_field_in_key(TABLE *table, Field *field) { return false; } -// Check that an expression looks like fieldname = constant, fieldname is part of the -// primary key, and the named field is an int, char or varchar type. Return true if it does. -static bool check_pk_field_equal_constant(Item *item, TABLE *table, MY_BITMAP *pk_fields) { +// Check that an expression looks like fieldname = constant, fieldname is part +// of the primary key, and the named field is an int, char or varchar type. +// Return true if it does. +static bool check_pk_field_equal_constant( + Item* item, + TABLE* table, + MY_BITMAP* pk_fields) { + if (item->type() != Item::FUNC_ITEM) return false; - Item_func *func = static_cast(item); + Item_func* func = static_cast(item); if (strcmp(func->func_name(), "=") != 0) return false; uint n = func->argument_count(); if (n != 2) return false; - Item **arguments = func->arguments(); - Field *field = find_field_by_name(table, arguments[0]); + Item** arguments = func->arguments(); + Field* field = find_field_by_name(table, arguments[0]); if (field == NULL) return false; if (!bitmap_test_and_clear(pk_fields, field->field_index)) @@ -414,19 +490,21 @@ static bool check_pk_field_equal_constant(Item *item, TABLE *table, MY_BITMAP *p case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: - return arguments[1]->type() == Item::INT_ITEM || arguments[1]->type() == Item::STRING_ITEM; + return arguments[1]->type() == Item::INT_ITEM || + arguments[1]->type() == Item::STRING_ITEM; case MYSQL_TYPE_STRING: case MYSQL_TYPE_VARCHAR: return full_field_in_key(table, field) && - (arguments[1]->type() == Item::INT_ITEM || arguments[1]->type() == Item::STRING_ITEM); + (arguments[1]->type() == Item::INT_ITEM || + arguments[1]->type() == Item::STRING_ITEM); default: return false; } } -// Check that the where condition covers all of the primary key components with fieldname = constant -// expressions. Return true if it does. -static bool check_point_update(Item *conds, TABLE *table) { +// Check that the where condition covers all of the primary key components +// with fieldname = constant expressions. Return true if it does. +static bool check_point_update(Item* conds, TABLE* table) { bool result = false; if (conds == NULL) @@ -435,8 +513,8 @@ static bool check_point_update(Item *conds, TABLE *table) { if (table->s->primary_key >= table->s->keys) return false; // no primary key defined - // use a bitmap of the primary key fields to keep track of those fields that are covered - // by the where conditions + // use a bitmap of the primary key fields to keep track of those fields + // that are covered by the where conditions MY_BITMAP pk_fields; if (bitmap_init(&pk_fields, NULL, table->s->fields, FALSE)) // 1 -> failure return false; @@ -449,14 +527,17 @@ static bool check_point_update(Item *conds, TABLE *table) { result = check_pk_field_equal_constant(conds, table, &pk_fields); break; case Item::COND_ITEM: { - Item_cond *cond_item = static_cast(conds); + Item_cond* cond_item = static_cast(conds); if (strcmp(cond_item->func_name(), "and") != 0) break; List_iterator li(*cond_item->argument_list()); - Item *list_item; + Item* list_item; result = true; while (result == true && (list_item = li++)) { - result = check_pk_field_equal_constant(list_item, table, &pk_fields); + result = check_pk_field_equal_constant( + list_item, + table, + &pk_fields); } break; } @@ -474,13 +555,14 @@ static bool check_point_update(Item *conds, TABLE *table) { // Precompute this when the table is opened. static bool clustering_keys_exist(TABLE *table) { for (uint keynr = 0; keynr < table->s->keys; keynr++) { - if (keynr != table->s->primary_key && key_is_clustering(&table->s->key_info[keynr])) + if (keynr != table->s->primary_key && + key_is_clustering(&table->s->key_info[keynr])) return true; } return false; } -static bool is_strict_mode(THD *thd) { +static bool is_strict_mode(THD* thd) { #if 50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699 return thd->is_strict_mode(); #else @@ -488,8 +570,14 @@ static bool is_strict_mode(THD *thd) { #endif } -// Check if an update operation can be handled by this storage engine. Return true if it can. -bool ha_tokudb::check_fast_update(THD *thd, List &fields, List &values, Item *conds) { +// Check if an update operation can be handled by this storage engine. +// Return true if it can. +bool ha_tokudb::check_fast_update( + THD* thd, + List& fields, + List& values, + Item* conds) { + if (!transaction) return false; @@ -503,10 +591,12 @@ bool ha_tokudb::check_fast_update(THD *thd, List &fields, List &valu // no binlog if (mysql_bin_log.is_open() && - !(thd->variables.binlog_format == BINLOG_FORMAT_STMT || thd->variables.binlog_format == BINLOG_FORMAT_MIXED)) + !(thd->variables.binlog_format == BINLOG_FORMAT_STMT || + thd->variables.binlog_format == BINLOG_FORMAT_MIXED)) return false; - // no clustering keys (need to broadcast an increment into the clustering keys since we are selecting with the primary key) + // no clustering keys (need to broadcast an increment into the clustering + // keys since we are selecting with the primary key) if (clustering_keys_exist(table)) return false; @@ -519,22 +609,34 @@ bool ha_tokudb::check_fast_update(THD *thd, List &fields, List &valu return true; } -static void marshall_varchar_descriptor(tokudb::buffer &b, TABLE *table, KEY_AND_COL_INFO *kc_info, uint key_num) { +static void marshall_varchar_descriptor( + tokudb::buffer& b, + TABLE* table, + KEY_AND_COL_INFO* kc_info, + uint key_num) { + b.append_ui('v'); - b.append_ui(table->s->null_bytes + kc_info->mcp_info[key_num].fixed_field_size); + b.append_ui( + table->s->null_bytes + kc_info->mcp_info[key_num].fixed_field_size); uint32_t var_offset_bytes = kc_info->mcp_info[key_num].len_of_offsets; b.append_ui(var_offset_bytes); - b.append_ui(var_offset_bytes == 0 ? 0 : kc_info->num_offset_bytes); + b.append_ui( + var_offset_bytes == 0 ? 0 : kc_info->num_offset_bytes); } -static void marshall_blobs_descriptor(tokudb::buffer &b, TABLE *table, KEY_AND_COL_INFO *kc_info) { +static void marshall_blobs_descriptor( + tokudb::buffer& b, + TABLE* table, + KEY_AND_COL_INFO* kc_info) { + b.append_ui('b'); uint32_t n = kc_info->num_blobs; b.append_ui(n); for (uint i = 0; i < n; i++) { uint blob_field_index = kc_info->blob_fields[i]; - assert(blob_field_index < table->s->fields); - uint8_t blob_field_length = table->s->field[blob_field_index]->row_pack_length(); + assert_always(blob_field_index < table->s->fields); + uint8_t blob_field_length = + table->s->field[blob_field_index]->row_pack_length(); b.append(&blob_field_length, sizeof blob_field_length); } } @@ -542,30 +644,37 @@ static void marshall_blobs_descriptor(tokudb::buffer &b, TABLE *table, KEY_AND_C static inline uint32_t get_null_bit_position(uint32_t null_bit); // evaluate the int value of an item -static longlong item_val_int(Item *item) { +static longlong item_val_int(Item* item) { Item::Type t = item->type(); if (t == Item::INSERT_VALUE_ITEM) { - Item_insert_value *value_item = static_cast(item); + Item_insert_value* value_item = static_cast(item); return value_item->arg->val_int(); } else return item->val_int(); } // Marshall update operations to a buffer. -static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, TABLE *table, TOKUDB_SHARE *share) { +static void marshall_update( + tokudb::buffer& b, + Item* lhs_item, + Item* rhs_item, + TABLE* table, + TOKUDB_SHARE* share) { + // figure out the update operation type (again) - Field *lhs_field = find_field_by_name(table, lhs_item); - assert(lhs_field); // we found it before, so this should work + Field* lhs_field = find_field_by_name(table, lhs_item); + assert_always(lhs_field); // we found it before, so this should work // compute the update info uint32_t field_type; uint32_t field_null_num = 0; if (lhs_field->real_maybe_null()) { uint32_t field_num = lhs_field->field_index; - field_null_num = ((field_num/8)*8 + get_null_bit_position(lhs_field->null_bit)) + 1; + field_null_num = + ((field_num/8)*8 + get_null_bit_position(lhs_field->null_bit)) + 1; } uint32_t offset; - void *v_ptr = NULL; + void* v_ptr = NULL; uint32_t v_length; uint32_t update_operation; longlong v_ll; @@ -577,9 +686,14 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: { - Field_num *lhs_num = static_cast(lhs_field); + Field_num* lhs_num = static_cast(lhs_field); field_type = lhs_num->unsigned_flag ? UPDATE_TYPE_UINT : UPDATE_TYPE_INT; - offset = fixed_field_offset(table->s->null_bytes, &share->kc_info, table->s->primary_key, lhs_field->field_index); + offset = + fixed_field_offset( + table->s->null_bytes, + &share->kc_info, + table->s->primary_key, + lhs_field->field_index); switch (rhs_item->type()) { case Item::INT_ITEM: { update_operation = '='; @@ -589,10 +703,12 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T break; } case Item::FUNC_ITEM: { - Item_func *rhs_func = static_cast(rhs_item); - Item **arguments = rhs_func->arguments(); + Item_func* rhs_func = static_cast(rhs_item); + Item** arguments = rhs_func->arguments(); + // we only support one if function for now, and it is a + // decrement with floor. if (strcmp(rhs_func->func_name(), "if") == 0) { - update_operation = '-'; // we only support one if function for now, and it is a decrement with floor. + update_operation = '-'; v_ll = 1; } else if (rhs_func->argument_count() == 1) { update_operation = '='; @@ -606,14 +722,20 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T break; } default: - assert(0); + assert_unreachable(); } break; } case MYSQL_TYPE_STRING: { update_operation = '='; - field_type = lhs_field->binary() ? UPDATE_TYPE_BINARY : UPDATE_TYPE_CHAR; - offset = fixed_field_offset(table->s->null_bytes, &share->kc_info, table->s->primary_key, lhs_field->field_index); + field_type = + lhs_field->binary() ? UPDATE_TYPE_BINARY : UPDATE_TYPE_CHAR; + offset = + fixed_field_offset( + table->s->null_bytes, + &share->kc_info, + table->s->primary_key, + lhs_field->field_index); v_str = *rhs_item->val_str(&v_str); v_length = v_str.length(); if (v_length >= lhs_field->pack_length()) { @@ -621,7 +743,8 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T v_str.length(v_length); // truncate } else { v_length = lhs_field->pack_length(); - uchar pad_char = lhs_field->binary() ? 0 : lhs_field->charset()->pad_char; + uchar pad_char = + lhs_field->binary() ? 0 : lhs_field->charset()->pad_char; v_str.fill(lhs_field->pack_length(), pad_char); // pad } v_ptr = v_str.c_ptr(); @@ -629,8 +752,14 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T } case MYSQL_TYPE_VARCHAR: { update_operation = '='; - field_type = lhs_field->binary() ? UPDATE_TYPE_VARBINARY : UPDATE_TYPE_VARCHAR; - offset = var_field_index(table, &share->kc_info, table->s->primary_key, lhs_field->field_index); + field_type = + lhs_field->binary() ? UPDATE_TYPE_VARBINARY : UPDATE_TYPE_VARCHAR; + offset = + var_field_index( + table, + &share->kc_info, + table->s->primary_key, + lhs_field->field_index); v_str = *rhs_item->val_str(&v_str); v_length = v_str.length(); if (v_length >= lhs_field->row_pack_length()) { @@ -643,7 +772,12 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T case MYSQL_TYPE_BLOB: { update_operation = '='; field_type = lhs_field->binary() ? UPDATE_TYPE_BLOB : UPDATE_TYPE_TEXT; - offset = blob_field_index(table, &share->kc_info, table->s->primary_key, lhs_field->field_index); + offset = + blob_field_index( + table, + &share->kc_info, + table->s->primary_key, + lhs_field->field_index); v_str = *rhs_item->val_str(&v_str); v_length = v_str.length(); if (v_length >= lhs_field->max_data_length()) { @@ -654,7 +788,7 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T break; } default: - assert(0); + assert_unreachable(); } // marshall the update fields into the buffer @@ -667,14 +801,14 @@ static void marshall_update(tokudb::buffer &b, Item *lhs_item, Item *rhs_item, T } // Save an item's value into the appropriate field. Return 0 if successful. -static int save_in_field(Item *item, TABLE *table) { - assert(item->type() == Item::FUNC_ITEM); +static int save_in_field(Item* item, TABLE* table) { + assert_always(item->type() == Item::FUNC_ITEM); Item_func *func = static_cast(item); - assert(strcmp(func->func_name(), "=") == 0); + assert_always(strcmp(func->func_name(), "=") == 0); uint n = func->argument_count(); - assert(n == 2); + assert_always(n == 2); Item **arguments = func->arguments(); - assert(arguments[0]->type() == Item::FIELD_ITEM); + assert_always(arguments[0]->type() == Item::FIELD_ITEM); Item_field *field_item = static_cast(arguments[0]); my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set); int error = arguments[1]->save_in_field(field_item->field, 0); @@ -682,7 +816,11 @@ static int save_in_field(Item *item, TABLE *table) { return error; } -static void count_update_types(Field *lhs_field, uint *num_varchars, uint *num_blobs) { +static void count_update_types( + Field* lhs_field, + uint* num_varchars, + uint* num_blobs) { + switch (lhs_field->type()) { case MYSQL_TYPE_VARCHAR: *num_varchars += 1; @@ -695,8 +833,14 @@ static void count_update_types(Field *lhs_field, uint *num_varchars, uint *num_b } } -// Generate an update message for an update operation and send it into the primary tree. Return 0 if successful. -int ha_tokudb::send_update_message(List &update_fields, List &update_values, Item *conds, DB_TXN *txn) { +// Generate an update message for an update operation and send it into the +// primary tree. Return 0 if successful. +int ha_tokudb::send_update_message( + List& update_fields, + List& update_values, + Item* conds, + DB_TXN* txn) { + int error; // Save the primary key from the where conditions @@ -704,26 +848,32 @@ int ha_tokudb::send_update_message(List &update_fields, List &update if (t == Item::FUNC_ITEM) { error = save_in_field(conds, table); } else if (t == Item::COND_ITEM) { - Item_cond *cond_item = static_cast(conds); + Item_cond* cond_item = static_cast(conds); List_iterator li(*cond_item->argument_list()); - Item *list_item; + Item* list_item; error = 0; while (error == 0 && (list_item = li++)) { error = save_in_field(list_item, table); } - } else - assert(0); + } else { + assert_unreachable(); + } if (error) return error; // put the primary key into key_buff and wrap it with key_dbt DBT key_dbt; bool has_null; - create_dbt_key_from_table(&key_dbt, primary_key, key_buff, table->record[0], &has_null); - + create_dbt_key_from_table( + &key_dbt, + primary_key, + key_buff, + table->record[0], + &has_null); + // construct the update message tokudb::buffer update_message; - + uint8_t op = UPDATE_OP_UPDATE_2; update_message.append(&op, sizeof op); @@ -731,12 +881,12 @@ int ha_tokudb::send_update_message(List &update_fields, List &update uint num_varchars = 0, num_blobs = 0; if (1) { List_iterator lhs_i(update_fields); - Item *lhs_item; + Item* lhs_item; while ((lhs_item = lhs_i++)) { if (lhs_item == NULL) break; - Field *lhs_field = find_field_by_name(table, lhs_item); - assert(lhs_field); // we found it before, so this should work + Field* lhs_field = find_field_by_name(table, lhs_item); + assert_always(lhs_field); // we found it before, so this should work count_update_types(lhs_field, &num_varchars, &num_blobs); } if (num_varchars > 0 || num_blobs > 0) @@ -747,56 +897,75 @@ int ha_tokudb::send_update_message(List &update_fields, List &update // append the updates update_message.append_ui(num_updates); - + if (num_varchars > 0 || num_blobs > 0) - marshall_varchar_descriptor(update_message, table, &share->kc_info, table->s->primary_key); + marshall_varchar_descriptor( + update_message, + table, + &share->kc_info, + table->s->primary_key); if (num_blobs > 0) marshall_blobs_descriptor(update_message, table, &share->kc_info); List_iterator lhs_i(update_fields); List_iterator rhs_i(update_values); while (error == 0) { - Item *lhs_item = lhs_i++; + Item* lhs_item = lhs_i++; if (lhs_item == NULL) break; - Item *rhs_item = rhs_i++; - assert(rhs_item != NULL); + Item* rhs_item = rhs_i++; + assert_always(rhs_item != NULL); marshall_update(update_message, lhs_item, rhs_item, table, share); } - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); - if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) { // hot index in progress + // hot index in progress + if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) { error = ENOTSUP; // run on the slow path } else { - // send the update message + // send the update message DBT update_dbt; memset(&update_dbt, 0, sizeof update_dbt); update_dbt.data = update_message.data(); update_dbt.size = update_message.size(); - error = share->key_file[primary_key]->update(share->key_file[primary_key], txn, &key_dbt, &update_dbt, 0); + error = + share->key_file[primary_key]->update( + share->key_file[primary_key], + txn, + &key_dbt, + &update_dbt, + 0); } - rw_unlock(&share->num_DBs_lock); - + share->_num_DBs_lock.unlock(); + return error; } // Determine if an upsert operation can be offloaded to the storage engine. -// An upsert consists of a row and a list of update expressions (update_fields[i] = update_values[i]). -// The function returns 0 if the upsert is handled in the storage engine. Otherwise, an error code is returned. -int ha_tokudb::upsert(THD *thd, List &update_fields, List &update_values) { +// An upsert consists of a row and a list of update expressions +// (update_fields[i] = update_values[i]). +// The function returns 0 if the upsert is handled in the storage engine. +// Otherwise, an error code is returned. +int ha_tokudb::upsert( + THD* thd, + List& update_fields, + List& update_values) { + TOKUDB_HANDLER_DBUG_ENTER(""); int error = 0; - if (tokudb_debug & TOKUDB_DEBUG_UPSERT) { + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(TOKUDB_DEBUG_UPSERT))) { fprintf(stderr, "upsert\n"); dump_item_list("update_fields", update_fields); dump_item_list("update_values", update_values); } - if (update_fields.elements < 1 || update_fields.elements != update_values.elements) { - error = ENOTSUP; // not an upsert or something is fishy with the parameters + // not an upsert or something is fishy with the parameters + if (update_fields.elements < 1 || + update_fields.elements != update_values.elements) { + error = ENOTSUP; goto return_error; } @@ -812,7 +981,7 @@ int ha_tokudb::upsert(THD *thd, List &update_fields, List &update_va check_error: if (error != 0) { - if (THDVAR(thd, disable_slow_upsert) != 0) + if (tokudb::sysvars::disable_slow_upsert(thd) != 0) error = HA_ERR_UNSUPPORTED; if (error != ENOTSUP) print_error(error, MYF(0)); @@ -822,8 +991,13 @@ int ha_tokudb::upsert(THD *thd, List &update_fields, List &update_va TOKUDB_HANDLER_DBUG_RETURN(error); } -// Check if an upsert can be handled by this storage engine. Return trus if it can. -bool ha_tokudb::check_upsert(THD *thd, List &update_fields, List &update_values) { +// Check if an upsert can be handled by this storage engine. +// Return true if it can. +bool ha_tokudb::check_upsert( + THD* thd, + List& update_fields, + List& update_values) { + if (!transaction) return false; @@ -845,23 +1019,38 @@ bool ha_tokudb::check_upsert(THD *thd, List &update_fields, List &up // no binlog if (mysql_bin_log.is_open() && - !(thd->variables.binlog_format == BINLOG_FORMAT_STMT || thd->variables.binlog_format == BINLOG_FORMAT_MIXED)) + !(thd->variables.binlog_format == BINLOG_FORMAT_STMT || + thd->variables.binlog_format == BINLOG_FORMAT_MIXED)) return false; - if (!check_all_update_expressions(update_fields, update_values, table, true)) + if (!check_all_update_expressions( + update_fields, + update_values, + table, + true)) return false; return true; } -// Generate an upsert message and send it into the primary tree. Return 0 if successful. -int ha_tokudb::send_upsert_message(THD *thd, List &update_fields, List &update_values, DB_TXN *txn) { +// Generate an upsert message and send it into the primary tree. +// Return 0 if successful. +int ha_tokudb::send_upsert_message( + THD* thd, + List& update_fields, + List& update_values, + DB_TXN* txn) { int error = 0; // generate primary key DBT key_dbt; bool has_null; - create_dbt_key_from_table(&key_dbt, primary_key, primary_key_buff, table->record[0], &has_null); + create_dbt_key_from_table( + &key_dbt, + primary_key, + primary_key_buff, + table->record[0], + &has_null); // generate packed row DBT row; @@ -883,12 +1072,12 @@ int ha_tokudb::send_upsert_message(THD *thd, List &update_fields, List lhs_i(update_fields); - Item *lhs_item; + Item* lhs_item; while ((lhs_item = lhs_i++)) { if (lhs_item == NULL) break; - Field *lhs_field = find_field_by_name(table, lhs_item); - assert(lhs_field); // we found it before, so this should work + Field* lhs_field = find_field_by_name(table, lhs_item); + assert_always(lhs_field); // we found it before, so this should work count_update_types(lhs_field, &num_varchars, &num_blobs); } if (num_varchars > 0 || num_blobs > 0) @@ -901,35 +1090,44 @@ int ha_tokudb::send_upsert_message(THD *thd, List &update_fields, List(num_updates); if (num_varchars > 0 || num_blobs > 0) - marshall_varchar_descriptor(update_message, table, &share->kc_info, table->s->primary_key); + marshall_varchar_descriptor( + update_message, + table, &share->kc_info, + table->s->primary_key); if (num_blobs > 0) marshall_blobs_descriptor(update_message, table, &share->kc_info); List_iterator lhs_i(update_fields); List_iterator rhs_i(update_values); while (1) { - Item *lhs_item = lhs_i++; + Item* lhs_item = lhs_i++; if (lhs_item == NULL) break; - Item *rhs_item = rhs_i++; - if (rhs_item == NULL) - assert(0); // can not happen + Item* rhs_item = rhs_i++; + assert_always(rhs_item != NULL); marshall_update(update_message, lhs_item, rhs_item, table, share); } - rw_rdlock(&share->num_DBs_lock); + share->_num_DBs_lock.lock_read(); - if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) { // hot index in progress + // hot index in progress + if (share->num_DBs > table->s->keys + tokudb_test(hidden_primary_key)) { error = ENOTSUP; // run on the slow path } else { // send the upsert message DBT update_dbt; memset(&update_dbt, 0, sizeof update_dbt); update_dbt.data = update_message.data(); update_dbt.size = update_message.size(); - error = share->key_file[primary_key]->update(share->key_file[primary_key], txn, &key_dbt, &update_dbt, 0); + error = + share->key_file[primary_key]->update( + share->key_file[primary_key], + txn, + &key_dbt, + &update_dbt, + 0); } - rw_unlock(&share->num_DBs_lock); + share->_num_DBs_lock.unlock(); return error; } diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc index 9892c6f5eed4f..a5e0874505a18 100644 --- a/storage/tokudb/hatoku_cmp.cc +++ b/storage/tokudb/hatoku_cmp.cc @@ -104,8 +104,7 @@ static void get_var_field_info( data_end_offset = uint2korr(var_field_offset_ptr + 2*var_field_index); break; default: - assert(false); - break; + assert_unreachable(); } if (var_field_index) { @@ -117,8 +116,7 @@ static void get_var_field_info( data_start_offset = uint2korr(var_field_offset_ptr + 2*(var_field_index-1)); break; default: - assert(false); - break; + assert_unreachable(); } } else { @@ -126,7 +124,7 @@ static void get_var_field_info( } *start_offset = data_start_offset; - assert(data_end_offset >= data_start_offset); + assert_always(data_end_offset >= data_start_offset); *field_len = data_end_offset - data_start_offset; } @@ -153,8 +151,7 @@ static void get_blob_field_info( data_end_offset = uint2korr(var_field_data_ptr - 2); break; default: - assert(false); - break; + assert_unreachable(); } } else { @@ -245,7 +242,7 @@ static TOKU_TYPE mysql_to_toku_type (Field* field) { case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_NULL: - assert(false); + assert_unreachable(); } exit: return ret_val; @@ -312,7 +309,7 @@ static inline uchar* pack_toku_int (uchar* to_tokudb, uchar* from_mysql, uint32_ memcpy(to_tokudb, from_mysql, 8); break; default: - assert(false); + assert_unreachable(); } return to_tokudb+num_bytes; } @@ -338,7 +335,7 @@ static inline uchar* unpack_toku_int(uchar* to_mysql, uchar* from_tokudb, uint32 memcpy(to_mysql, from_tokudb, 8); break; default: - assert(false); + assert_unreachable(); } return from_tokudb+num_bytes; } @@ -390,7 +387,7 @@ static inline int cmp_toku_int (uchar* a_buf, uchar* b_buf, bool is_unsigned, ui ret_val = 0; goto exit; default: - assert(false); + assert_unreachable(); } } // @@ -438,13 +435,13 @@ static inline int cmp_toku_int (uchar* a_buf, uchar* b_buf, bool is_unsigned, ui ret_val = 0; goto exit; default: - assert(false); + assert_unreachable(); } } // // if this is hit, indicates bug in writing of this function // - assert(false); + assert_unreachable(); exit: return ret_val; } @@ -653,7 +650,7 @@ static inline uchar* unpack_toku_varbinary( int4store(to_mysql, length); break; default: - assert(false); + assert_unreachable(); } // // copy the binary data @@ -779,7 +776,7 @@ static inline uchar* unpack_toku_blob( int4store(to_mysql, length); break; default: - assert(false); + assert_unreachable(); } // // copy the binary data @@ -957,7 +954,9 @@ static inline int tokudb_compare_two_hidden_keys( const void* saved_key_data, const uint32_t saved_key_size ) { - assert( (new_key_size >= TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH) && (saved_key_size >= TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH) ); + assert_always( + (new_key_size >= TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH) && + (saved_key_size >= TOKUDB_HIDDEN_PRIMARY_KEY_LENGTH)); ulonglong a = hpk_char_to_num((uchar *) new_key_data); ulonglong b = hpk_char_to_num((uchar *) saved_key_data); return a < b ? -1 : (a > b ? 1 : 0); @@ -997,8 +996,7 @@ static uint32_t skip_field_in_descriptor(uchar* row_desc) { row_desc_pos += sizeof(uint32_t); break; default: - assert(false); - break; + assert_unreachable(); } return (uint32_t)(row_desc_pos - row_desc); } @@ -1026,7 +1024,7 @@ static int create_toku_key_descriptor_for_key(KEY* key, uchar* buf) { // The second byte for each field is the type // TOKU_TYPE type = mysql_to_toku_type(field); - assert (type < 256); + assert_always((int)type < 256); *pos = (uchar)(type & 255); pos++; @@ -1041,7 +1039,7 @@ static int create_toku_key_descriptor_for_key(KEY* key, uchar* buf) { // case (toku_type_int): num_bytes_in_field = field->pack_length(); - assert (num_bytes_in_field < 256); + assert_always (num_bytes_in_field < 256); *pos = (uchar)(num_bytes_in_field & 255); pos++; *pos = (field->flags & UNSIGNED_FLAG) ? 1 : 0; @@ -1059,7 +1057,7 @@ static int create_toku_key_descriptor_for_key(KEY* key, uchar* buf) { case (toku_type_fixbinary): num_bytes_in_field = field->pack_length(); set_if_smaller(num_bytes_in_field, key->key_part[i].length); - assert(num_bytes_in_field < 256); + assert_always(num_bytes_in_field < 256); pos[0] = (uchar)(num_bytes_in_field & 255); pos++; break; @@ -1087,8 +1085,7 @@ static int create_toku_key_descriptor_for_key(KEY* key, uchar* buf) { pos += 4; break; default: - assert(false); - + assert_unreachable(); } } return pos - buf; @@ -1277,8 +1274,7 @@ static inline int compare_toku_field( *read_string = true; break; default: - assert(false); - break; + assert_unreachable(); } *row_desc_bytes_read = row_desc_pos - row_desc; @@ -1301,7 +1297,7 @@ static uchar* pack_toku_key_field( TOKU_TYPE toku_type = mysql_to_toku_type(field); switch(toku_type) { case (toku_type_int): - assert(key_part_length == field->pack_length()); + assert_always(key_part_length == field->pack_length()); new_pos = pack_toku_int( to_tokudb, from_mysql, @@ -1309,13 +1305,13 @@ static uchar* pack_toku_key_field( ); goto exit; case (toku_type_double): - assert(field->pack_length() == sizeof(double)); - assert(key_part_length == sizeof(double)); + assert_always(field->pack_length() == sizeof(double)); + assert_always(key_part_length == sizeof(double)); new_pos = pack_toku_double(to_tokudb, from_mysql); goto exit; case (toku_type_float): - assert(field->pack_length() == sizeof(float)); - assert(key_part_length == sizeof(float)); + assert_always(field->pack_length() == sizeof(float)); + assert_always(key_part_length == sizeof(float)); new_pos = pack_toku_float(to_tokudb, from_mysql); goto exit; case (toku_type_fixbinary): @@ -1368,9 +1364,9 @@ static uchar* pack_toku_key_field( ); goto exit; default: - assert(false); + assert_unreachable(); } - assert(false); + assert_unreachable(); exit: return new_pos; } @@ -1419,10 +1415,10 @@ static uchar* pack_key_toku_key_field( ); goto exit; default: - assert(false); + assert_unreachable(); } - assert(false); + assert_unreachable(); exit: return new_pos; } @@ -1432,16 +1428,15 @@ uchar* unpack_toku_key_field( uchar* to_mysql, uchar* from_tokudb, Field* field, - uint32_t key_part_length - ) -{ + uint32_t key_part_length) { + uchar* new_pos = NULL; uint32_t num_bytes = 0; uint32_t num_bytes_copied; TOKU_TYPE toku_type = mysql_to_toku_type(field); switch(toku_type) { case (toku_type_int): - assert(key_part_length == field->pack_length()); + assert_always(key_part_length == field->pack_length()); new_pos = unpack_toku_int( to_mysql, from_tokudb, @@ -1449,13 +1444,13 @@ uchar* unpack_toku_key_field( ); goto exit; case (toku_type_double): - assert(field->pack_length() == sizeof(double)); - assert(key_part_length == sizeof(double)); + assert_always(field->pack_length() == sizeof(double)); + assert_always(key_part_length == sizeof(double)); new_pos = unpack_toku_double(to_mysql, from_tokudb); goto exit; case (toku_type_float): - assert(field->pack_length() == sizeof(float)); - assert(key_part_length == sizeof(float)); + assert_always(field->pack_length() == sizeof(float)); + assert_always(key_part_length == sizeof(float)); new_pos = unpack_toku_float(to_mysql, from_tokudb); goto exit; case (toku_type_fixbinary): @@ -1464,8 +1459,7 @@ uchar* unpack_toku_key_field( new_pos = unpack_toku_binary( to_mysql, from_tokudb, - num_bytes - ); + num_bytes); goto exit; case (toku_type_fixstring): num_bytes = field->pack_length(); @@ -1473,11 +1467,15 @@ uchar* unpack_toku_key_field( to_mysql, from_tokudb, get_length_bytes_from_max(key_part_length), - 0 - ); - num_bytes_copied = new_pos - (from_tokudb + get_length_bytes_from_max(key_part_length)); - assert(num_bytes_copied <= num_bytes); - memset(to_mysql+num_bytes_copied, field->charset()->pad_char, num_bytes - num_bytes_copied); + 0); + num_bytes_copied = + new_pos - + (from_tokudb + get_length_bytes_from_max(key_part_length)); + assert_always(num_bytes_copied <= num_bytes); + memset( + to_mysql + num_bytes_copied, + field->charset()->pad_char, + num_bytes - num_bytes_copied); goto exit; case (toku_type_varbinary): case (toku_type_varstring): @@ -1485,21 +1483,20 @@ uchar* unpack_toku_key_field( to_mysql, from_tokudb, get_length_bytes_from_max(key_part_length), - ((Field_varstring *)field)->length_bytes - ); + ((Field_varstring*)field)->length_bytes); goto exit; case (toku_type_blob): new_pos = unpack_toku_blob( to_mysql, from_tokudb, get_length_bytes_from_max(key_part_length), - ((Field_blob *)field)->row_pack_length() //only calling this because packlength is returned - ); + //only calling this because packlength is returned + ((Field_blob *)field)->row_pack_length()); goto exit; default: - assert(false); + assert_unreachable(); } - assert(false); + assert_unreachable(); exit: return new_pos; } @@ -1513,9 +1510,8 @@ static int tokudb_compare_two_keys( const void* row_desc, const uint32_t row_desc_size, bool cmp_prefix, - bool* read_string - ) -{ + bool* read_string) { + int ret_val = 0; int8_t new_key_inf_val = COL_NEG_INF; int8_t saved_key_inf_val = COL_NEG_INF; @@ -1538,11 +1534,9 @@ static int tokudb_compare_two_keys( } row_desc_ptr++; - while ( (uint32_t)(new_key_ptr - (uchar *)new_key_data) < new_key_size && - (uint32_t)(saved_key_ptr - (uchar *)saved_key_data) < saved_key_size && - (uint32_t)(row_desc_ptr - (uchar *)row_desc) < row_desc_size - ) - { + while ((uint32_t)(new_key_ptr - (uchar*)new_key_data) < new_key_size && + (uint32_t)(saved_key_ptr - (uchar*)saved_key_data) < saved_key_size && + (uint32_t)(row_desc_ptr - (uchar*)row_desc) < row_desc_size) { uint32_t new_key_field_length; uint32_t saved_key_field_length; uint32_t row_desc_field_length; @@ -1583,8 +1577,7 @@ static int tokudb_compare_two_keys( &new_key_field_length, &saved_key_field_length, &row_desc_field_length, - read_string - ); + read_string); new_key_ptr += new_key_field_length; saved_key_ptr += saved_key_field_length; row_desc_ptr += row_desc_field_length; @@ -1592,35 +1585,30 @@ static int tokudb_compare_two_keys( goto exit; } - assert((uint32_t)(new_key_ptr - (uchar *)new_key_data) <= new_key_size); - assert((uint32_t)(saved_key_ptr - (uchar *)saved_key_data) <= saved_key_size); - assert((uint32_t)(row_desc_ptr - (uchar *)row_desc) <= row_desc_size); - } - new_key_bytes_left = new_key_size - ((uint32_t)(new_key_ptr - (uchar *)new_key_data)); - saved_key_bytes_left = saved_key_size - ((uint32_t)(saved_key_ptr - (uchar *)saved_key_data)); + assert_always( + (uint32_t)(new_key_ptr - (uchar*)new_key_data) <= new_key_size); + assert_always( + (uint32_t)(saved_key_ptr - (uchar*)saved_key_data) <= saved_key_size); + assert_always( + (uint32_t)(row_desc_ptr - (uchar*)row_desc) <= row_desc_size); + } + new_key_bytes_left = + new_key_size - ((uint32_t)(new_key_ptr - (uchar*)new_key_data)); + saved_key_bytes_left = + saved_key_size - ((uint32_t)(saved_key_ptr - (uchar*)saved_key_data)); if (cmp_prefix) { ret_val = 0; - } - // - // in this case, read both keys to completion, now read infinity byte - // - else if (new_key_bytes_left== 0 && saved_key_bytes_left== 0) { + } else if (new_key_bytes_left== 0 && saved_key_bytes_left== 0) { + // in this case, read both keys to completion, now read infinity byte ret_val = new_key_inf_val - saved_key_inf_val; - } - // - // at this point, one SHOULD be 0 - // - else if (new_key_bytes_left == 0 && saved_key_bytes_left > 0) { + } else if (new_key_bytes_left == 0 && saved_key_bytes_left > 0) { + // at this point, one SHOULD be 0 ret_val = (new_key_inf_val == COL_POS_INF ) ? 1 : -1; - } - else if (new_key_bytes_left > 0 && saved_key_bytes_left == 0) { + } else if (new_key_bytes_left > 0 && saved_key_bytes_left == 0) { ret_val = (saved_key_inf_val == COL_POS_INF ) ? -1 : 1; - } - // - // this should never happen, perhaps we should assert(false) - // - else { - assert(false); + } else { + // this should never happen, perhaps we should assert(false) + assert_unreachable(); ret_val = new_key_bytes_left - saved_key_bytes_left; } exit: @@ -1765,9 +1753,9 @@ static int tokudb_compare_two_key_parts( goto exit; } - assert((uint32_t)(new_key_ptr - (uchar *)new_key_data) <= new_key_size); - assert((uint32_t)(saved_key_ptr - (uchar *)saved_key_data) <= saved_key_size); - assert((uint32_t)(row_desc_ptr - (uchar *)row_desc) <= row_desc_size); + assert_always((uint32_t)(new_key_ptr - (uchar *)new_key_data) <= new_key_size); + assert_always((uint32_t)(saved_key_ptr - (uchar *)saved_key_data) <= saved_key_size); + assert_always((uint32_t)(row_desc_ptr - (uchar *)row_desc) <= row_desc_size); } ret_val = 0; @@ -1776,7 +1764,7 @@ static int tokudb_compare_two_key_parts( } static int tokudb_cmp_dbt_key_parts(DB *file, const DBT *keya, const DBT *keyb, uint max_parts) { - assert(file->cmp_descriptor->dbt.size); + assert_always(file->cmp_descriptor->dbt.size); return tokudb_compare_two_key_parts( keya->data, keya->size, @@ -1847,7 +1835,7 @@ static uint32_t pack_desc_pk_info(uchar* buf, KEY_AND_COL_INFO* kc_info, TABLE_S case (toku_type_float): pos[0] = COL_FIX_FIELD; pos++; - assert(kc_info->field_lengths[field_index] < 256); + assert_always(kc_info->field_lengths[field_index] < 256); pos[0] = kc_info->field_lengths[field_index]; pos++; break; @@ -1856,7 +1844,7 @@ static uint32_t pack_desc_pk_info(uchar* buf, KEY_AND_COL_INFO* kc_info, TABLE_S pos++; field_length = field->pack_length(); set_if_smaller(key_part_length, field_length); - assert(key_part_length < 256); + assert_always(key_part_length < 256); pos[0] = (uchar)key_part_length; pos++; break; @@ -1871,7 +1859,7 @@ static uint32_t pack_desc_pk_info(uchar* buf, KEY_AND_COL_INFO* kc_info, TABLE_S pos++; break; default: - assert(false); + assert_unreachable(); } return pos - buf; @@ -1908,7 +1896,7 @@ static uint32_t pack_desc_pk_offset_info( } offset += pk_info[2*i + 1]; } - assert(found_col_in_pk); + assert_always(found_col_in_pk); if (is_constant_offset) { pos[0] = COL_FIX_PK_OFFSET; pos++; @@ -1966,10 +1954,10 @@ static uint32_t pack_desc_offset_info(uchar* buf, KEY_AND_COL_INFO* kc_info, uin break; } } - assert(found_index); + assert_always(found_index); break; default: - assert(false); + assert_unreachable(); } return pos - buf; @@ -2004,7 +1992,7 @@ static uint32_t pack_desc_key_length_info(uchar* buf, KEY_AND_COL_INFO* kc_info, pos += sizeof(key_part_length); break; default: - assert(false); + assert_unreachable(); } return pos - buf; @@ -2041,7 +2029,7 @@ static uint32_t pack_desc_char_info(uchar* buf, KEY_AND_COL_INFO* kc_info, TABLE pos += 4; break; default: - assert(false); + assert_unreachable(); } return pos - buf; @@ -2151,7 +2139,7 @@ static uint32_t create_toku_clustering_val_pack_descriptor ( bool col_filtered = bitmap_is_set(&kc_info->key_filters[keynr],i); bool col_filtered_in_pk = bitmap_is_set(&kc_info->key_filters[pk_index],i); if (col_filtered_in_pk) { - assert(col_filtered); + assert_always(col_filtered); } } @@ -2321,7 +2309,7 @@ static uint32_t pack_clustering_val_from_desc( memcpy(&end, desc_pos, sizeof(end)); desc_pos += sizeof(end); - assert (start <= end); + assert_always (start <= end); if (curr == CK_FIX_RANGE) { length = end - start; @@ -2367,24 +2355,21 @@ static uint32_t pack_clustering_val_from_desc( offset_diffs = (end_data_offset + end_data_size) - (uint32_t)(var_dest_data_ptr - orig_var_dest_data_ptr); for (uint32_t i = start; i <= end; i++) { if ( num_offset_bytes == 1 ) { - assert(offset_diffs < 256); + assert_always(offset_diffs < 256); var_dest_offset_ptr[0] = var_src_offset_ptr[i] - (uchar)offset_diffs; var_dest_offset_ptr++; - } - else if ( num_offset_bytes == 2 ) { + } else if ( num_offset_bytes == 2 ) { uint32_t tmp = uint2korr(var_src_offset_ptr + 2*i); uint32_t new_offset = tmp - offset_diffs; - assert(new_offset < 1<<16); + assert_always(new_offset < 1<<16); int2store(var_dest_offset_ptr,new_offset); var_dest_offset_ptr += 2; - } - else { - assert(false); + } else { + assert_unreachable(); } } - } - else { - assert(false); + } else { + assert_unreachable(); } } // @@ -2518,7 +2503,7 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( // // store number of parts // - assert(get_key_parts(prim_key) < 128); + assert_always(get_key_parts(prim_key) < 128); pos[0] = 2 * get_key_parts(prim_key); pos++; // @@ -2540,7 +2525,7 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( // // asserting that we moved forward as much as we think we have // - assert(tmp - pos == (2 * get_key_parts(prim_key))); + assert_always(tmp - pos == (2 * get_key_parts(prim_key))); pos = tmp; } @@ -2551,7 +2536,7 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( bool is_col_in_pk = false; if (bitmap_is_set(&kc_info->key_filters[pk_index],field_index)) { - assert(!has_hpk && prim_key != NULL); + assert_always(!has_hpk && prim_key != NULL); is_col_in_pk = true; } else { @@ -2566,7 +2551,7 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( // assert that columns in pk do not have a null bit // because in MySQL, pk columns cannot be null // - assert(!field->null_bit); + assert_always(!field->null_bit); } if (field->null_bit) { @@ -2668,7 +2653,7 @@ static uint32_t max_key_size_from_desc( // skip byte that states if main dictionary bool is_main_dictionary = desc_pos[0]; desc_pos++; - assert(!is_main_dictionary); + assert_always(!is_main_dictionary); // skip hpk byte desc_pos++; @@ -2731,7 +2716,7 @@ static uint32_t max_key_size_from_desc( desc_pos += sizeof(charset_num); } else { - assert(has_charset == COL_HAS_NO_CHARSET); + assert_always(has_charset == COL_HAS_NO_CHARSET); } } return max_size; @@ -2742,9 +2727,8 @@ static uint32_t pack_key_from_desc( void* row_desc, uint32_t row_desc_size, const DBT* pk_key, - const DBT* pk_val - ) -{ + const DBT* pk_val) { + MULTI_COL_PACK_INFO mcp_info; uint32_t num_null_bytes; uint32_t num_blobs; @@ -2762,7 +2746,7 @@ static uint32_t pack_key_from_desc( bool is_main_dictionary = desc_pos[0]; desc_pos++; - assert(!is_main_dictionary); + assert_always(!is_main_dictionary); // // get the constant info out of descriptor @@ -2810,7 +2794,7 @@ static uint32_t pack_key_from_desc( fixed_field_ptr = null_bytes_ptr + num_null_bytes; var_field_offset_ptr = fixed_field_ptr + mcp_info.fixed_field_size; var_field_data_ptr = var_field_offset_ptr + mcp_info.len_of_offsets; - while ( (uint32_t)(desc_pos - (uchar *)row_desc) < row_desc_size) { + while ((uint32_t)(desc_pos - (uchar*)row_desc) < row_desc_size) { uchar col_fix_val; uchar has_charset; uint32_t col_pack_val = 0; @@ -2834,8 +2818,7 @@ static uint32_t pack_key_from_desc( packed_key_pos++; desc_pos += skip_key_in_desc(desc_pos); continue; - } - else { + } else { packed_key_pos[0] = NONNULL_COL_VAL; packed_key_pos++; } @@ -2859,42 +2842,46 @@ static uint32_t pack_key_from_desc( if (has_charset == COL_HAS_CHARSET) { memcpy(&charset_num, desc_pos, sizeof(charset_num)); desc_pos += sizeof(charset_num); - } - else { - assert(has_charset == COL_HAS_NO_CHARSET); + } else { + assert_always(has_charset == COL_HAS_NO_CHARSET); } // // case where column is in pk val // - if (col_fix_val == COL_FIX_FIELD || col_fix_val == COL_VAR_FIELD || col_fix_val == COL_BLOB_FIELD) { - if (col_fix_val == COL_FIX_FIELD && has_charset == COL_HAS_NO_CHARSET) { - memcpy(packed_key_pos, &fixed_field_ptr[col_pack_val], key_length); + if (col_fix_val == COL_FIX_FIELD || + col_fix_val == COL_VAR_FIELD || + col_fix_val == COL_BLOB_FIELD) { + if (col_fix_val == COL_FIX_FIELD && + has_charset == COL_HAS_NO_CHARSET) { + memcpy( + packed_key_pos, + &fixed_field_ptr[col_pack_val], + key_length); packed_key_pos += key_length; - } - else if (col_fix_val == COL_VAR_FIELD && has_charset == COL_HAS_NO_CHARSET) { + } else if (col_fix_val == COL_VAR_FIELD && + has_charset == COL_HAS_NO_CHARSET) { uint32_t data_start_offset = 0; uint32_t data_size = 0; get_var_field_info( - &data_size, - &data_start_offset, - col_pack_val, - var_field_offset_ptr, - num_offset_bytes - ); + &data_size, + &data_start_offset, + col_pack_val, + var_field_offset_ptr, + num_offset_bytes); // // length of this field in this row is data_size // data is located beginning at var_field_data_ptr + data_start_offset // packed_key_pos = pack_toku_varbinary_from_desc( - packed_key_pos, - var_field_data_ptr + data_start_offset, - key_length, //number of bytes to use to encode the length in to_tokudb - data_size //length of field - ); - } - else { + packed_key_pos, + var_field_data_ptr + data_start_offset, + //number of bytes to use to encode the length in to_tokudb + key_length, + //length of field + data_size); + } else { const uchar* data_start = NULL; uint32_t data_start_offset = 0; uint32_t data_size = 0; @@ -2903,76 +2890,59 @@ static uint32_t pack_key_from_desc( data_start_offset = col_pack_val; data_size = key_length; data_start = fixed_field_ptr + data_start_offset; - } - else if (col_fix_val == COL_VAR_FIELD){ + } else if (col_fix_val == COL_VAR_FIELD){ get_var_field_info( - &data_size, - &data_start_offset, - col_pack_val, - var_field_offset_ptr, - num_offset_bytes - ); + &data_size, + &data_start_offset, + col_pack_val, + var_field_offset_ptr, + num_offset_bytes); data_start = var_field_data_ptr + data_start_offset; - } - else if (col_fix_val == COL_BLOB_FIELD) { + } else if (col_fix_val == COL_BLOB_FIELD) { uint32_t blob_index = col_pack_val; uint32_t blob_offset; const uchar* blob_ptr = NULL; uint32_t field_len; uint32_t field_len_bytes = blob_lengths[blob_index]; get_blob_field_info( - &blob_offset, + &blob_offset, mcp_info.len_of_offsets, - var_field_data_ptr, - num_offset_bytes - ); + var_field_data_ptr, + num_offset_bytes); blob_ptr = var_field_data_ptr + blob_offset; - assert(num_blobs > 0); - // - // skip over other blobs to get to the one we want to make a key out of - // + assert_always(num_blobs > 0); + + // skip over other blobs to get to the one we want to + // make a key out of for (uint32_t i = 0; i < blob_index; i++) { blob_ptr = unpack_toku_field_blob( NULL, blob_ptr, blob_lengths[i], - true - ); + true); } - // - // at this point, blob_ptr is pointing to the blob we want to make a key from - // + // at this point, blob_ptr is pointing to the blob we + // want to make a key from field_len = get_blob_field_len(blob_ptr, field_len_bytes); - // // now we set the variables to make the key - // data_start = blob_ptr + field_len_bytes; data_size = field_len; - - - } - else { - assert(false); + } else { + assert_unreachable(); } - packed_key_pos = pack_toku_varstring_from_desc( - packed_key_pos, + packed_key_pos = pack_toku_varstring_from_desc(packed_key_pos, data_start, key_length, data_size, - charset_num - ); + charset_num); } - } - // - // case where column is in pk key - // - else { + } else { + // case where column is in pk key if (col_fix_val == COL_FIX_PK_OFFSET) { memcpy(packed_key_pos, &pk_data_ptr[col_pack_val], key_length); packed_key_pos += key_length; - } - else if (col_fix_val == COL_VAR_PK_OFFSET) { + } else if (col_fix_val == COL_VAR_PK_OFFSET) { uchar* tmp_pk_data_ptr = pk_data_ptr; uint32_t index_in_pk = col_pack_val; // @@ -2981,25 +2951,21 @@ static uint32_t pack_key_from_desc( for (uint32_t i = 0; i < index_in_pk; i++) { if (pk_info[2*i] == COL_FIX_FIELD) { tmp_pk_data_ptr += pk_info[2*i + 1]; - } - else if (pk_info[2*i] == COL_VAR_FIELD) { + } else if (pk_info[2*i] == COL_VAR_FIELD) { uint32_t len_bytes = pk_info[2*i + 1]; uint32_t len; if (len_bytes == 1) { len = tmp_pk_data_ptr[0]; tmp_pk_data_ptr++; - } - else if (len_bytes == 2) { + } else if (len_bytes == 2) { len = uint2korr(tmp_pk_data_ptr); tmp_pk_data_ptr += 2; - } - else { - assert(false); + } else { + assert_unreachable(); } tmp_pk_data_ptr += len; - } - else { - assert(false); + } else { + assert_unreachable(); } } // @@ -3009,21 +2975,18 @@ static uint32_t pack_key_from_desc( if (is_fix_field == COL_FIX_FIELD) { memcpy(packed_key_pos, tmp_pk_data_ptr, key_length); packed_key_pos += key_length; - } - else if (is_fix_field == COL_VAR_FIELD) { + } else if (is_fix_field == COL_VAR_FIELD) { const uchar* data_start = NULL; uint32_t data_size = 0; uint32_t len_bytes = pk_info[2*index_in_pk + 1]; if (len_bytes == 1) { data_size = tmp_pk_data_ptr[0]; tmp_pk_data_ptr++; - } - else if (len_bytes == 2) { + } else if (len_bytes == 2) { data_size = uint2korr(tmp_pk_data_ptr); tmp_pk_data_ptr += 2; - } - else { - assert(false); + } else { + assert_unreachable(); } data_start = tmp_pk_data_ptr; @@ -3033,32 +2996,26 @@ static uint32_t pack_key_from_desc( data_start, key_length, data_size, - charset_num - ); - } - else if (has_charset == COL_HAS_NO_CHARSET) { + charset_num); + } else if (has_charset == COL_HAS_NO_CHARSET) { packed_key_pos = pack_toku_varbinary_from_desc( - packed_key_pos, - data_start, + packed_key_pos, + data_start, key_length, - data_size //length of field - ); - } - else { - assert(false); + data_size); + } else { + assert_unreachable(); } + } else { + assert_unreachable(); } - else { - assert(false); - } - } - else { - assert(false); + } else { + assert_unreachable(); } } } - assert( (uint32_t)(desc_pos - (uchar *)row_desc) == row_desc_size); + assert_always( (uint32_t)(desc_pos - (uchar *)row_desc) == row_desc_size); // // now append the primary key to the end of the key @@ -3066,13 +3023,12 @@ static uint32_t pack_key_from_desc( if (hpk) { memcpy(packed_key_pos, pk_key->data, pk_key->size); packed_key_pos += pk_key->size; - } - else { + } else { memcpy(packed_key_pos, (uchar *)pk_key->data + 1, pk_key->size - 1); packed_key_pos += (pk_key->size - 1); } - return (uint32_t)(packed_key_pos - buf); // + return (uint32_t)(packed_key_pos - buf); } static bool fields_have_same_name(Field* a, Field* b) { @@ -3249,7 +3205,7 @@ static bool fields_are_same_type(Field* a, Field* b) { case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_NULL: - assert(false); + assert_unreachable(); } cleanup: diff --git a/storage/tokudb/hatoku_cmp.h b/storage/tokudb/hatoku_cmp.h index 9a5358fc9afba..34b3cfbe1f80b 100644 --- a/storage/tokudb/hatoku_cmp.h +++ b/storage/tokudb/hatoku_cmp.h @@ -26,9 +26,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ifndef _HATOKU_CMP #define _HATOKU_CMP -#include "stdint.h" +#include "hatoku_defines.h" +#include "tokudb_debug.h" -#include // // A MySQL row is encoded in TokuDB, as follows: @@ -180,7 +180,7 @@ static inline uint32_t get_blob_field_len(const uchar* from_tokudb, uint32_t len length = uint4korr(from_tokudb); break; default: - assert(false); + assert_unreachable(); } return length; } diff --git a/storage/tokudb/hatoku_defines.h b/storage/tokudb/hatoku_defines.h index 225d11068ec12..27b4493c804ed 100644 --- a/storage/tokudb/hatoku_defines.h +++ b/storage/tokudb/hatoku_defines.h @@ -23,8 +23,49 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." -#ifndef _TOKUDB_CONFIG_H -#define _TOKUDB_CONFIG_H +#ifndef _HATOKU_DEFINES_H +#define _HATOKU_DEFINES_H + +#include +#define MYSQL_SERVER 1 +#include "mysql_version.h" +#include "sql_table.h" +#include "handler.h" +#include "table.h" +#include "log.h" +#include "sql_class.h" +#include "sql_show.h" +#include "discover.h" + +#if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) +#include +#endif + +#undef PACKAGE +#undef VERSION +#undef HAVE_DTRACE +#undef _DTRACE_VERSION + +/* We define DTRACE after mysql_priv.h in case it disabled dtrace in the main server */ +#ifdef HAVE_DTRACE +#define _DTRACE_VERSION 1 +#else +#endif + +#include + +#include +#include +#define __STDC_FORMAT_MACROS +#include +#if defined(_WIN32) +#include "misc.h" +#endif + +#include "db.h" +#include "toku_os.h" +#include "toku_time.h" +#include "partitioned_counter.h" #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ @@ -161,326 +202,51 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. /* Bits for share->status */ #define STATUS_PRIMARY_KEY_INIT 0x1 -#endif // _TOKUDB_CONFIG_H - -#ifndef _TOKUDB_DEBUG_H -#define _TOKUDB_DEBUG_H - -#define TOKU_INCLUDE_BACKTRACE 0 -#if TOKU_INCLUDE_BACKTRACE -static void tokudb_backtrace(void); -#endif - -extern ulong tokudb_debug; - -// tokudb debug tracing -#define TOKUDB_DEBUG_INIT 1 -#define TOKUDB_DEBUG_OPEN 2 -#define TOKUDB_DEBUG_ENTER 4 -#define TOKUDB_DEBUG_RETURN 8 -#define TOKUDB_DEBUG_ERROR 16 -#define TOKUDB_DEBUG_TXN 32 -#define TOKUDB_DEBUG_AUTO_INCREMENT 64 -#define TOKUDB_DEBUG_INDEX_KEY 128 -#define TOKUDB_DEBUG_LOCK 256 -#define TOKUDB_DEBUG_CHECK_KEY 1024 -#define TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS 2048 -#define TOKUDB_DEBUG_ALTER_TABLE 4096 -#define TOKUDB_DEBUG_UPSERT 8192 -#define TOKUDB_DEBUG_CHECK (1<<14) -#define TOKUDB_DEBUG_ANALYZE (1<<15) - -#define TOKUDB_TRACE(f, ...) { \ - fprintf(stderr, "%u %s:%u %s " f "\n", my_tid(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ -} - -static inline unsigned int my_tid() { - return (unsigned int)toku_os_gettid(); -} - -#define TOKUDB_DBUG_ENTER(f, ...) { \ - if (tokudb_debug & TOKUDB_DEBUG_ENTER) { \ - TOKUDB_TRACE(f, ##__VA_ARGS__); \ - } \ -} \ - DBUG_ENTER(__FUNCTION__); - -#define TOKUDB_DBUG_RETURN(r) { \ - int rr = (r); \ - if ((tokudb_debug & TOKUDB_DEBUG_RETURN) || (rr != 0 && (tokudb_debug & TOKUDB_DEBUG_ERROR))) { \ - TOKUDB_TRACE("return %d", rr); \ - } \ - DBUG_RETURN(rr); \ -} - -#define TOKUDB_HANDLER_TRACE(f, ...) \ - fprintf(stderr, "%u %p %s:%u ha_tokudb::%s " f "\n", my_tid(), this, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); - -#define TOKUDB_HANDLER_DBUG_ENTER(f, ...) { \ - if (tokudb_debug & TOKUDB_DEBUG_ENTER) { \ - TOKUDB_HANDLER_TRACE(f, ##__VA_ARGS__); \ - } \ -} \ - DBUG_ENTER(__FUNCTION__); - -#define TOKUDB_HANDLER_DBUG_RETURN(r) { \ - int rr = (r); \ - if ((tokudb_debug & TOKUDB_DEBUG_RETURN) || (rr != 0 && (tokudb_debug & TOKUDB_DEBUG_ERROR))) { \ - TOKUDB_HANDLER_TRACE("return %d", rr); \ - } \ - DBUG_RETURN(rr); \ -} - -#define TOKUDB_HANDLER_DBUG_VOID_RETURN { \ - if (tokudb_debug & TOKUDB_DEBUG_RETURN) { \ - TOKUDB_HANDLER_TRACE("return"); \ - } \ - DBUG_VOID_RETURN; \ -} - -#define TOKUDB_DBUG_DUMP(s, p, len) \ -{ \ - TOKUDB_TRACE("%s", s); \ - uint i; \ - for (i=0; ideleted = 0; - val->inserted = 0; - val->updated = 0; - val->queried = 0; -} - -static inline int get_name_length(const char *name) { - int n = 0; - const char *newname = name; - n += strlen(newname); - n += strlen(ha_tokudb_ext); - return n; -} - -// -// returns maximum length of path to a dictionary -// -static inline int get_max_dict_name_path_length(const char *tablename) { - int n = 0; - n += get_name_length(tablename); - n += 1; //for the '-' - n += MAX_DICT_NAME_LEN; - return n; -} - -static inline void make_name(char *newname, const char *tablename, const char *dictname) { - const char *newtablename = tablename; - char *nn = newname; - assert(tablename); - assert(dictname); - nn += sprintf(nn, "%s", newtablename); - nn += sprintf(nn, "-%s", dictname); -} - -static inline int txn_begin(DB_ENV *env, DB_TXN *parent, DB_TXN **txn, uint32_t flags, THD *thd) { - *txn = NULL; - int r = env->txn_begin(env, parent, txn, flags); - if (r == 0 && thd) { - DB_TXN *this_txn = *txn; - this_txn->set_client_id(this_txn, thd_get_thread_id(thd)); - } - if ((tokudb_debug & TOKUDB_DEBUG_TXN)) { - TOKUDB_TRACE("begin txn %p %p %u r=%d", parent, *txn, flags, r); - } - return r; -} - -static inline void commit_txn(DB_TXN* txn, uint32_t flags) { - if (tokudb_debug & TOKUDB_DEBUG_TXN) - TOKUDB_TRACE("commit txn %p", txn); - int r = txn->commit(txn, flags); - if (r != 0) { - sql_print_error("tried committing transaction %p and got error code %d", txn, r); - } - assert(r == 0); -} - -static inline void abort_txn(DB_TXN* txn) { - if (tokudb_debug & TOKUDB_DEBUG_TXN) - TOKUDB_TRACE("abort txn %p", txn); - int r = txn->abort(txn); - if (r != 0) { - sql_print_error("tried aborting transaction %p and got error code %d", txn, r); - } - assert(r == 0); -} - -#endif // _TOKUDB_TXN_H - -#ifndef _TOKUDB_PORTABILITY_H -#define _TOKUDB_PORTABILITY_H - -static inline void *tokudb_my_malloc(size_t s, myf flags) { -#if 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799 - return my_malloc(0, s, flags); +#if defined(TOKUDB_VERSION_MAJOR) && defined(TOKUDB_VERSION_MINOR) +#define TOKUDB_PLUGIN_VERSION ((TOKUDB_VERSION_MAJOR << 8) + TOKUDB_VERSION_MINOR) #else - return my_malloc(s, flags); +#define TOKUDB_PLUGIN_VERSION 0 #endif -} -static inline void *tokudb_my_realloc(void *p, size_t s, myf flags) { - if (s == 0) - return p; -#if 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799 - return my_realloc(0, p, s, flags); -#else - return my_realloc(p, s, flags); -#endif -} +// Branch prediction macros. +// If supported by the compiler, will hint in instruction caching for likely +// branching. Should only be used where there is a very good idea of the correct +// branch heuristics as determined by profiling. Mostly copied from InnoDB. +// Use: +// "if (TOKUDB_LIKELY(x))" where the chances of "x" evaluating true are higher +// "if (TOKUDB_UNLIKELY(x))" where the chances of "x" evaluating false are higher +#if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER) -static inline void tokudb_my_free(void *ptr) { - if (ptr) - my_free(ptr); -} +// Tell the compiler that 'expr' probably evaluates to 'constant'. +#define TOKUDB_EXPECT(expr,constant) __builtin_expect(expr, constant) -static inline char *tokudb_my_strdup(const char *p, myf flags) { -#if 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799 - return my_strdup(0, p, flags); #else - return my_strdup(p, flags); -#endif -} - -static inline void* tokudb_my_multi_malloc(myf myFlags, ...) { - va_list args; - char **ptr,*start,*res; - size_t tot_length,length; - - va_start(args,myFlags); - 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 *) tokudb_my_malloc(tot_length,myFlags))) { - return 0; - } - - va_start(args,myFlags); - res=start; - while ((ptr=va_arg(args, char **))) { - *ptr=res; - length=va_arg(args,uint); - res+=ALIGN_SIZE(length); - } - va_end(args); - return start; -} - -static inline void tokudb_pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - int r = pthread_mutex_init(mutex, attr); - assert(r == 0); -} - -static inline void tokudb_pthread_mutex_destroy(pthread_mutex_t *mutex) { - int r = pthread_mutex_destroy(mutex); - assert(r == 0); -} -static inline void tokudb_pthread_mutex_lock(pthread_mutex_t *mutex) { - int r = pthread_mutex_lock(mutex); - assert(r == 0); -} +#error "No TokuDB branch prediction operations in use!" +#define TOKUDB_EXPECT(expr,constant) (expr) -static inline void tokudb_pthread_mutex_unlock(pthread_mutex_t *mutex) { - int r = pthread_mutex_unlock(mutex); - assert(r == 0); -} +#endif // defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER) -static inline void tokudb_pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { - int r = pthread_cond_init(cond, attr); - assert(r == 0); -} +// Tell the compiler that cond is likely to hold +#define TOKUDB_LIKELY(cond) TOKUDB_EXPECT(cond, 1) -static inline void tokudb_pthread_cond_destroy(pthread_cond_t *cond) { - int r = pthread_cond_destroy(cond); - assert(r == 0); -} - -static inline void tokudb_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - int r = pthread_cond_wait(cond, mutex); - assert(r == 0); -} - -static inline void tokudb_pthread_cond_broadcast(pthread_cond_t *cond) { - int r = pthread_cond_broadcast(cond); - assert(r == 0); -} +// Tell the compiler that cond is unlikely to hold +#define TOKUDB_UNLIKELY(cond) TOKUDB_EXPECT(cond, 0) +// Tell the compiler that the function/argument is unused +#define TOKUDB_UNUSED(_uu) _uu __attribute__((unused)) // mysql 5.6.15 removed the test macro, so we define our own #define tokudb_test(e) ((e) ? 1 : 0) -static const char *tokudb_thd_get_proc_info(THD *thd) { +inline const char* tokudb_thd_get_proc_info(const THD *thd) { return thd->proc_info; } // uint3korr reads 4 bytes and valgrind reports an error, so we use this function instead -static uint tokudb_uint3korr(const uchar *a) { +inline uint tokudb_uint3korr(const uchar *a) { uchar b[4] = {}; memcpy(b, a, 3); return uint3korr(b); } -#endif // _TOKUDB_PORTABILITY_H +#endif // _HATOKU_DEFINES_H diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 959490b3160b2..086280a76dfdb 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -24,35 +24,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." -#define MYSQL_SERVER 1 -#include "hatoku_defines.h" -#include -#include - -#include "stdint.h" -#if defined(_WIN32) -#include "misc.h" -#endif -#define __STDC_FORMAT_MACROS -#include -#include "toku_os.h" -#include "toku_time.h" -#include "partitioned_counter.h" - -/* We define DTRACE after mysql_priv.h in case it disabled dtrace in the main server */ -#ifdef HAVE_DTRACE -#define _DTRACE_VERSION 1 -#else -#endif - -#include #include "hatoku_hton.h" -#include "ha_tokudb.h" - -#undef PACKAGE -#undef VERSION -#undef HAVE_DTRACE -#undef _DTRACE_VERSION #define TOKU_METADB_NAME "tokudb_meta" @@ -74,63 +46,96 @@ ha_create_table_option tokudb_index_options[] = { }; #endif -static uchar *tokudb_get_key(TOKUDB_SHARE * share, size_t * length, my_bool not_used __attribute__ ((unused))) { - *length = share->table_name_length; - return (uchar *) share->table_name; -} - -static handler *tokudb_create_handler(handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root); +static handler* tokudb_create_handler( + handlerton* hton, + TABLE_SHARE* table, + MEM_ROOT* mem_root); - -static void tokudb_print_error(const DB_ENV * db_env, const char *db_errpfx, const char *buffer); +static void tokudb_print_error( + const DB_ENV* db_env, + const char* db_errpfx, + const char* buffer); static void tokudb_cleanup_log_files(void); -static int tokudb_end(handlerton * hton, ha_panic_function type); -static bool tokudb_flush_logs(handlerton * hton); -static bool tokudb_show_status(handlerton * hton, THD * thd, stat_print_fn * print, enum ha_stat_type); +static int tokudb_end(handlerton* hton, ha_panic_function type); +static bool tokudb_flush_logs(handlerton* hton); +static bool tokudb_show_status( + handlerton* hton, + THD* thd, + stat_print_fn* print, + enum ha_stat_type); #if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL -static void tokudb_handle_fatal_signal(handlerton *hton, THD *thd, int sig); +static void tokudb_handle_fatal_signal(handlerton* hton, THD* thd, int sig); #endif -static int tokudb_close_connection(handlerton * hton, THD * thd); -static int tokudb_commit(handlerton * hton, THD * thd, bool all); -static int tokudb_rollback(handlerton * hton, THD * thd, bool all); +static int tokudb_close_connection(handlerton* hton, THD* thd); +static int tokudb_commit(handlerton* hton, THD* thd, bool all); +static int tokudb_rollback(handlerton* hton, THD* thd, bool all); #if TOKU_INCLUDE_XA static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all); -static int tokudb_xa_recover(handlerton* hton, XID* xid_list, uint len); +static int tokudb_xa_recover(handlerton* hton, XID* xid_list, uint len); static int tokudb_commit_by_xid(handlerton* hton, XID* xid); -static int tokudb_rollback_by_xid(handlerton* hton, XID* xid); +static int tokudb_rollback_by_xid(handlerton* hton, XID* xid); #endif -static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint); -static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint); -static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint); +static int tokudb_rollback_to_savepoint( + handlerton* hton, + THD* thd, + void* savepoint); +static int tokudb_savepoint(handlerton* hton, THD* thd, void* savepoint); +static int tokudb_release_savepoint( + handlerton* hton, + THD* thd, + void* savepoint); #if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099 static int tokudb_discover_table(handlerton *hton, THD* thd, TABLE_SHARE *ts); -static int tokudb_discover_table_existence(handlerton *hton, const char *db, const char *name); +static int tokudb_discover_table_existence( + handlerton* hton, + const char* db, + const char* name); #endif -static int tokudb_discover(handlerton *hton, THD* thd, const char *db, const char *name, uchar **frmblob, size_t *frmlen); -static int tokudb_discover2(handlerton *hton, THD* thd, const char *db, const char *name, bool translate_name, uchar **frmblob, size_t *frmlen); -static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const char *name, char *path, uchar **frmblob, size_t *frmlen); -handlerton *tokudb_hton; - -const char *ha_tokudb_ext = ".tokudb"; -char *tokudb_data_dir; -ulong tokudb_debug; -DB_ENV *db_env; -HASH tokudb_open_tables; -pthread_mutex_t tokudb_mutex; +static int tokudb_discover( + handlerton* hton, + THD* thd, + const char* db, + const char* name, + uchar** frmblob, + size_t* frmlen); +static int tokudb_discover2( + handlerton* hton, + THD* thd, + const char* db, + const char* name, + bool translate_name, + uchar** frmblob, + size_t* frmlen); +static int tokudb_discover3( + handlerton* hton, + THD* thd, + const char* db, + const char* name, + char* path, + uchar** frmblob, + size_t* frmlen); +handlerton* tokudb_hton; + +const char* ha_tokudb_ext = ".tokudb"; +DB_ENV* db_env; #if TOKU_THDVAR_MEMALLOC_BUG -static pthread_mutex_t tokudb_map_mutex; +static tokudb::thread::mutex_t tokudb_map_mutex; static TREE tokudb_map; struct tokudb_map_pair { - THD *thd; + THD* thd; char *last_lock_timeout; }; #if 50500 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50599 static int tokudb_map_pair_cmp(void *custom_arg, const void *a, const void *b) { #else -static int tokudb_map_pair_cmp(const void *custom_arg, const void *a, const void *b) { +static int tokudb_map_pair_cmp( + const void* custom_arg, + const void* a, + const void* b) { #endif + const struct tokudb_map_pair *a_key = (const struct tokudb_map_pair *) a; const struct tokudb_map_pair *b_key = (const struct tokudb_map_pair *) b; if (a_key->thd < b_key->thd) @@ -142,30 +147,41 @@ static int tokudb_map_pair_cmp(const void *custom_arg, const void *a, const void }; #endif -#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL -static my_bool tokudb_gdb_on_fatal; -static char *tokudb_gdb_path; -#endif - static PARTITIONED_COUNTER tokudb_primary_key_bytes_inserted; void toku_hton_update_primary_key_bytes_inserted(uint64_t row_size) { increment_partitioned_counter(tokudb_primary_key_bytes_inserted, row_size); } -static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, const DBT *left_key, const DBT *right_key, uint64_t blocking_txnid); -static ulong tokudb_cleaner_period; -static ulong tokudb_cleaner_iterations; +static void tokudb_lock_timeout_callback( + DB* db, + uint64_t requesting_txnid, + const DBT* left_key, + const DBT* right_key, + uint64_t blocking_txnid); #define ASSERT_MSGLEN 1024 -void toku_hton_assert_fail(const char* expr_as_string, const char * fun, const char * file, int line, int caller_errno) { +void toku_hton_assert_fail( + const char* expr_as_string, + const char* fun, + const char* file, + int line, + int caller_errno) { + char msg[ASSERT_MSGLEN]; if (db_env) { snprintf(msg, ASSERT_MSGLEN, "Handlerton: %s ", expr_as_string); db_env->crash(db_env, msg, fun, file, line,caller_errno); - } - else { - snprintf(msg, ASSERT_MSGLEN, "Handlerton assertion failed, no env, %s, %d, %s, %s (errno=%d)\n", file, line, fun, expr_as_string, caller_errno); + } else { + snprintf( + msg, + ASSERT_MSGLEN, + "Handlerton assertion failed, no env, %s, %d, %s, %s (errno=%d)\n", + file, + line, + fun, + expr_as_string, + caller_errno); perror(msg); fflush(stderr); } @@ -184,36 +200,11 @@ static uint32_t tokudb_env_flags = 0; // static uint32_t tokudb_lock_type = DB_LOCK_DEFAULT; // static ulong tokudb_log_buffer_size = 0; // static ulong tokudb_log_file_size = 0; -static my_bool tokudb_directio = FALSE; -static my_bool tokudb_compress_buffers_before_eviction = TRUE; -static my_bool tokudb_checkpoint_on_flush_logs = FALSE; -static ulonglong tokudb_cache_size = 0; -static uint32_t tokudb_client_pool_threads = 0; -static uint32_t tokudb_cachetable_pool_threads = 0; -static uint32_t tokudb_checkpoint_pool_threads = 0; -static ulonglong tokudb_max_lock_memory = 0; -static my_bool tokudb_enable_partial_eviction = TRUE; -static char *tokudb_home; -static char *tokudb_tmp_dir; -static char *tokudb_log_dir; +static char* tokudb_home; // static long tokudb_lock_scan_time = 0; // static ulong tokudb_region_size = 0; // static ulong tokudb_cache_parts = 1; -const char *tokudb_hton_name = "TokuDB"; -static uint32_t tokudb_checkpointing_period; -static uint32_t tokudb_fsync_log_period; -uint32_t tokudb_write_status_frequency; -uint32_t tokudb_read_status_frequency; - -#ifdef TOKUDB_VERSION -#define tokudb_stringify_2(x) #x -#define tokudb_stringify(x) tokudb_stringify_2(x) -#define TOKUDB_VERSION_STR tokudb_stringify(TOKUDB_VERSION) -#else -#define TOKUDB_VERSION_STR NULL -#endif -char *tokudb_version = (char *) TOKUDB_VERSION_STR; -static int tokudb_fs_reserve_percent; // file system reserve as a percentage of total disk space +const char* tokudb_hton_name = "TokuDB"; #if defined(_WIN32) extern "C" { @@ -226,18 +217,8 @@ extern "C" { // Since we don't have static initializers for the opaque rwlock type, // use constructor and destructor functions to create and destroy // the lock before and after main(), respectively. -static int tokudb_hton_initialized; -static rw_lock_t tokudb_hton_initialized_lock; - -static void create_tokudb_hton_intialized_lock(void) __attribute__((constructor)); -static void create_tokudb_hton_intialized_lock(void) { - my_rwlock_init(&tokudb_hton_initialized_lock, 0); -} - -static void destroy_tokudb_hton_initialized_lock(void) __attribute__((destructor)); -static void destroy_tokudb_hton_initialized_lock(void) { - rwlock_destroy(&tokudb_hton_initialized_lock); -} +int tokudb_hton_initialized; +tokudb::thread::rwlock_t tokudb_hton_initialized_lock; static SHOW_VAR *toku_global_status_variables = NULL; static uint64_t toku_global_status_max_rows; @@ -266,7 +247,10 @@ static void handle_ydb_error(int error) { sql_print_error("************************************************************"); break; case TOKUDB_UPGRADE_FAILURE: - sql_print_error("%s upgrade failed. A clean shutdown of the previous version is required.", tokudb_hton_name); + sql_print_error( + "%s upgrade failed. A clean shutdown of the previous version is " + "required.", + tokudb_hton_name); break; default: sql_print_error("%s unknown error %d", tokudb_hton_name, error); @@ -289,27 +273,51 @@ static int tokudb_init_func(void *p) { int r; // 3938: lock the handlerton's initialized status flag for writing - r = rw_wrlock(&tokudb_hton_initialized_lock); - assert(r == 0); + tokudb_hton_initialized_lock.lock_write(); db_env = NULL; tokudb_hton = (handlerton *) p; #if TOKUDB_CHECK_JEMALLOC - if (tokudb_check_jemalloc && dlsym(RTLD_DEFAULT, "mallctl") == NULL) { - sql_print_error("%s is not initialized because jemalloc is not loaded", tokudb_hton_name); - goto error; + if (tokudb::sysvars::check_jemalloc) { + typedef int (*mallctl_type)( + const char*, + void*, + size_t*, + void*, + size_t); + mallctl_type mallctl_func; + mallctl_func= (mallctl_type)dlsym(RTLD_DEFAULT, "mallctl"); + if (!mallctl_func) { + sql_print_error( + "%s is not initialized because jemalloc is not loaded", + tokudb_hton_name); + goto error; + } + char *ver; + size_t len = sizeof(ver); + mallctl_func("version", &ver, &len, NULL, 0); + /* jemalloc 2.2.5 crashes mysql-test */ + if (strcmp(ver, "2.3.") < 0) { + sql_print_error( + "%s is not initialized because jemalloc is older than 2.3.0", + tokudb_hton_name); + goto error; + } } #endif r = tokudb_set_product_name(); if (r) { - sql_print_error("%s can not set product name error %d", tokudb_hton_name, r); + sql_print_error( + "%s can not set product name error %d", + tokudb_hton_name, + r); goto error; } - tokudb_pthread_mutex_init(&tokudb_mutex, MY_MUTEX_INIT_FAST); - (void) my_hash_init(&tokudb_open_tables, table_alias_charset, 32, 0, 0, (my_hash_get_key) tokudb_get_key, 0, 0); + TOKUDB_SHARE::static_init(); + tokudb::background::initialize(); tokudb_hton->state = SHOW_OPTION_YES; // tokudb_hton->flags= HTON_CAN_RECREATE; // QQQ this came from skeleton @@ -386,8 +394,11 @@ static int tokudb_init_func(void *p) { DBUG_PRINT("info", ("tokudb_env_flags: 0x%x\n", tokudb_env_flags)); r = db_env->set_flags(db_env, tokudb_env_flags, 1); if (r) { // QQQ - if (tokudb_debug & TOKUDB_DEBUG_INIT) - TOKUDB_TRACE("WARNING: flags=%x r=%d", tokudb_env_flags, r); + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_INIT, + "WARNING: flags=%x r=%d", + tokudb_env_flags, + r); // goto error; } @@ -405,8 +416,8 @@ static int tokudb_init_func(void *p) { } { - char *tmp_dir = tokudb_tmp_dir; - char *data_dir = tokudb_data_dir; + char* tmp_dir = tokudb::sysvars::tmp_dir; + char* data_dir = tokudb::sysvars::data_dir; if (data_dir == 0) { data_dir = mysql_data_home; } @@ -419,36 +430,48 @@ static int tokudb_init_func(void *p) { db_env->set_tmp_dir(db_env, tmp_dir); } - if (tokudb_log_dir) { - DBUG_PRINT("info", ("tokudb_log_dir: %s\n", tokudb_log_dir)); - db_env->set_lg_dir(db_env, tokudb_log_dir); + if (tokudb::sysvars::log_dir) { + DBUG_PRINT("info", ("tokudb_log_dir: %s\n", tokudb::sysvars::log_dir)); + db_env->set_lg_dir(db_env, tokudb::sysvars::log_dir); } - // config the cache table size to min(1/2 of physical memory, 1/8 of the process address space) - if (tokudb_cache_size == 0) { + // config the cache table size to min(1/2 of physical memory, 1/8 of the + // process address space) + if (tokudb::sysvars::cache_size == 0) { uint64_t physmem, maxdata; physmem = toku_os_get_phys_memory_size(); - tokudb_cache_size = physmem / 2; + tokudb::sysvars::cache_size = physmem / 2; r = toku_os_get_max_process_data_size(&maxdata); if (r == 0) { - if (tokudb_cache_size > maxdata / 8) - tokudb_cache_size = maxdata / 8; + if (tokudb::sysvars::cache_size > maxdata / 8) + tokudb::sysvars::cache_size = maxdata / 8; } } - if (tokudb_cache_size) { - DBUG_PRINT("info", ("tokudb_cache_size: %lld\n", tokudb_cache_size)); - r = db_env->set_cachesize(db_env, (uint32_t)(tokudb_cache_size >> 30), (uint32_t)(tokudb_cache_size % (1024L * 1024L * 1024L)), 1); + if (tokudb::sysvars::cache_size) { + DBUG_PRINT( + "info", + ("tokudb_cache_size: %lld\n", tokudb::sysvars::cache_size)); + r = db_env->set_cachesize( + db_env, + (uint32_t)(tokudb::sysvars::cache_size >> 30), + (uint32_t)(tokudb::sysvars::cache_size % + (1024L * 1024L * 1024L)), 1); if (r) { DBUG_PRINT("info", ("set_cachesize %d\n", r)); goto error; } } - if (tokudb_max_lock_memory == 0) { - tokudb_max_lock_memory = tokudb_cache_size/8; - } - if (tokudb_max_lock_memory) { - DBUG_PRINT("info", ("tokudb_max_lock_memory: %lld\n", tokudb_max_lock_memory)); - r = db_env->set_lk_max_memory(db_env, tokudb_max_lock_memory); + if (tokudb::sysvars::max_lock_memory == 0) { + tokudb::sysvars::max_lock_memory = tokudb::sysvars::cache_size/8; + } + if (tokudb::sysvars::max_lock_memory) { + DBUG_PRINT( + "info", + ("tokudb_max_lock_memory: %lld\n", + tokudb::sysvars::max_lock_memory)); + r = db_env->set_lk_max_memory( + db_env, + tokudb::sysvars::max_lock_memory); if (r) { DBUG_PRINT("info", ("set_lk_max_memory %d\n", r)); goto error; @@ -457,51 +480,73 @@ static int tokudb_init_func(void *p) { uint32_t gbytes, bytes; int parts; r = db_env->get_cachesize(db_env, &gbytes, &bytes, &parts); - if (tokudb_debug & TOKUDB_DEBUG_INIT) - TOKUDB_TRACE("tokudb_cache_size=%lld r=%d", ((unsigned long long) gbytes << 30) + bytes, r); + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_INIT, + "tokudb_cache_size=%lld r=%d", + ((unsigned long long) gbytes << 30) + bytes, + r); - r = db_env->set_client_pool_threads(db_env, tokudb_client_pool_threads); + r = db_env->set_client_pool_threads( + db_env, + tokudb::sysvars::client_pool_threads); if (r) { DBUG_PRINT("info", ("set_client_pool_threads %d\n", r)); goto error; } - r = db_env->set_cachetable_pool_threads(db_env, tokudb_cachetable_pool_threads); + r = db_env->set_cachetable_pool_threads( + db_env, + tokudb::sysvars::cachetable_pool_threads); if (r) { DBUG_PRINT("info", ("set_cachetable_pool_threads %d\n", r)); goto error; } - r = db_env->set_checkpoint_pool_threads(db_env, tokudb_checkpoint_pool_threads); + r = db_env->set_checkpoint_pool_threads( + db_env, + tokudb::sysvars::checkpoint_pool_threads); if (r) { DBUG_PRINT("info", ("set_checkpoint_pool_threads %d\n", r)); goto error; } if (db_env->set_redzone) { - r = db_env->set_redzone(db_env, tokudb_fs_reserve_percent); - if (tokudb_debug & TOKUDB_DEBUG_INIT) - TOKUDB_TRACE("set_redzone r=%d", r); + r = db_env->set_redzone(db_env, tokudb::sysvars::fs_reserve_percent); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_INIT, "set_redzone r=%d", r); } + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_INIT, + "env open:flags=%x", + tokudb_init_flags); + + r = db_env->set_generate_row_callback_for_put(db_env, generate_row_for_put); + assert_always(r == 0); - if (tokudb_debug & TOKUDB_DEBUG_INIT) - TOKUDB_TRACE("env open:flags=%x", tokudb_init_flags); + r = db_env->set_generate_row_callback_for_del(db_env, generate_row_for_del); + assert_always(r == 0); - r = db_env->set_generate_row_callback_for_put(db_env,generate_row_for_put); - assert(r == 0); - r = db_env->set_generate_row_callback_for_del(db_env,generate_row_for_del); - assert(r == 0); db_env->set_update(db_env, tokudb_update_fun); - db_env_set_direct_io(tokudb_directio == TRUE); - db_env_set_compress_buffers_before_eviction(tokudb_compress_buffers_before_eviction == TRUE); - db_env->change_fsync_log_period(db_env, tokudb_fsync_log_period); + + db_env_set_direct_io(tokudb::sysvars::directio == TRUE); + + db_env_set_compress_buffers_before_eviction( + tokudb::sysvars::compress_buffers_before_eviction == TRUE); + + db_env->change_fsync_log_period(db_env, tokudb::sysvars::fsync_log_period); + db_env->set_lock_timeout_callback(db_env, tokudb_lock_timeout_callback); - db_env->set_loader_memory_size(db_env, tokudb_get_loader_memory_size_callback); - r = db_env->open(db_env, tokudb_home, tokudb_init_flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + db_env->set_loader_memory_size( + db_env, + tokudb_get_loader_memory_size_callback); + + r = db_env->open( + db_env, + tokudb_home, + tokudb_init_flags, + S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - if (tokudb_debug & TOKUDB_DEBUG_INIT) - TOKUDB_TRACE("env opened:return=%d", r); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_INIT, "env opened:return=%d", r); if (r) { DBUG_PRINT("info", ("env->open %d", r)); @@ -509,72 +554,106 @@ static int tokudb_init_func(void *p) { goto error; } - r = db_env->checkpointing_set_period(db_env, tokudb_checkpointing_period); - assert(r == 0); - r = db_env->cleaner_set_period(db_env, tokudb_cleaner_period); - assert(r == 0); - r = db_env->cleaner_set_iterations(db_env, tokudb_cleaner_iterations); - assert(r == 0); + r = db_env->checkpointing_set_period( + db_env, + tokudb::sysvars::checkpointing_period); + assert_always(r == 0); - r = db_env->set_lock_timeout(db_env, DEFAULT_TOKUDB_LOCK_TIMEOUT, tokudb_get_lock_wait_time_callback); - assert(r == 0); + r = db_env->cleaner_set_period(db_env, tokudb::sysvars::cleaner_period); + assert_always(r == 0); - r = db_env->evictor_set_enable_partial_eviction(db_env, - tokudb_enable_partial_eviction); - assert(r == 0); + r = db_env->cleaner_set_iterations( + db_env, + tokudb::sysvars::cleaner_iterations); + assert_always(r == 0); - db_env->set_killed_callback(db_env, DEFAULT_TOKUDB_KILLED_TIME, tokudb_get_killed_time_callback, tokudb_killed_callback); + r = db_env->set_lock_timeout( + db_env, + DEFAULT_TOKUDB_LOCK_TIMEOUT, + tokudb_get_lock_wait_time_callback); + assert_always(r == 0); - r = db_env->get_engine_status_num_rows (db_env, &toku_global_status_max_rows); - assert(r == 0); + r = db_env->evictor_set_enable_partial_eviction( + db_env, + tokudb::sysvars::enable_partial_eviction); + assert_always(r == 0); + + db_env->set_killed_callback( + db_env, + DEFAULT_TOKUDB_KILLED_TIME, + tokudb_get_killed_time_callback, + tokudb_killed_callback); + + r = db_env->get_engine_status_num_rows( + db_env, + &toku_global_status_max_rows); + assert_always(r == 0); { - const myf mem_flags = MY_FAE|MY_WME|MY_ZEROFILL|MY_ALLOW_ZERO_PTR|MY_FREE_ON_ERROR; - toku_global_status_variables = (SHOW_VAR*)tokudb_my_malloc(sizeof(*toku_global_status_variables)*toku_global_status_max_rows, mem_flags); - toku_global_status_rows = (TOKU_ENGINE_STATUS_ROW_S*)tokudb_my_malloc(sizeof(*toku_global_status_rows)*toku_global_status_max_rows, mem_flags); + const myf mem_flags = + MY_FAE|MY_WME|MY_ZEROFILL|MY_ALLOW_ZERO_PTR|MY_FREE_ON_ERROR; + toku_global_status_variables = + (SHOW_VAR*)tokudb::memory::malloc( + sizeof(*toku_global_status_variables) * + toku_global_status_max_rows, + mem_flags); + toku_global_status_rows = + (TOKU_ENGINE_STATUS_ROW_S*)tokudb::memory::malloc( + sizeof(*toku_global_status_rows)* + toku_global_status_max_rows, + mem_flags); } tokudb_primary_key_bytes_inserted = create_partitioned_counter(); #if TOKU_THDVAR_MEMALLOC_BUG - tokudb_pthread_mutex_init(&tokudb_map_mutex, MY_MUTEX_INIT_FAST); init_tree(&tokudb_map, 0, 0, 0, tokudb_map_pair_cmp, true, NULL, NULL); #endif + if (tokudb::sysvars::strip_frm_data) { + r = tokudb::metadata::strip_frm_data(db_env); + if (r) { + DBUG_PRINT("info", ("env->open %d", r)); + handle_ydb_error(r); + goto error; + } + } + //3938: succeeded, set the init status flag and unlock tokudb_hton_initialized = 1; - rw_unlock(&tokudb_hton_initialized_lock); + tokudb_hton_initialized_lock.unlock(); DBUG_RETURN(false); error: if (db_env) { int rr= db_env->close(db_env, 0); - assert(rr==0); + assert_always(rr==0); db_env = 0; } // 3938: failed to initialized, drop the flag and lock tokudb_hton_initialized = 0; - rw_unlock(&tokudb_hton_initialized_lock); + tokudb_hton_initialized_lock.unlock(); DBUG_RETURN(true); } -static int tokudb_done_func(void *p) { +static int tokudb_done_func(void* p) { TOKUDB_DBUG_ENTER(""); - tokudb_my_free(toku_global_status_variables); + tokudb::memory::free(toku_global_status_variables); toku_global_status_variables = NULL; - tokudb_my_free(toku_global_status_rows); + tokudb::memory::free(toku_global_status_rows); toku_global_status_rows = NULL; - my_hash_free(&tokudb_open_tables); - tokudb_pthread_mutex_destroy(&tokudb_mutex); TOKUDB_DBUG_RETURN(0); } -static handler *tokudb_create_handler(handlerton * hton, TABLE_SHARE * table, MEM_ROOT * mem_root) { +static handler* tokudb_create_handler( + handlerton* hton, + TABLE_SHARE* table, + MEM_ROOT* mem_root) { return new(mem_root) ha_tokudb(hton, table); } -int tokudb_end(handlerton * hton, ha_panic_function type) { +int tokudb_end(handlerton* hton, ha_panic_function type) { TOKUDB_DBUG_ENTER(""); int error = 0; @@ -582,41 +661,57 @@ int tokudb_end(handlerton * hton, ha_panic_function type) { // initialized. grab a writer lock for the duration of the // call, so we can drop the flag and destroy the mutexes // in isolation. - rw_wrlock(&tokudb_hton_initialized_lock); - assert(tokudb_hton_initialized); + tokudb_hton_initialized_lock.lock_write(); + assert_always(tokudb_hton_initialized); + + tokudb::background::destroy(); + TOKUDB_SHARE::static_destroy(); if (db_env) { if (tokudb_init_flags & DB_INIT_LOG) tokudb_cleanup_log_files(); - long total_prepared = 0; // count the total number of prepared txn's that we discard + + // count the total number of prepared txn's that we discard + long total_prepared = 0; #if TOKU_INCLUDE_XA while (1) { // get xid's const long n_xid = 1; TOKU_XA_XID xids[n_xid]; long n_prepared = 0; - error = db_env->txn_xa_recover(db_env, xids, n_xid, &n_prepared, total_prepared == 0 ? DB_FIRST : DB_NEXT); - assert(error == 0); + error = db_env->txn_xa_recover( + db_env, + xids, + n_xid, + &n_prepared, + total_prepared == 0 ? DB_FIRST : DB_NEXT); + assert_always(error == 0); if (n_prepared == 0) break; // discard xid's for (long i = 0; i < n_xid; i++) { DB_TXN *txn = NULL; error = db_env->get_txn_from_xid(db_env, &xids[i], &txn); - assert(error == 0); + assert_always(error == 0); error = txn->discard(txn, 0); - assert(error == 0); + assert_always(error == 0); } total_prepared += n_prepared; } #endif - error = db_env->close(db_env, total_prepared > 0 ? TOKUFT_DIRTY_SHUTDOWN : 0); + error = db_env->close( + db_env, + total_prepared > 0 ? TOKUFT_DIRTY_SHUTDOWN : 0); #if TOKU_INCLUDE_XA if (error != 0 && total_prepared > 0) { - sql_print_error("%s: %ld prepared txns still live, please shutdown, error %d", tokudb_hton_name, total_prepared, error); + sql_print_error( + "%s: %ld prepared txns still live, please shutdown, error %d", + tokudb_hton_name, + total_prepared, + error); } else #endif - assert(error == 0); + assert_always(error == 0); db_env = NULL; } @@ -626,33 +721,34 @@ int tokudb_end(handlerton * hton, ha_panic_function type) { } #if TOKU_THDVAR_MEMALLOC_BUG - tokudb_pthread_mutex_destroy(&tokudb_map_mutex); delete_tree(&tokudb_map); #endif // 3938: drop the initialized flag and unlock tokudb_hton_initialized = 0; - rw_unlock(&tokudb_hton_initialized_lock); + tokudb_hton_initialized_lock.unlock(); TOKUDB_DBUG_RETURN(error); } -static int tokudb_close_connection(handlerton * hton, THD * thd) { +static int tokudb_close_connection(handlerton* hton, THD* thd) { int error = 0; - tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); if (trx && trx->checkpoint_lock_taken) { error = db_env->checkpointing_resume(db_env); } - tokudb_my_free(trx); + tokudb::memory::free(trx); #if TOKU_THDVAR_MEMALLOC_BUG - tokudb_pthread_mutex_lock(&tokudb_map_mutex); + tokudb_map_mutex.lock(); struct tokudb_map_pair key = { thd, NULL }; - struct tokudb_map_pair *found_key = (struct tokudb_map_pair *) tree_search(&tokudb_map, &key, NULL); + struct tokudb_map_pair* found_key = + (struct tokudb_map_pair*) tree_search(&tokudb_map, &key, NULL); + if (found_key) { - tokudb_my_free(found_key->last_lock_timeout); - tree_delete(&tokudb_map, found_key, sizeof *found_key, NULL); + tokudb::memory::free(found_key->last_lock_timeout); + tree_delete(&tokudb_map, found_key, sizeof(*found_key), NULL); } - tokudb_pthread_mutex_unlock(&tokudb_map_mutex); + tokudb_map_mutex.unlock(); #endif return error; } @@ -662,7 +758,7 @@ bool tokudb_flush_logs(handlerton * hton) { int error; bool result = 0; - if (tokudb_checkpoint_on_flush_logs) { + if (tokudb::sysvars::checkpoint_on_flush_logs) { // // take the checkpoint // @@ -675,7 +771,7 @@ bool tokudb_flush_logs(handlerton * hton) { } else { error = db_env->log_flush(db_env, NULL); - assert(error == 0); + assert_always(error == 0); } result = 0; @@ -691,14 +787,14 @@ typedef struct txn_progress_info { static void txn_progress_func(TOKU_TXN_PROGRESS progress, void* extra) { TXN_PROGRESS_INFO progress_info = (TXN_PROGRESS_INFO)extra; - int r = sprintf(progress_info->status, - "%sprocessing %s of transaction, %" PRId64 " out of %" PRId64, - progress->stalled_on_checkpoint ? "Writing committed changes to disk, " : "", - progress->is_commit ? "commit" : "abort", - progress->entries_processed, - progress->entries_total - ); - assert(r >= 0); + int r = sprintf( + progress_info->status, + "%sprocessing %s of transaction, %" PRId64 " out of %" PRId64, + progress->stalled_on_checkpoint ? "Writing committed changes to disk, " : "", + progress->is_commit ? "commit" : "abort", + progress->entries_processed, + progress->entries_total); + assert_always(r >= 0); thd_proc_info(progress_info->thd, progress_info->status); } @@ -708,9 +804,13 @@ static void commit_txn_with_progress(DB_TXN* txn, uint32_t flags, THD* thd) { info.thd = thd; int r = txn->commit_with_progress(txn, flags, txn_progress_func, &info); if (r != 0) { - sql_print_error("%s: tried committing transaction %p and got error code %d", tokudb_hton_name, txn, r); + sql_print_error( + "%s: tried committing transaction %p and got error code %d", + tokudb_hton_name, + txn, + r); } - assert(r == 0); + assert_always(r == 0); thd_proc_info(thd, orig_proc_info); } @@ -720,9 +820,13 @@ static void abort_txn_with_progress(DB_TXN* txn, THD* thd) { info.thd = thd; int r = txn->abort_with_progress(txn, txn_progress_func, &info); if (r != 0) { - sql_print_error("%s: tried aborting transaction %p and got error code %d", tokudb_hton_name, txn, r); + sql_print_error( + "%s: tried aborting transaction %p and got error code %d", + tokudb_hton_name, + txn, + r); } - assert(r == 0); + assert_always(r == 0); thd_proc_info(thd, orig_proc_info); } @@ -736,11 +840,12 @@ static void tokudb_cleanup_handlers(tokudb_trx_data *trx, DB_TXN *txn) { } #if MYSQL_VERSION_ID >= 50600 -extern "C" enum durability_properties thd_get_durability_property(const MYSQL_THD thd); +extern "C" enum durability_properties thd_get_durability_property( + const MYSQL_THD thd); #endif // Determine if an fsync is used when a transaction is committed. -static bool tokudb_sync_on_commit(THD *thd, tokudb_trx_data *trx, DB_TXN *txn) { +static bool tokudb_sync_on_commit(THD* thd, tokudb_trx_data* trx, DB_TXN* txn) { #if MYSQL_VERSION_ID >= 50600 // Check the client durability property which is set during 2PC if (thd_get_durability_property(thd) == HA_IGNORE_DURABILITY) @@ -751,9 +856,9 @@ static bool tokudb_sync_on_commit(THD *thd, tokudb_trx_data *trx, DB_TXN *txn) { if (txn->is_prepared(txn) && mysql_bin_log.is_open()) return false; #endif - if (tokudb_fsync_log_period > 0) + if (tokudb::sysvars::fsync_log_period > 0) return false; - return THDVAR(thd, commit_sync) != 0; + return tokudb::sysvars::commit_sync(thd) != 0; } static int tokudb_commit(handlerton * hton, THD * thd, bool all) { @@ -763,10 +868,14 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) { DB_TXN **txn = all ? &trx->all : &trx->stmt; DB_TXN *this_txn = *txn; if (this_txn) { - uint32_t syncflag = tokudb_sync_on_commit(thd, trx, this_txn) ? 0 : DB_TXN_NOSYNC; - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("commit trx %u txn %p syncflag %u", all, this_txn, syncflag); - } + uint32_t syncflag = + tokudb_sync_on_commit(thd, trx, this_txn) ? 0 : DB_TXN_NOSYNC; + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "commit trx %u txn %p syncflag %u", + all, + this_txn, + syncflag); // test hook to induce a crash on a debug build DBUG_EXECUTE_IF("tokudb_crash_commit_before", DBUG_SUICIDE();); tokudb_cleanup_handlers(trx, this_txn); @@ -778,9 +887,8 @@ static int tokudb_commit(handlerton * hton, THD * thd, bool all) { if (this_txn == trx->sp_level || trx->all == NULL) { trx->sp_level = NULL; } - } - else if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("nothing to commit %d", all); + } else { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "nothing to commit %d", all); } reset_stmt_progress(&trx->stmt_progress); TOKUDB_DBUG_RETURN(0); @@ -793,9 +901,11 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) { DB_TXN **txn = all ? &trx->all : &trx->stmt; DB_TXN *this_txn = *txn; if (this_txn) { - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("rollback %u txn %p", all, this_txn); - } + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "rollback %u txn %p", + all, + this_txn); tokudb_cleanup_handlers(trx, this_txn); abort_txn_with_progress(this_txn, thd); *txn = NULL; @@ -803,11 +913,8 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) { if (this_txn == trx->sp_level || trx->all == NULL) { trx->sp_level = NULL; } - } - else { - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("abort0"); - } + } else { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "abort0"); } reset_stmt_progress(&trx->stmt_progress); TOKUDB_DBUG_RETURN(0); @@ -816,7 +923,7 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) { #if TOKU_INCLUDE_XA static bool tokudb_sync_on_prepare(void) { // skip sync of log if fsync log period > 0 - if (tokudb_fsync_log_period > 0) + if (tokudb::sysvars::fsync_log_period > 0) return false; else return true; @@ -827,7 +934,7 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) { int r = 0; // if tokudb_support_xa is disable, just return - if (!THDVAR(thd, support_xa)) { + if (!tokudb::sysvars::support_xa(thd)) { TOKUDB_DBUG_RETURN(r); } @@ -836,9 +943,11 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) { DB_TXN* txn = all ? trx->all : trx->stmt; if (txn) { uint32_t syncflag = tokudb_sync_on_prepare() ? 0 : DB_TXN_NOSYNC; - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("doing txn prepare:%d:%p", all, txn); - } + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "doing txn prepare:%d:%p", + all, + txn); // a TOKU_XA_XID is identical to a MYSQL_XID TOKU_XA_XID thd_xid; thd_get_xid(thd, (MYSQL_XID*) &thd_xid); @@ -847,9 +956,8 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) { r = txn->xa_prepare(txn, &thd_xid, syncflag); // test hook to induce a crash on a debug build DBUG_EXECUTE_IF("tokudb_crash_prepare_after", DBUG_SUICIDE();); - } - else if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("nothing to prepare %d", all); + } else { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "nothing to prepare %d", all); } TOKUDB_DBUG_RETURN(r); } @@ -866,9 +974,8 @@ static int tokudb_xa_recover(handlerton* hton, XID* xid_list, uint len) { (TOKU_XA_XID*)xid_list, len, &num_returned, - DB_NEXT - ); - assert(r == 0); + DB_NEXT); + assert_always(r == 0); TOKUDB_DBUG_RETURN((int)num_returned); } @@ -914,43 +1021,55 @@ static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) { SP_INFO save_info = (SP_INFO)savepoint; tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton); if (thd->in_sub_stmt) { - assert(trx->stmt); - error = txn_begin(db_env, trx->sub_sp_level, &(save_info->txn), DB_INHERIT_ISOLATION, thd); + assert_always(trx->stmt); + error = txn_begin( + db_env, + trx->sub_sp_level, + &(save_info->txn), + DB_INHERIT_ISOLATION, + thd); if (error) { goto cleanup; } trx->sub_sp_level = save_info->txn; save_info->in_sub_stmt = true; - } - else { - error = txn_begin(db_env, trx->sp_level, &(save_info->txn), DB_INHERIT_ISOLATION, thd); + } else { + error = txn_begin( + db_env, + trx->sp_level, + &(save_info->txn), + DB_INHERIT_ISOLATION, + thd); if (error) { goto cleanup; } trx->sp_level = save_info->txn; save_info->in_sub_stmt = false; } - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("begin txn %p", save_info->txn); - } + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "begin txn %p", save_info->txn); save_info->trx = trx; error = 0; cleanup: TOKUDB_DBUG_RETURN(error); } -static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint) { +static int tokudb_rollback_to_savepoint( + handlerton* hton, + THD* thd, + void* savepoint) { + TOKUDB_DBUG_ENTER("%p", savepoint); int error; SP_INFO save_info = (SP_INFO)savepoint; DB_TXN* parent = NULL; DB_TXN* txn_to_rollback = save_info->txn; - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton); + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, hton); parent = txn_to_rollback->parent; - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("rollback txn %p", txn_to_rollback); - } + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "rollback txn %p", + txn_to_rollback); if (!(error = txn_to_rollback->abort(txn_to_rollback))) { if (save_info->in_sub_stmt) { trx->sub_sp_level = parent; @@ -963,7 +1082,11 @@ static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *save TOKUDB_DBUG_RETURN(error); } -static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint) { +static int tokudb_release_savepoint( + handlerton* hton, + THD* thd, + void* savepoint) { + TOKUDB_DBUG_ENTER("%p", savepoint); int error = 0; SP_INFO save_info = (SP_INFO)savepoint; @@ -972,9 +1095,7 @@ static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoin tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton); parent = txn_to_commit->parent; - if (tokudb_debug & TOKUDB_DEBUG_TXN) { - TOKUDB_TRACE("commit txn %p", txn_to_commit); - } + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "commit txn %p", txn_to_commit); DB_TXN *child = txn_to_commit->get_child(txn_to_commit); if (child == NULL && !(error = txn_to_commit->commit(txn_to_commit, 0))) { if (save_info->in_sub_stmt) { @@ -992,8 +1113,14 @@ static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoin static int tokudb_discover_table(handlerton *hton, THD* thd, TABLE_SHARE *ts) { uchar *frmblob = 0; size_t frmlen; - int res= tokudb_discover3(hton, thd, ts->db.str, ts->table_name.str, - ts->normalized_path.str, &frmblob, &frmlen); + int res= tokudb_discover3( + hton, + thd, + ts->db.str, + ts->table_name.str, + ts->normalized_path.str, + &frmblob, + &frmlen); if (!res) res= ts->init_from_binary_frm_image(thd, true, frmblob, frmlen); @@ -1002,7 +1129,11 @@ static int tokudb_discover_table(handlerton *hton, THD* thd, TABLE_SHARE *ts) { return res == ENOENT ? HA_ERR_NO_SUCH_TABLE : res; } -static int tokudb_discover_table_existence(handlerton *hton, const char *db, const char *name) { +static int tokudb_discover_table_existence( + handlerton* hton, + const char* db, + const char* name) { + uchar *frmblob = 0; size_t frmlen; int res= tokudb_discover(hton, current_thd, db, name, &frmblob, &frmlen); @@ -1011,19 +1142,46 @@ static int tokudb_discover_table_existence(handlerton *hton, const char *db, con } #endif -static int tokudb_discover(handlerton *hton, THD* thd, const char *db, const char *name, uchar **frmblob, size_t *frmlen) { +static int tokudb_discover( + handlerton* hton, + THD* thd, + const char* db, + const char* name, + uchar** frmblob, + size_t* frmlen) { + return tokudb_discover2(hton, thd, db, name, true, frmblob, frmlen); } -static int tokudb_discover2(handlerton *hton, THD* thd, const char *db, const char *name, bool translate_name, - uchar **frmblob, size_t *frmlen) { +static int tokudb_discover2( + handlerton* hton, + THD* thd, + const char* db, + const char* name, + bool translate_name, + uchar** frmblob, + size_t*frmlen) { + char path[FN_REFLEN + 1]; - build_table_filename(path, sizeof(path) - 1, db, name, "", translate_name ? 0 : FN_IS_TMP); + build_table_filename( + path, + sizeof(path) - 1, + db, + name, + "", + translate_name ? 0 : FN_IS_TMP); return tokudb_discover3(hton, thd, db, name, path, frmblob, frmlen); } -static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const char *name, char *path, - uchar **frmblob, size_t *frmlen) { +static int tokudb_discover3( + handlerton* hton, + THD* thd, + const char* db, + const char* name, + char* path, + uchar** frmblob, + size_t* frmlen) { + TOKUDB_DBUG_ENTER("%s %s %s", db, name, path); int error; DB* status_db = NULL; @@ -1034,8 +1192,10 @@ static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const ch bool do_commit = false; #if 100000 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099 - tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); - if (thd_sql_command(thd) == SQLCOM_CREATE_TABLE && trx && trx->sub_sp_level) { + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); + if (thd_sql_command(thd) == SQLCOM_CREATE_TABLE && + trx && + trx->sub_sp_level) { do_commit = false; txn = trx->sub_sp_level; } else { @@ -1061,8 +1221,7 @@ static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const ch 0, &key, smart_dbt_callback_verify_frm, - &value - ); + &value); if (error) { goto cleanup; } @@ -1078,19 +1237,23 @@ static int tokudb_discover3(handlerton *hton, THD* thd, const char *db, const ch if (do_commit && txn) { commit_txn(txn, 0); } - TOKUDB_DBUG_RETURN(error); + TOKUDB_DBUG_RETURN(error); } -#define STATPRINT(legend, val) if (legend != NULL && val != NULL) stat_print(thd, \ - tokudb_hton_name, \ - strlen(tokudb_hton_name), \ - legend, \ - strlen(legend), \ - val, \ - strlen(val)) +#define STATPRINT(legend, val) if (legend != NULL && val != NULL) \ + stat_print(thd, \ + tokudb_hton_name, \ + strlen(tokudb_hton_name), \ + legend, \ + strlen(legend), \ + val, \ + strlen(val)) -extern sys_var *intern_find_sys_var(const char *str, uint length, bool no_error); +extern sys_var* intern_find_sys_var( + const char* str, + uint length, + bool no_error); static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) { TOKUDB_DBUG_ENTER(""); @@ -1106,14 +1269,29 @@ static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) { #if MYSQL_VERSION_ID < 50500 { - sys_var * version = intern_find_sys_var("version", 0, false); - snprintf(buf, bufsiz, "%s", version->value_ptr(thd, (enum_var_type)0, (LEX_STRING*)NULL)); + sys_var* version = intern_find_sys_var("version", 0, false); + snprintf( + buf, + bufsiz, + "%s", + version->value_ptr(thd, + (enum_var_type)0, + (LEX_STRING*)NULL)); STATPRINT("Version", buf); } #endif error = db_env->get_engine_status_num_rows (db_env, &max_rows); TOKU_ENGINE_STATUS_ROW_S mystat[max_rows]; - error = db_env->get_engine_status (db_env, mystat, max_rows, &num_rows, &redzone_state, &panic, panic_string, panic_string_len, TOKU_ENGINE_STATUS); + error = db_env->get_engine_status( + db_env, + mystat, + max_rows, + &num_rows, + &redzone_state, + &panic, + panic_string, + panic_string_len, + TOKU_ENGINE_STATUS); if (strlen(panic_string)) { STATPRINT("Environment panic string", panic_string); @@ -1125,20 +1303,35 @@ static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) { } if(redzone_state == FS_BLOCKED) { - STATPRINT("*** URGENT WARNING ***", "FILE SYSTEM IS COMPLETELY FULL"); + STATPRINT( + "*** URGENT WARNING ***", "FILE SYSTEM IS COMPLETELY FULL"); snprintf(buf, bufsiz, "FILE SYSTEM IS COMPLETELY FULL"); - } - else if (redzone_state == FS_GREEN) { - snprintf(buf, bufsiz, "more than %d percent of total file system space", 2*tokudb_fs_reserve_percent); - } - else if (redzone_state == FS_YELLOW) { - snprintf(buf, bufsiz, "*** WARNING *** FILE SYSTEM IS GETTING FULL (less than %d percent free)", 2*tokudb_fs_reserve_percent); - } - else if (redzone_state == FS_RED){ - snprintf(buf, bufsiz, "*** WARNING *** FILE SYSTEM IS GETTING VERY FULL (less than %d percent free): INSERTS ARE PROHIBITED", tokudb_fs_reserve_percent); - } - else { - snprintf(buf, bufsiz, "information unavailable, unknown redzone state %d", redzone_state); + } else if (redzone_state == FS_GREEN) { + snprintf( + buf, + bufsiz, + "more than %d percent of total file system space", + 2 * tokudb::sysvars::fs_reserve_percent); + } else if (redzone_state == FS_YELLOW) { + snprintf( + buf, + bufsiz, + "*** WARNING *** FILE SYSTEM IS GETTING FULL (less than %d " + "percent free)", + 2 * tokudb::sysvars::fs_reserve_percent); + } else if (redzone_state == FS_RED){ + snprintf( + buf, + bufsiz, + "*** WARNING *** FILE SYSTEM IS GETTING VERY FULL (less than " + "%d percent free): INSERTS ARE PROHIBITED", + tokudb::sysvars::fs_reserve_percent); + } else { + snprintf( + buf, + bufsiz, + "information unavailable, unknown redzone state %d", + redzone_state); } STATPRINT ("disk free space", buf); @@ -1165,7 +1358,8 @@ static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) { break; } case PARCOUNT: { - uint64_t v = read_partitioned_counter(mystat[row].value.parcount); + uint64_t v = read_partitioned_counter( + mystat[row].value.parcount); snprintf(buf, bufsiz, "%" PRIu64, v); break; } @@ -1173,12 +1367,17 @@ static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) { snprintf(buf, bufsiz, "%.6f", mystat[row].value.dnum); break; default: - snprintf(buf, bufsiz, "UNKNOWN STATUS TYPE: %d", mystat[row].type); - break; + snprintf( + buf, + bufsiz, + "UNKNOWN STATUS TYPE: %d", + mystat[row].type); + break; } STATPRINT(mystat[row].legend, buf); } - uint64_t bytes_inserted = read_partitioned_counter(tokudb_primary_key_bytes_inserted); + uint64_t bytes_inserted = read_partitioned_counter( + tokudb_primary_key_bytes_inserted); snprintf(buf, bufsiz, "%" PRIu64, bytes_inserted); STATPRINT("handlerton: primary key bytes inserted", buf); } @@ -1186,16 +1385,16 @@ static bool tokudb_show_engine_status(THD * thd, stat_print_fn * stat_print) { TOKUDB_DBUG_RETURN(error); } -static void tokudb_checkpoint_lock(THD * thd) { +void tokudb_checkpoint_lock(THD * thd) { int error; const char *old_proc_info; - tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); if (!trx) { error = create_tokudb_trx_data_instance(&trx); // // can only fail due to memory allocation, so ok to assert // - assert(!error); + assert_always(!error); thd_set_ha_data(thd, tokudb_hton, trx); } @@ -1209,7 +1408,7 @@ static void tokudb_checkpoint_lock(THD * thd) { old_proc_info = tokudb_thd_get_proc_info(thd); thd_proc_info(thd, "Trying to grab checkpointing lock."); error = db_env->checkpointing_postpone(db_env); - assert(!error); + assert_always(!error); thd_proc_info(thd, old_proc_info); trx->checkpoint_lock_taken = true; @@ -1217,10 +1416,10 @@ static void tokudb_checkpoint_lock(THD * thd) { return; } -static void tokudb_checkpoint_unlock(THD * thd) { +void tokudb_checkpoint_unlock(THD * thd) { int error; const char *old_proc_info; - tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); + tokudb_trx_data* trx = (tokudb_trx_data*)thd_get_ha_data(thd, tokudb_hton); if (!trx) { error = 0; goto cleanup; @@ -1235,7 +1434,7 @@ static void tokudb_checkpoint_unlock(THD * thd) { old_proc_info = tokudb_thd_get_proc_info(thd); thd_proc_info(thd, "Trying to release checkpointing lock."); error = db_env->checkpointing_resume(db_env); - assert(!error); + assert_always(!error); thd_proc_info(thd, old_proc_info); trx->checkpoint_lock_taken = false; @@ -1244,7 +1443,12 @@ static void tokudb_checkpoint_unlock(THD * thd) { return; } -static bool tokudb_show_status(handlerton * hton, THD * thd, stat_print_fn * stat_print, enum ha_stat_type stat_type) { +static bool tokudb_show_status( + handlerton* hton, + THD* thd, + stat_print_fn* stat_print, + enum ha_stat_type stat_type) { + switch (stat_type) { case HA_ENGINE_STATUS: return tokudb_show_engine_status(thd, stat_print); @@ -1256,14 +1460,21 @@ static bool tokudb_show_status(handlerton * hton, THD * thd, stat_print_fn * sta } #if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL -static void tokudb_handle_fatal_signal(handlerton *hton __attribute__ ((__unused__)), THD *thd __attribute__ ((__unused__)), int sig) { +static void tokudb_handle_fatal_signal( + TOKUDB_UNUSED(handlerton* hton), + TOKUDB_UNUSD(THD* thd), + int sig) { + if (tokudb_gdb_on_fatal) { db_env_try_gdb_stack_trace(tokudb_gdb_path); } } #endif -static void tokudb_print_error(const DB_ENV * db_env, const char *db_errpfx, const char *buffer) { +static void tokudb_print_error( + const DB_ENV* db_env, + const char* db_errpfx, + const char* buffer) { sql_print_error("%s: %s", db_errpfx, buffer); } @@ -1285,7 +1496,7 @@ static void tokudb_cleanup_log_files(void) { char **np; for (np = names; *np; ++np) { #if 1 - if (tokudb_debug) + if (TOKUDB_UNLIKELY(tokudb::sysvars::debug)) TOKUDB_TRACE("cleanup:%s", *np); #else my_delete(*np, MYF(MY_WME)); @@ -1298,246 +1509,13 @@ static void tokudb_cleanup_log_files(void) { DBUG_VOID_RETURN; } -// options flags -// PLUGIN_VAR_THDLOCAL Variable is per-connection -// PLUGIN_VAR_READONLY Server variable is read only -// PLUGIN_VAR_NOSYSVAR Not a server variable -// PLUGIN_VAR_NOCMDOPT Not a command line option -// PLUGIN_VAR_NOCMDARG No argument for cmd line -// PLUGIN_VAR_RQCMDARG Argument required for cmd line -// PLUGIN_VAR_OPCMDARG Argument optional for cmd line -// PLUGIN_VAR_MEMALLOC String needs memory allocated - - -// system variables -static void tokudb_cleaner_period_update(THD* thd, - struct st_mysql_sys_var* sys_var, - void* var, const void * save) { - ulong * cleaner_period = (ulong *) var; - *cleaner_period = *(const ulonglong *) save; - int r = db_env->cleaner_set_period(db_env, *cleaner_period); - assert(r == 0); -} - -#define DEFAULT_CLEANER_PERIOD 1 - -static MYSQL_SYSVAR_ULONG(cleaner_period, tokudb_cleaner_period, - 0, "TokuDB cleaner_period", - NULL, tokudb_cleaner_period_update, DEFAULT_CLEANER_PERIOD, - 0, ~0UL, 0); - -static void tokudb_cleaner_iterations_update(THD* thd, - struct st_mysql_sys_var* sys_var, - void* var, const void* save) { - ulong * cleaner_iterations = (ulong *) var; - *cleaner_iterations = *(const ulonglong *) save; - int r = db_env->cleaner_set_iterations(db_env, *cleaner_iterations); - assert(r == 0); -} - -#define DEFAULT_CLEANER_ITERATIONS 5 - -static MYSQL_SYSVAR_ULONG(cleaner_iterations, tokudb_cleaner_iterations, - 0, "TokuDB cleaner_iterations", - NULL, tokudb_cleaner_iterations_update, DEFAULT_CLEANER_ITERATIONS, - 0, ~0UL, 0); - -static void tokudb_checkpointing_period_update(THD* thd, - struct st_mysql_sys_var* sys_var, - void* var, const void* save) { - uint * checkpointing_period = (uint *) var; - *checkpointing_period = *(const ulonglong *) save; - int r = db_env->checkpointing_set_period(db_env, *checkpointing_period); - assert(r == 0); -} - -static MYSQL_SYSVAR_UINT(checkpointing_period, tokudb_checkpointing_period, - 0, "TokuDB Checkpointing period", - NULL, tokudb_checkpointing_period_update, 60, - 0, ~0U, 0); - -static MYSQL_SYSVAR_BOOL(directio, tokudb_directio, - PLUGIN_VAR_READONLY, "TokuDB Enable Direct I/O ", - NULL, NULL, FALSE); - -static MYSQL_SYSVAR_BOOL(compress_buffers_before_eviction, - tokudb_compress_buffers_before_eviction, - PLUGIN_VAR_READONLY, - "TokuDB Enable buffer compression before partial eviction", - NULL, NULL, TRUE); - -static MYSQL_SYSVAR_BOOL(checkpoint_on_flush_logs, tokudb_checkpoint_on_flush_logs, - 0, "TokuDB Checkpoint on Flush Logs ", - NULL, NULL, FALSE); - -static MYSQL_SYSVAR_ULONGLONG(cache_size, tokudb_cache_size, - PLUGIN_VAR_READONLY, "TokuDB cache table size", - NULL, NULL, 0, - 0, ~0ULL, 0); - -static MYSQL_SYSVAR_ULONGLONG(max_lock_memory, tokudb_max_lock_memory, - PLUGIN_VAR_READONLY, "TokuDB max memory for locks", - NULL, NULL, 0, - 0, ~0ULL, 0); - -static MYSQL_SYSVAR_UINT(client_pool_threads, tokudb_client_pool_threads, - PLUGIN_VAR_READONLY, "TokuDB client ops thread pool size", NULL, NULL, 0, - 0, 1024, 0); - -static MYSQL_SYSVAR_UINT(cachetable_pool_threads, tokudb_cachetable_pool_threads, - PLUGIN_VAR_READONLY, "TokuDB cachetable ops thread pool size", NULL, NULL, 0, - 0, 1024, 0); - -static MYSQL_SYSVAR_UINT(checkpoint_pool_threads, tokudb_checkpoint_pool_threads, - PLUGIN_VAR_READONLY, "TokuDB checkpoint ops thread pool size", NULL, NULL, 0, - 0, 1024, 0); - -static void tokudb_enable_partial_eviction_update(THD* thd, - struct st_mysql_sys_var* sys_var, - void* var, const void* save) { - my_bool * enable_partial_eviction = (my_bool *) var; - *enable_partial_eviction = *(const my_bool *) save; - int r = db_env->evictor_set_enable_partial_eviction(db_env, *enable_partial_eviction); - assert(r == 0); -} - -static MYSQL_SYSVAR_BOOL(enable_partial_eviction, tokudb_enable_partial_eviction, - 0, "TokuDB enable partial node eviction", - NULL, tokudb_enable_partial_eviction_update, TRUE); - -static MYSQL_SYSVAR_ULONG(debug, tokudb_debug, - 0, "TokuDB Debug", - NULL, NULL, 0, - 0, ~0UL, 0); - -static MYSQL_SYSVAR_STR(log_dir, tokudb_log_dir, - PLUGIN_VAR_READONLY, "TokuDB Log Directory", - NULL, NULL, NULL); - -static MYSQL_SYSVAR_STR(data_dir, tokudb_data_dir, - PLUGIN_VAR_READONLY, "TokuDB Data Directory", - NULL, NULL, NULL); - -static MYSQL_SYSVAR_STR(version, tokudb_version, - PLUGIN_VAR_READONLY, "TokuDB Version", - NULL, NULL, NULL); - -static MYSQL_SYSVAR_UINT(write_status_frequency, tokudb_write_status_frequency, - 0, "TokuDB frequency that show processlist updates status of writes", - NULL, NULL, 1000, - 0, ~0U, 0); - -static MYSQL_SYSVAR_UINT(read_status_frequency, tokudb_read_status_frequency, - 0, "TokuDB frequency that show processlist updates status of reads", - NULL, NULL, 10000, - 0, ~0U, 0); - -static MYSQL_SYSVAR_INT(fs_reserve_percent, tokudb_fs_reserve_percent, - PLUGIN_VAR_READONLY, "TokuDB file system space reserve (percent free required)", - NULL, NULL, 5, - 0, 100, 0); - -static MYSQL_SYSVAR_STR(tmp_dir, tokudb_tmp_dir, - PLUGIN_VAR_READONLY, "Tokudb Tmp Dir", - NULL, NULL, NULL); - -#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL -static MYSQL_SYSVAR_STR(gdb_path, tokudb_gdb_path, - PLUGIN_VAR_READONLY|PLUGIN_VAR_RQCMDARG, "TokuDB path to gdb for extra debug info on fatal signal", - NULL, NULL, "/usr/bin/gdb"); - -static MYSQL_SYSVAR_BOOL(gdb_on_fatal, tokudb_gdb_on_fatal, - 0, "TokuDB enable gdb debug info on fatal signal", - NULL, NULL, true); -#endif - -static void tokudb_fsync_log_period_update(THD* thd, - struct st_mysql_sys_var* sys_var, - void* var, const void* save) { - uint32 *period = (uint32 *) var; - *period = *(const ulonglong *) save; - db_env->change_fsync_log_period(db_env, *period); -} - -static MYSQL_SYSVAR_UINT(fsync_log_period, tokudb_fsync_log_period, - 0, "TokuDB fsync log period", - NULL, tokudb_fsync_log_period_update, 0, - 0, ~0U, 0); - -static struct st_mysql_sys_var *tokudb_system_variables[] = { - MYSQL_SYSVAR(cache_size), - MYSQL_SYSVAR(client_pool_threads), - MYSQL_SYSVAR(cachetable_pool_threads), - MYSQL_SYSVAR(checkpoint_pool_threads), - MYSQL_SYSVAR(max_lock_memory), - MYSQL_SYSVAR(enable_partial_eviction), - MYSQL_SYSVAR(data_dir), - MYSQL_SYSVAR(log_dir), - MYSQL_SYSVAR(debug), - MYSQL_SYSVAR(commit_sync), - MYSQL_SYSVAR(lock_timeout), - MYSQL_SYSVAR(cleaner_period), - MYSQL_SYSVAR(cleaner_iterations), - MYSQL_SYSVAR(pk_insert_mode), - MYSQL_SYSVAR(load_save_space), - MYSQL_SYSVAR(disable_slow_alter), - MYSQL_SYSVAR(disable_hot_alter), - MYSQL_SYSVAR(alter_print_error), - MYSQL_SYSVAR(create_index_online), - MYSQL_SYSVAR(disable_prefetching), - MYSQL_SYSVAR(version), - MYSQL_SYSVAR(checkpointing_period), - MYSQL_SYSVAR(prelock_empty), - MYSQL_SYSVAR(checkpoint_lock), - MYSQL_SYSVAR(write_status_frequency), - MYSQL_SYSVAR(read_status_frequency), - MYSQL_SYSVAR(fs_reserve_percent), - MYSQL_SYSVAR(tmp_dir), - MYSQL_SYSVAR(block_size), - MYSQL_SYSVAR(read_block_size), - MYSQL_SYSVAR(read_buf_size), - MYSQL_SYSVAR(fanout), - MYSQL_SYSVAR(row_format), - MYSQL_SYSVAR(directio), - MYSQL_SYSVAR(compress_buffers_before_eviction), - MYSQL_SYSVAR(checkpoint_on_flush_logs), -#if TOKU_INCLUDE_UPSERT - MYSQL_SYSVAR(disable_slow_update), - MYSQL_SYSVAR(disable_slow_upsert), -#endif - MYSQL_SYSVAR(analyze_time), - MYSQL_SYSVAR(analyze_delete_fraction), - MYSQL_SYSVAR(fsync_log_period), -#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL - MYSQL_SYSVAR(gdb_path), - MYSQL_SYSVAR(gdb_on_fatal), -#endif - MYSQL_SYSVAR(last_lock_timeout), - MYSQL_SYSVAR(lock_timeout_debug), - MYSQL_SYSVAR(loader_memory_size), - MYSQL_SYSVAR(hide_default_row_format), - MYSQL_SYSVAR(killed_time), - MYSQL_SYSVAR(empty_scan), -#if TOKUDB_CHECK_JEMALLOC - MYSQL_SYSVAR(check_jemalloc), -#endif - MYSQL_SYSVAR(bulk_fetch), -#if TOKU_INCLUDE_XA - MYSQL_SYSVAR(support_xa), -#endif - MYSQL_SYSVAR(rpl_unique_checks), - MYSQL_SYSVAR(rpl_unique_checks_delay), - MYSQL_SYSVAR(rpl_lookup_rows), - MYSQL_SYSVAR(rpl_lookup_rows_delay), - MYSQL_SYSVAR(rpl_check_readonly), - MYSQL_SYSVAR(optimize_index_name), - MYSQL_SYSVAR(optimize_index_fraction), - MYSQL_SYSVAR(optimize_throttle), - NULL -}; - // Split ./database/table-dictionary into database, table and dictionary strings -static void tokudb_split_dname(const char *dname, String &database_name, String &table_name, String &dictionary_name) { +void tokudb_split_dname( + const char* dname, + String& database_name, + String& table_name, + String& dictionary_name) { + const char *splitter = strchr(dname, '/'); if (splitter) { const char *database_ptr = splitter+1; @@ -1550,482 +1528,18 @@ static void tokudb_split_dname(const char *dname, String &database_name, String table_name.append(table_ptr, dictionary_ptr - table_ptr); dictionary_ptr += 1; dictionary_name.append(dictionary_ptr); + } else { + table_name.append(table_ptr); } - } - } -} - -struct st_mysql_storage_engine tokudb_storage_engine = { MYSQL_HANDLERTON_INTERFACE_VERSION }; - -static struct st_mysql_information_schema tokudb_file_map_information_schema = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -static ST_FIELD_INFO tokudb_file_map_field_info[] = { - {"dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"internal_file_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} -}; - -static int tokudb_file_map(TABLE *table, THD *thd) { - int error; - DB_TXN* txn = NULL; - DBC* tmp_cursor = NULL; - DBT curr_key; - DBT curr_val; - memset(&curr_key, 0, sizeof curr_key); - memset(&curr_val, 0, sizeof curr_val); - error = txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED, thd); - if (error) { - goto cleanup; - } - error = db_env->get_cursor_for_directory(db_env, txn, &tmp_cursor); - if (error) { - goto cleanup; - } - while (error == 0) { - error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT); - if (!error) { - // We store the NULL terminator in the directory so it's included in the size. - // See #5789 - // Recalculate and check just to be safe. - const char *dname = (const char *) curr_key.data; - size_t dname_len = strlen(dname); - assert(dname_len == curr_key.size - 1); - table->field[0]->store(dname, dname_len, system_charset_info); - - const char *iname = (const char *) curr_val.data; - size_t iname_len = strlen(iname); - assert(iname_len == curr_val.size - 1); - table->field[1]->store(iname, iname_len, system_charset_info); - - // split the dname - String database_name, table_name, dictionary_name; - tokudb_split_dname(dname, database_name, table_name, dictionary_name); - table->field[2]->store(database_name.c_ptr(), database_name.length(), system_charset_info); - table->field[3]->store(table_name.c_ptr(), table_name.length(), system_charset_info); - table->field[4]->store(dictionary_name.c_ptr(), dictionary_name.length(), system_charset_info); - - error = schema_table_store_record(thd, table); - } - if (!error && thd_killed(thd)) - error = ER_QUERY_INTERRUPTED; - } - if (error == DB_NOTFOUND) { - error = 0; - } -cleanup: - if (tmp_cursor) { - int r = tmp_cursor->c_close(tmp_cursor); - assert(r == 0); - } - if (txn) { - commit_txn(txn, 0); - } - return error; -} - -#if MYSQL_VERSION_ID >= 50600 -static int tokudb_file_map_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { -#else -static int tokudb_file_map_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { -#endif - TOKUDB_DBUG_ENTER(""); - int error; - TABLE *table = tables->table; - - rw_rdlock(&tokudb_hton_initialized_lock); - - if (!tokudb_hton_initialized) { - error = ER_PLUGIN_IS_NOT_LOADED; - my_error(error, MYF(0), tokudb_hton_name); - } else { - error = tokudb_file_map(table, thd); - if (error) - my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); - } - - rw_unlock(&tokudb_hton_initialized_lock); - TOKUDB_DBUG_RETURN(error); -} - -static int tokudb_file_map_init(void *p) { - ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; - schema->fields_info = tokudb_file_map_field_info; - schema->fill_table = tokudb_file_map_fill_table; - return 0; -} - -static int tokudb_file_map_done(void *p) { - return 0; -} - -static struct st_mysql_information_schema tokudb_fractal_tree_info_information_schema = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -static ST_FIELD_INFO tokudb_fractal_tree_info_field_info[] = { - {"dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"internal_file_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"bt_num_blocks_allocated", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"bt_num_blocks_in_use", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"bt_size_allocated", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"bt_size_in_use", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} -}; - -static int tokudb_report_fractal_tree_info_for_db(const DBT *dname, const DBT *iname, TABLE *table, THD *thd) { - int error; - uint64_t bt_num_blocks_allocated; - uint64_t bt_num_blocks_in_use; - uint64_t bt_size_allocated; - uint64_t bt_size_in_use; - - DB *db = NULL; - error = db_create(&db, db_env, 0); - if (error) { - goto exit; - } - error = db->open(db, NULL, (char *)dname->data, NULL, DB_BTREE, 0, 0666); - if (error) { - goto exit; - } - error = db->get_fractal_tree_info64(db, - &bt_num_blocks_allocated, &bt_num_blocks_in_use, - &bt_size_allocated, &bt_size_in_use); - if (error) { - goto exit; - } - - // We store the NULL terminator in the directory so it's included in the size. - // See #5789 - // Recalculate and check just to be safe. - { - size_t dname_len = strlen((const char *)dname->data); - assert(dname_len == dname->size - 1); - table->field[0]->store((char *)dname->data, dname_len, system_charset_info); - size_t iname_len = strlen((const char *)iname->data); - assert(iname_len == iname->size - 1); - table->field[1]->store((char *)iname->data, iname_len, system_charset_info); - } - table->field[2]->store(bt_num_blocks_allocated, false); - table->field[3]->store(bt_num_blocks_in_use, false); - table->field[4]->store(bt_size_allocated, false); - table->field[5]->store(bt_size_in_use, false); - - // split the dname - { - String database_name, table_name, dictionary_name; - tokudb_split_dname((const char *)dname->data, database_name, table_name, dictionary_name); - table->field[6]->store(database_name.c_ptr(), database_name.length(), system_charset_info); - table->field[7]->store(table_name.c_ptr(), table_name.length(), system_charset_info); - table->field[8]->store(dictionary_name.c_ptr(), dictionary_name.length(), system_charset_info); - } - error = schema_table_store_record(thd, table); - -exit: - if (db) { - int close_error = db->close(db, 0); - if (error == 0) - error = close_error; - } - return error; -} - -static int tokudb_fractal_tree_info(TABLE *table, THD *thd) { - int error; - DB_TXN* txn = NULL; - DBC* tmp_cursor = NULL; - DBT curr_key; - DBT curr_val; - memset(&curr_key, 0, sizeof curr_key); - memset(&curr_val, 0, sizeof curr_val); - error = txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED, thd); - if (error) { - goto cleanup; - } - error = db_env->get_cursor_for_directory(db_env, txn, &tmp_cursor); - if (error) { - goto cleanup; - } - while (error == 0) { - error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT); - if (!error) { - error = tokudb_report_fractal_tree_info_for_db(&curr_key, &curr_val, table, thd); - if (error) - error = 0; // ignore read uncommitted errors - } - if (!error && thd_killed(thd)) - error = ER_QUERY_INTERRUPTED; - } - if (error == DB_NOTFOUND) { - error = 0; - } -cleanup: - if (tmp_cursor) { - int r = tmp_cursor->c_close(tmp_cursor); - assert(r == 0); - } - if (txn) { - commit_txn(txn, 0); - } - return error; -} - -#if MYSQL_VERSION_ID >= 50600 -static int tokudb_fractal_tree_info_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { -#else -static int tokudb_fractal_tree_info_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { -#endif - TOKUDB_DBUG_ENTER(""); - int error; - TABLE *table = tables->table; - - // 3938: Get a read lock on the status flag, since we must - // read it before safely proceeding - rw_rdlock(&tokudb_hton_initialized_lock); - - if (!tokudb_hton_initialized) { - error = ER_PLUGIN_IS_NOT_LOADED; - my_error(error, MYF(0), tokudb_hton_name); - } else { - error = tokudb_fractal_tree_info(table, thd); - if (error) - my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); - } - - //3938: unlock the status flag lock - rw_unlock(&tokudb_hton_initialized_lock); - TOKUDB_DBUG_RETURN(error); -} - -static int tokudb_fractal_tree_info_init(void *p) { - ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; - schema->fields_info = tokudb_fractal_tree_info_field_info; - schema->fill_table = tokudb_fractal_tree_info_fill_table; - return 0; -} - -static int tokudb_fractal_tree_info_done(void *p) { - return 0; -} - -static struct st_mysql_information_schema tokudb_fractal_tree_block_map_information_schema = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -static ST_FIELD_INFO tokudb_fractal_tree_block_map_field_info[] = { - {"dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"internal_file_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"checkpoint_count", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"blocknum", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"offset", 0, MYSQL_TYPE_LONGLONG, 0, MY_I_S_MAYBE_NULL, NULL, SKIP_OPEN_TABLE }, - {"size", 0, MYSQL_TYPE_LONGLONG, 0, MY_I_S_MAYBE_NULL, NULL, SKIP_OPEN_TABLE }, - {"table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} -}; - -struct tokudb_report_fractal_tree_block_map_iterator_extra { - int64_t num_rows; - int64_t i; - uint64_t *checkpoint_counts; - int64_t *blocknums; - int64_t *diskoffs; - int64_t *sizes; -}; - -// This iterator is called while holding the blocktable lock. We should be as quick as possible. -// We don't want to do one call to get the number of rows, release the blocktable lock, and then do another call to get all the rows because the number of rows may change if we don't hold the lock. -// As a compromise, we'll do some mallocs inside the lock on the first call, but everything else should be fast. -static int tokudb_report_fractal_tree_block_map_iterator(uint64_t checkpoint_count, - int64_t num_rows, - int64_t blocknum, - int64_t diskoff, - int64_t size, - void *iter_extra) { - struct tokudb_report_fractal_tree_block_map_iterator_extra *e = static_cast(iter_extra); - - assert(num_rows > 0); - if (e->num_rows == 0) { - e->checkpoint_counts = (uint64_t *) tokudb_my_malloc(num_rows * (sizeof *e->checkpoint_counts), MYF(MY_WME|MY_ZEROFILL|MY_FAE)); - e->blocknums = (int64_t *) tokudb_my_malloc(num_rows * (sizeof *e->blocknums), MYF(MY_WME|MY_ZEROFILL|MY_FAE)); - e->diskoffs = (int64_t *) tokudb_my_malloc(num_rows * (sizeof *e->diskoffs), MYF(MY_WME|MY_ZEROFILL|MY_FAE)); - e->sizes = (int64_t *) tokudb_my_malloc(num_rows * (sizeof *e->sizes), MYF(MY_WME|MY_ZEROFILL|MY_FAE)); - e->num_rows = num_rows; - } - - e->checkpoint_counts[e->i] = checkpoint_count; - e->blocknums[e->i] = blocknum; - e->diskoffs[e->i] = diskoff; - e->sizes[e->i] = size; - ++(e->i); - - return 0; -} - -static int tokudb_report_fractal_tree_block_map_for_db(const DBT *dname, const DBT *iname, TABLE *table, THD *thd) { - int error; - DB *db; - struct tokudb_report_fractal_tree_block_map_iterator_extra e = {}; // avoid struct initializers so that we can compile with older gcc versions - - error = db_create(&db, db_env, 0); - if (error) { - goto exit; - } - error = db->open(db, NULL, (char *)dname->data, NULL, DB_BTREE, 0, 0666); - if (error) { - goto exit; - } - error = db->iterate_fractal_tree_block_map(db, tokudb_report_fractal_tree_block_map_iterator, &e); - { - int close_error = db->close(db, 0); - if (!error) { - error = close_error; - } - } - if (error) { - goto exit; - } - - // If not, we should have gotten an error and skipped this section of code - assert(e.i == e.num_rows); - for (int64_t i = 0; error == 0 && i < e.num_rows; ++i) { - // We store the NULL terminator in the directory so it's included in the size. - // See #5789 - // Recalculate and check just to be safe. - size_t dname_len = strlen((const char *)dname->data); - assert(dname_len == dname->size - 1); - table->field[0]->store((char *)dname->data, dname_len, system_charset_info); - - size_t iname_len = strlen((const char *)iname->data); - assert(iname_len == iname->size - 1); - table->field[1]->store((char *)iname->data, iname_len, system_charset_info); - - table->field[2]->store(e.checkpoint_counts[i], false); - table->field[3]->store(e.blocknums[i], false); - static const int64_t freelist_null = -1; - static const int64_t diskoff_unused = -2; - if (e.diskoffs[i] == diskoff_unused || e.diskoffs[i] == freelist_null) { - table->field[4]->set_null(); } else { - table->field[4]->set_notnull(); - table->field[4]->store(e.diskoffs[i], false); + database_name.append(database_ptr); } - static const int64_t size_is_free = -1; - if (e.sizes[i] == size_is_free) { - table->field[5]->set_null(); - } else { - table->field[5]->set_notnull(); - table->field[5]->store(e.sizes[i], false); - } - - // split the dname - String database_name, table_name, dictionary_name; - tokudb_split_dname((const char *)dname->data, database_name, table_name,dictionary_name); - table->field[6]->store(database_name.c_ptr(), database_name.length(), system_charset_info); - table->field[7]->store(table_name.c_ptr(), table_name.length(), system_charset_info); - table->field[8]->store(dictionary_name.c_ptr(), dictionary_name.length(), system_charset_info); - - error = schema_table_store_record(thd, table); - } - -exit: - if (e.checkpoint_counts != NULL) { - tokudb_my_free(e.checkpoint_counts); - e.checkpoint_counts = NULL; - } - if (e.blocknums != NULL) { - tokudb_my_free(e.blocknums); - e.blocknums = NULL; - } - if (e.diskoffs != NULL) { - tokudb_my_free(e.diskoffs); - e.diskoffs = NULL; } - if (e.sizes != NULL) { - tokudb_my_free(e.sizes); - e.sizes = NULL; - } - return error; -} - -static int tokudb_fractal_tree_block_map(TABLE *table, THD *thd) { - int error; - DB_TXN* txn = NULL; - DBC* tmp_cursor = NULL; - DBT curr_key; - DBT curr_val; - memset(&curr_key, 0, sizeof curr_key); - memset(&curr_val, 0, sizeof curr_val); - error = txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED, thd); - if (error) { - goto cleanup; - } - error = db_env->get_cursor_for_directory(db_env, txn, &tmp_cursor); - if (error) { - goto cleanup; - } - while (error == 0) { - error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT); - if (!error) { - error = tokudb_report_fractal_tree_block_map_for_db(&curr_key, &curr_val, table, thd); - } - if (!error && thd_killed(thd)) - error = ER_QUERY_INTERRUPTED; - } - if (error == DB_NOTFOUND) { - error = 0; - } -cleanup: - if (tmp_cursor) { - int r = tmp_cursor->c_close(tmp_cursor); - assert(r == 0); - } - if (txn) { - commit_txn(txn, 0); - } - return error; -} - -#if MYSQL_VERSION_ID >= 50600 -static int tokudb_fractal_tree_block_map_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { -#else -static int tokudb_fractal_tree_block_map_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { -#endif - TOKUDB_DBUG_ENTER(""); - int error; - TABLE *table = tables->table; - - // 3938: Get a read lock on the status flag, since we must - // read it before safely proceeding - rw_rdlock(&tokudb_hton_initialized_lock); - - if (!tokudb_hton_initialized) { - error = ER_PLUGIN_IS_NOT_LOADED; - my_error(error, MYF(0), tokudb_hton_name); - } else { - error = tokudb_fractal_tree_block_map(table, thd); - if (error) - my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); - } - - //3938: unlock the status flag lock - rw_unlock(&tokudb_hton_initialized_lock); - TOKUDB_DBUG_RETURN(error); -} - -static int tokudb_fractal_tree_block_map_init(void *p) { - ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; - schema->fields_info = tokudb_fractal_tree_block_map_field_info; - schema->fill_table = tokudb_fractal_tree_block_map_fill_table; - return 0; } -static int tokudb_fractal_tree_block_map_done(void *p) { - return 0; -} +struct st_mysql_storage_engine tokudb_storage_engine = { + MYSQL_HANDLERTON_INTERFACE_VERSION +}; #if TOKU_INCLUDE_LOCK_TIMEOUT_QUERY_STRING struct tokudb_search_txn_extra { @@ -2034,10 +1548,16 @@ struct tokudb_search_txn_extra { uint64_t match_client_id; }; -static int tokudb_search_txn_callback(DB_TXN *txn, iterate_row_locks_callback iterate_locks, void *locks_extra, void *extra) { +static int tokudb_search_txn_callback( + DB_TXN* txn, + iterate_row_locks_callback iterate_locks, + void* locks_extra, + void* extra) { + uint64_t txn_id = txn->id64(txn); uint64_t client_id = txn->get_client_id(txn); - struct tokudb_search_txn_extra *e = reinterpret_cast(extra); + struct tokudb_search_txn_extra* e = + reinterpret_cast(extra); if (e->match_txn_id == txn_id) { e->match_found = true; e->match_client_id = client_id; @@ -2046,9 +1566,17 @@ static int tokudb_search_txn_callback(DB_TXN *txn, iterate_row_locks_callback it return 0; } -static bool tokudb_txn_id_to_client_id(THD *thd, uint64_t blocking_txnid, uint64_t *blocking_client_id) { - struct tokudb_search_txn_extra e = { false, blocking_txnid, 0}; - (void) db_env->iterate_live_transactions(db_env, tokudb_search_txn_callback, &e); +static bool tokudb_txn_id_to_client_id( + THD* thd, + uint64_t blocking_txnid, + uint64_t* blocking_client_id) { + + struct tokudb_search_txn_extra e = { + false, + blocking_txnid, + 0 + }; + db_env->iterate_live_transactions(db_env, tokudb_search_txn_callback, &e); if (e.match_found) { *blocking_client_id = e.match_client_id; } @@ -2056,14 +1584,20 @@ static bool tokudb_txn_id_to_client_id(THD *thd, uint64_t blocking_txnid, uint64 } #endif -static void tokudb_pretty_key(const DB *db, const DBT *key, const char *default_key, String *out) { +static void tokudb_pretty_key( + const DB* db, + const DBT* key, + const char* default_key, + String* out) { + if (key->data == NULL) { out->append(default_key); } else { bool do_hexdump = true; if (do_hexdump) { // hexdump the key - const unsigned char *data = reinterpret_cast(key->data); + const unsigned char* data = + reinterpret_cast(key->data); for (size_t i = 0; i < key->size; i++) { char str[3]; snprintf(str, sizeof str, "%2.2x", data[i]); @@ -2073,15 +1607,15 @@ static void tokudb_pretty_key(const DB *db, const DBT *key, const char *default_ } } -static void tokudb_pretty_left_key(const DB *db, const DBT *key, String *out) { +void tokudb_pretty_left_key(const DB* db, const DBT* key, String* out) { tokudb_pretty_key(db, key, "-infinity", out); } -static void tokudb_pretty_right_key(const DB *db, const DBT *key, String *out) { +void tokudb_pretty_right_key(const DB* db, const DBT* key, String* out) { tokudb_pretty_key(db, key, "+infinity", out); } -static const char *tokudb_get_index_name(DB *db) { +const char* tokudb_get_index_name(DB* db) { if (db != NULL) { return db->get_dname(db); } else { @@ -2090,17 +1624,24 @@ static const char *tokudb_get_index_name(DB *db) { } static int tokudb_equal_key(const DBT *left_key, const DBT *right_key) { - if (left_key->data == NULL || right_key->data == NULL || left_key->size != right_key->size) + if (left_key->data == NULL || right_key->data == NULL || + left_key->size != right_key->size) return 0; else return memcmp(left_key->data, right_key->data, left_key->size) == 0; } -static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, const DBT *left_key, const DBT *right_key, uint64_t blocking_txnid) { - THD *thd = current_thd; +static void tokudb_lock_timeout_callback( + DB* db, + uint64_t requesting_txnid, + const DBT* left_key, + const DBT* right_key, + uint64_t blocking_txnid) { + + THD* thd = current_thd; if (!thd) return; - ulong lock_timeout_debug = THDVAR(thd, lock_timeout_debug); + ulong lock_timeout_debug = tokudb::sysvars::lock_timeout_debug(thd); if (lock_timeout_debug != 0) { // generate a JSON document with the lock timeout info String log_str; @@ -2109,7 +1650,9 @@ static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, cons log_str.append("\"mysql_thread_id\":"); log_str.append_ulonglong(mysql_thread_id); log_str.append(", \"dbname\":"); - log_str.append("\""); log_str.append(tokudb_get_index_name(db)); log_str.append("\""); + log_str.append("\""); + log_str.append(tokudb_get_index_name(db)); + log_str.append("\""); log_str.append(", \"requesting_txnid\":"); log_str.append_ulonglong(requesting_txnid); log_str.append(", \"blocking_txnid\":"); @@ -2118,44 +1661,71 @@ static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, cons String key_str; tokudb_pretty_key(db, left_key, "?", &key_str); log_str.append(", \"key\":"); - log_str.append("\""); log_str.append(key_str); log_str.append("\""); + log_str.append("\""); + log_str.append(key_str); + log_str.append("\""); } else { String left_str; tokudb_pretty_left_key(db, left_key, &left_str); log_str.append(", \"key_left\":"); - log_str.append("\""); log_str.append(left_str); log_str.append("\""); + log_str.append("\""); + log_str.append(left_str); + log_str.append("\""); String right_str; tokudb_pretty_right_key(db, right_key, &right_str); log_str.append(", \"key_right\":"); - log_str.append("\""); log_str.append(right_str); log_str.append("\""); + log_str.append("\""); + log_str.append(right_str); + log_str.append("\""); } log_str.append("}"); // set last_lock_timeout if (lock_timeout_debug & 1) { - char *old_lock_timeout = THDVAR(thd, last_lock_timeout); - char *new_lock_timeout = tokudb_my_strdup(log_str.c_ptr(), MY_FAE); - THDVAR(thd, last_lock_timeout) = new_lock_timeout; - tokudb_my_free(old_lock_timeout); + char* old_lock_timeout = tokudb::sysvars::last_lock_timeout(thd); + char* new_lock_timeout = + tokudb::memory::strdup(log_str.c_ptr(), MY_FAE); + tokudb::sysvars::set_last_lock_timeout(thd, new_lock_timeout); #if TOKU_THDVAR_MEMALLOC_BUG - tokudb_pthread_mutex_lock(&tokudb_map_mutex); + tokudb_map_mutex.lock(); struct tokudb_map_pair old_key = { thd, old_lock_timeout }; tree_delete(&tokudb_map, &old_key, sizeof old_key, NULL); struct tokudb_map_pair new_key = { thd, new_lock_timeout }; tree_insert(&tokudb_map, &new_key, sizeof new_key, NULL); - tokudb_pthread_mutex_unlock(&tokudb_map_mutex); + tokudb_map_mutex.unlock(); #endif + tokudb::memory::free(old_lock_timeout); } // dump to stderr if (lock_timeout_debug & 2) { - sql_print_error("%s: lock timeout %s", tokudb_hton_name, log_str.c_ptr()); + sql_print_error( + "%s: lock timeout %s", + tokudb_hton_name, + log_str.c_ptr()); LEX_STRING *qs = thd_query_string(thd); - sql_print_error("%s: requesting_thread_id:%" PRIu64 " q:%.*s", tokudb_hton_name, mysql_thread_id, (int) qs->length, qs->str); + sql_print_error( + "%s: requesting_thread_id:%" PRIu64 " q:%.*s", + tokudb_hton_name, + mysql_thread_id, + (int)qs->length, + qs->str); #if TOKU_INCLUDE_LOCK_TIMEOUT_QUERY_STRING uint64_t blocking_thread_id = 0; - if (tokudb_txn_id_to_client_id(thd, blocking_txnid, &blocking_thread_id)) { + if (tokudb_txn_id_to_client_id( + thd, + blocking_txnid, + &blocking_thread_id)) { + String blocking_qs; - if (get_thread_query_string(blocking_thread_id, blocking_qs) == 0) { - sql_print_error("%s: blocking_thread_id:%" PRIu64 " q:%.*s", tokudb_hton_name, blocking_thread_id, blocking_qs.length(), blocking_qs.c_ptr()); + if (get_thread_query_string( + blocking_thread_id, + blocking_qs) == 0) { + + sql_print_error( + "%s: blocking_thread_id:%" PRIu64 " q:%.*s", + tokudb_hton_name, + blocking_thread_id, + blocking_qs.length(), + blocking_qs.c_ptr()); } } #endif @@ -2163,254 +1733,9 @@ static void tokudb_lock_timeout_callback(DB *db, uint64_t requesting_txnid, cons } } -static struct st_mysql_information_schema tokudb_trx_information_schema = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -static ST_FIELD_INFO tokudb_trx_field_info[] = { - {"trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"trx_mysql_thread_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"trx_time", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} -}; - -struct tokudb_trx_extra { - THD *thd; - TABLE *table; -}; - -static int tokudb_trx_callback(DB_TXN *txn, iterate_row_locks_callback iterate_locks, void *locks_extra, void *extra) { - uint64_t txn_id = txn->id64(txn); - uint64_t client_id = txn->get_client_id(txn); - uint64_t start_time = txn->get_start_time(txn); - struct tokudb_trx_extra *e = reinterpret_cast(extra); - THD *thd = e->thd; - TABLE *table = e->table; - table->field[0]->store(txn_id, false); - table->field[1]->store(client_id, false); - uint64_t tnow = (uint64_t) time(NULL); - table->field[2]->store(tnow >= start_time ? tnow - start_time : 0, false); - int error = schema_table_store_record(thd, table); - if (!error && thd_killed(thd)) - error = ER_QUERY_INTERRUPTED; - return error; -} - -#if MYSQL_VERSION_ID >= 50600 -static int tokudb_trx_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { -#else -static int tokudb_trx_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { -#endif - TOKUDB_DBUG_ENTER(""); - int error; - - rw_rdlock(&tokudb_hton_initialized_lock); - - if (!tokudb_hton_initialized) { - error = ER_PLUGIN_IS_NOT_LOADED; - my_error(error, MYF(0), tokudb_hton_name); - } else { - struct tokudb_trx_extra e = { thd, tables->table }; - error = db_env->iterate_live_transactions(db_env, tokudb_trx_callback, &e); - if (error) - my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); - } - - rw_unlock(&tokudb_hton_initialized_lock); - TOKUDB_DBUG_RETURN(error); -} - -static int tokudb_trx_init(void *p) { - ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; - schema->fields_info = tokudb_trx_field_info; - schema->fill_table = tokudb_trx_fill_table; - return 0; -} - -static int tokudb_trx_done(void *p) { - return 0; -} - -static struct st_mysql_information_schema tokudb_lock_waits_information_schema = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -static ST_FIELD_INFO tokudb_lock_waits_field_info[] = { - {"requesting_trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"blocking_trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_dname", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_key_left", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_key_right", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_start_time", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"lock_waits_table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} -}; - -struct tokudb_lock_waits_extra { - THD *thd; - TABLE *table; -}; - -static int tokudb_lock_waits_callback(DB *db, uint64_t requesting_txnid, const DBT *left_key, const DBT *right_key, - uint64_t blocking_txnid, uint64_t start_time, void *extra) { - struct tokudb_lock_waits_extra *e = reinterpret_cast(extra); - THD *thd = e->thd; - TABLE *table = e->table; - table->field[0]->store(requesting_txnid, false); - table->field[1]->store(blocking_txnid, false); - const char *dname = tokudb_get_index_name(db); - size_t dname_length = strlen(dname); - table->field[2]->store(dname, dname_length, system_charset_info); - String left_str; - tokudb_pretty_left_key(db, left_key, &left_str); - table->field[3]->store(left_str.ptr(), left_str.length(), system_charset_info); - String right_str; - tokudb_pretty_right_key(db, right_key, &right_str); - table->field[4]->store(right_str.ptr(), right_str.length(), system_charset_info); - table->field[5]->store(start_time, false); - - String database_name, table_name, dictionary_name; - tokudb_split_dname(dname, database_name, table_name, dictionary_name); - table->field[6]->store(database_name.c_ptr(), database_name.length(), system_charset_info); - table->field[7]->store(table_name.c_ptr(), table_name.length(), system_charset_info); - table->field[8]->store(dictionary_name.c_ptr(), dictionary_name.length(), system_charset_info); - - int error = schema_table_store_record(thd, table); - - if (!error && thd_killed(thd)) - error = ER_QUERY_INTERRUPTED; - - return error; -} - -#if MYSQL_VERSION_ID >= 50600 -static int tokudb_lock_waits_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { -#else -static int tokudb_lock_waits_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { -#endif - TOKUDB_DBUG_ENTER(""); - int error; - - rw_rdlock(&tokudb_hton_initialized_lock); - - if (!tokudb_hton_initialized) { - error = ER_PLUGIN_IS_NOT_LOADED; - my_error(error, MYF(0), tokudb_hton_name); - } else { - struct tokudb_lock_waits_extra e = { thd, tables->table }; - error = db_env->iterate_pending_lock_requests(db_env, tokudb_lock_waits_callback, &e); - if (error) - my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); - } - - rw_unlock(&tokudb_hton_initialized_lock); - TOKUDB_DBUG_RETURN(error); -} - -static int tokudb_lock_waits_init(void *p) { - ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; - schema->fields_info = tokudb_lock_waits_field_info; - schema->fill_table = tokudb_lock_waits_fill_table; - return 0; -} - -static int tokudb_lock_waits_done(void *p) { - return 0; -} - -static struct st_mysql_information_schema tokudb_locks_information_schema = { MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION }; - -static ST_FIELD_INFO tokudb_locks_field_info[] = { - {"locks_trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_mysql_thread_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_dname", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_key_left", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_key_right", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {"locks_table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, - {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} -}; - -struct tokudb_locks_extra { - THD *thd; - TABLE *table; -}; - -static int tokudb_locks_callback(DB_TXN *txn, iterate_row_locks_callback iterate_locks, void *locks_extra, void *extra) { - uint64_t txn_id = txn->id64(txn); - uint64_t client_id = txn->get_client_id(txn); - struct tokudb_locks_extra *e = reinterpret_cast(extra); - THD *thd = e->thd; - TABLE *table = e->table; - int error = 0; - DB *db; - DBT left_key, right_key; - while (error == 0 && iterate_locks(&db, &left_key, &right_key, locks_extra) == 0) { - table->field[0]->store(txn_id, false); - table->field[1]->store(client_id, false); - - const char *dname = tokudb_get_index_name(db); - size_t dname_length = strlen(dname); - table->field[2]->store(dname, dname_length, system_charset_info); - - String left_str; - tokudb_pretty_left_key(db, &left_key, &left_str); - table->field[3]->store(left_str.ptr(), left_str.length(), system_charset_info); - - String right_str; - tokudb_pretty_right_key(db, &right_key, &right_str); - table->field[4]->store(right_str.ptr(), right_str.length(), system_charset_info); - - String database_name, table_name, dictionary_name; - tokudb_split_dname(dname, database_name, table_name, dictionary_name); - table->field[5]->store(database_name.c_ptr(), database_name.length(), system_charset_info); - table->field[6]->store(table_name.c_ptr(), table_name.length(), system_charset_info); - table->field[7]->store(dictionary_name.c_ptr(), dictionary_name.length(), system_charset_info); - - error = schema_table_store_record(thd, table); - - if (!error && thd_killed(thd)) - error = ER_QUERY_INTERRUPTED; - } - return error; -} - -#if MYSQL_VERSION_ID >= 50600 -static int tokudb_locks_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { -#else -static int tokudb_locks_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { -#endif - TOKUDB_DBUG_ENTER(""); - int error; - - rw_rdlock(&tokudb_hton_initialized_lock); - - if (!tokudb_hton_initialized) { - error = ER_PLUGIN_IS_NOT_LOADED; - my_error(error, MYF(0), tokudb_hton_name); - } else { - struct tokudb_locks_extra e = { thd, tables->table }; - error = db_env->iterate_live_transactions(db_env, tokudb_locks_callback, &e); - if (error) - my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); - } - - rw_unlock(&tokudb_hton_initialized_lock); - TOKUDB_DBUG_RETURN(error); -} - -static int tokudb_locks_init(void *p) { - ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; - schema->fields_info = tokudb_locks_field_info; - schema->fill_table = tokudb_locks_fill_table; - return 0; -} - -static int tokudb_locks_done(void *p) { - return 0; -} - // Retrieves variables for information_schema.global_status. -// Names (columnname) are automatically converted to upper case, and prefixed with "TOKUDB_" +// Names (columnname) are automatically converted to upper case, +// and prefixed with "TOKUDB_" static int show_tokudb_vars(THD *thd, SHOW_VAR *var, char *buff) { TOKUDB_DBUG_ENTER(""); @@ -2421,13 +1746,23 @@ static int show_tokudb_vars(THD *thd, SHOW_VAR *var, char *buff) { fs_redzone_state redzone_state; uint64_t num_rows; - error = db_env->get_engine_status (db_env, toku_global_status_rows, toku_global_status_max_rows, &num_rows, &redzone_state, &panic, panic_string, panic_string_len, TOKU_GLOBAL_STATUS); + error = db_env->get_engine_status( + db_env, + toku_global_status_rows, + toku_global_status_max_rows, + &num_rows, + &redzone_state, + &panic, + panic_string, + panic_string_len, + TOKU_GLOBAL_STATUS); //TODO: Maybe do something with the panic output? if (error == 0) { - assert(num_rows <= toku_global_status_max_rows); + assert_always(num_rows <= toku_global_status_max_rows); //TODO: Maybe enable some of the items here: (copied from engine status - //TODO: (optionally) add redzone state, panic, panic string, etc. Right now it's being ignored. + //TODO: (optionally) add redzone state, panic, panic string, etc. + //Right now it's being ignored. for (uint64_t row = 0; row < num_rows; row++) { SHOW_VAR &status_var = toku_global_status_variables[row]; @@ -2449,7 +1784,11 @@ static int show_tokudb_vars(THD *thd, SHOW_VAR *var, char *buff) { time_t t = status_row.value.num; char tbuf[26]; // Reuse the memory in status_row. (It belongs to us). - snprintf(status_row.value.datebuf, sizeof(status_row.value.datebuf), "%.24s", ctime_r(&t, tbuf)); + snprintf( + status_row.value.datebuf, + sizeof(status_row.value.datebuf), + "%.24s", + ctime_r(&t, tbuf)); status_var.value = (char*)&status_row.value.datebuf[0]; break; } @@ -2475,7 +1814,11 @@ static int show_tokudb_vars(THD *thd, SHOW_VAR *var, char *buff) { status_var.type = SHOW_CHAR; // Reuse the memory in status_row.datebuf. (It belongs to us). // UNKNOWN TYPE: %d fits in 26 bytes (sizeof datebuf) for any integer. - snprintf(status_row.value.datebuf, sizeof(status_row.value.datebuf), "UNKNOWN TYPE: %d", status_row.type); + snprintf( + status_row.value.datebuf, + sizeof(status_row.value.datebuf), + "UNKNOWN TYPE: %d", + status_row.type); status_var.value = (char*)&status_row.value.datebuf[0]; break; } @@ -2507,157 +1850,38 @@ static void tokudb_backtrace(void) { } #endif -#if defined(TOKUDB_VERSION_MAJOR) && defined(TOKUDB_VERSION_MINOR) -#define TOKUDB_PLUGIN_VERSION ((TOKUDB_VERSION_MAJOR << 8) + TOKUDB_VERSION_MINOR) -#else -#define TOKUDB_PLUGIN_VERSION 0 -#endif - #ifdef MARIA_PLUGIN_INTERFACE_VERSION maria_declare_plugin(tokudb) #else mysql_declare_plugin(tokudb) #endif -{ - MYSQL_STORAGE_ENGINE_PLUGIN, - &tokudb_storage_engine, - tokudb_hton_name, - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_init_func, /* plugin init */ - tokudb_done_func, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - toku_global_status_variables_export, /* status variables */ - tokudb_system_variables, /* system variables */ -#ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ -#else - NULL, /* config options */ - 0, /* flags */ -#endif -}, -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &tokudb_trx_information_schema, - "TokuDB_trx", - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_trx_init, /* plugin init */ - tokudb_trx_done, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - NULL, /* status variables */ - NULL, /* system variables */ -#ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ -#else - NULL, /* config options */ - 0, /* flags */ -#endif -}, -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &tokudb_lock_waits_information_schema, - "TokuDB_lock_waits", - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_lock_waits_init, /* plugin init */ - tokudb_lock_waits_done, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - NULL, /* status variables */ - NULL, /* system variables */ -#ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ -#else - NULL, /* config options */ - 0, /* flags */ -#endif -}, -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &tokudb_locks_information_schema, - "TokuDB_locks", - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_locks_init, /* plugin init */ - tokudb_locks_done, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - NULL, /* status variables */ - NULL, /* system variables */ -#ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ -#else - NULL, /* config options */ - 0, /* flags */ -#endif -}, -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &tokudb_file_map_information_schema, - "TokuDB_file_map", - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_file_map_init, /* plugin init */ - tokudb_file_map_done, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - NULL, /* status variables */ - NULL, /* system variables */ -#ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ -#else - NULL, /* config options */ - 0, /* flags */ -#endif -}, -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &tokudb_fractal_tree_info_information_schema, - "TokuDB_fractal_tree_info", - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_fractal_tree_info_init, /* plugin init */ - tokudb_fractal_tree_info_done, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - NULL, /* status variables */ - NULL, /* system variables */ -#ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ -#else - NULL, /* config options */ - 0, /* flags */ -#endif -}, -{ - MYSQL_INFORMATION_SCHEMA_PLUGIN, - &tokudb_fractal_tree_block_map_information_schema, - "TokuDB_fractal_tree_block_map", - "Percona", - "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", - PLUGIN_LICENSE_GPL, - tokudb_fractal_tree_block_map_init, /* plugin init */ - tokudb_fractal_tree_block_map_done, /* plugin deinit */ - TOKUDB_PLUGIN_VERSION, - NULL, /* status variables */ - NULL, /* system variables */ + { + MYSQL_STORAGE_ENGINE_PLUGIN, + &tokudb_storage_engine, + tokudb_hton_name, + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + tokudb_init_func, /* plugin init */ + tokudb_done_func, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + toku_global_status_variables_export, /* status variables */ + tokudb::sysvars::system_variables, /* system variables */ #ifdef MARIA_PLUGIN_INTERFACE_VERSION - tokudb_version, - MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ #else - NULL, /* config options */ - 0, /* flags */ + NULL, /* config options */ + 0, /* flags */ #endif -} + }, + tokudb::information_schema::trx, + tokudb::information_schema::lock_waits, + tokudb::information_schema::locks, + tokudb::information_schema::file_map, + tokudb::information_schema::fractal_tree_info, + tokudb::information_schema::fractal_tree_block_map, + tokudb::information_schema::background_job_status #ifdef MARIA_PLUGIN_INTERFACE_VERSION maria_declare_plugin_end; #else diff --git a/storage/tokudb/hatoku_hton.h b/storage/tokudb/hatoku_hton.h index 6b2cbbe238334..37c61be849d0c 100644 --- a/storage/tokudb/hatoku_hton.h +++ b/storage/tokudb/hatoku_hton.h @@ -26,492 +26,187 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ifndef _HATOKU_HTON_H #define _HATOKU_HTON_H -#include "db.h" +#include "hatoku_defines.h" +#include "tokudb_debug.h" +#include "tokudb_information_schema.h" +#include "tokudb_memory.h" +#include "tokudb_thread.h" +#include "tokudb_time.h" +#include "tokudb_txn.h" +#include "tokudb_sysvars.h" -extern handlerton *tokudb_hton; +extern handlerton* tokudb_hton; -extern DB_ENV *db_env; +extern DB_ENV* db_env; -enum srv_row_format_enum { - SRV_ROW_FORMAT_UNCOMPRESSED = 0, - SRV_ROW_FORMAT_ZLIB = 1, - SRV_ROW_FORMAT_SNAPPY = 2, - SRV_ROW_FORMAT_QUICKLZ = 3, - SRV_ROW_FORMAT_LZMA = 4, - SRV_ROW_FORMAT_FAST = 5, - SRV_ROW_FORMAT_SMALL = 6, - SRV_ROW_FORMAT_DEFAULT = 7 -}; -typedef enum srv_row_format_enum srv_row_format_t; +inline tokudb::sysvars::row_format_t toku_compression_method_to_row_format( + toku_compression_method method) { -static inline srv_row_format_t toku_compression_method_to_row_format(toku_compression_method method) { switch (method) { case TOKU_NO_COMPRESSION: - return SRV_ROW_FORMAT_UNCOMPRESSED; + return tokudb::sysvars::SRV_ROW_FORMAT_UNCOMPRESSED; case TOKU_ZLIB_WITHOUT_CHECKSUM_METHOD: case TOKU_ZLIB_METHOD: - return SRV_ROW_FORMAT_ZLIB; + return tokudb::sysvars::SRV_ROW_FORMAT_ZLIB; case TOKU_SNAPPY_METHOD: - return SRV_ROW_FORMAT_SNAPPY; + return tokudb::sysvars::SRV_ROW_FORMAT_SNAPPY; case TOKU_QUICKLZ_METHOD: - return SRV_ROW_FORMAT_QUICKLZ; + return tokudb::sysvars::SRV_ROW_FORMAT_QUICKLZ; case TOKU_LZMA_METHOD: - return SRV_ROW_FORMAT_LZMA; + return tokudb::sysvars::SRV_ROW_FORMAT_LZMA; case TOKU_DEFAULT_COMPRESSION_METHOD: - return SRV_ROW_FORMAT_DEFAULT; + return tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT; case TOKU_FAST_COMPRESSION_METHOD: - return SRV_ROW_FORMAT_FAST; + return tokudb::sysvars::SRV_ROW_FORMAT_FAST; case TOKU_SMALL_COMPRESSION_METHOD: - return SRV_ROW_FORMAT_SMALL; + return tokudb::sysvars::SRV_ROW_FORMAT_SMALL; default: - assert(0); + assert_unreachable(); } } -static inline toku_compression_method row_format_to_toku_compression_method(srv_row_format_t row_format) { +inline toku_compression_method row_format_to_toku_compression_method( + tokudb::sysvars::row_format_t row_format) { + switch (row_format) { - case SRV_ROW_FORMAT_UNCOMPRESSED: + case tokudb::sysvars::SRV_ROW_FORMAT_UNCOMPRESSED: return TOKU_NO_COMPRESSION; - case SRV_ROW_FORMAT_QUICKLZ: - case SRV_ROW_FORMAT_FAST: + case tokudb::sysvars::SRV_ROW_FORMAT_QUICKLZ: + case tokudb::sysvars::SRV_ROW_FORMAT_FAST: return TOKU_QUICKLZ_METHOD; - case SRV_ROW_FORMAT_SNAPPY: + case tokudb::sysvars::SRV_ROW_FORMAT_SNAPPY: return TOKU_SNAPPY_METHOD; - case SRV_ROW_FORMAT_ZLIB: - case SRV_ROW_FORMAT_DEFAULT: + case tokudb::sysvars::SRV_ROW_FORMAT_ZLIB: + case tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT: return TOKU_ZLIB_WITHOUT_CHECKSUM_METHOD; - case SRV_ROW_FORMAT_LZMA: - case SRV_ROW_FORMAT_SMALL: + case tokudb::sysvars::SRV_ROW_FORMAT_LZMA: + case tokudb::sysvars::SRV_ROW_FORMAT_SMALL: return TOKU_LZMA_METHOD; default: - assert(0); + assert_unreachable(); } } -static inline enum row_type row_format_to_row_type(srv_row_format_t row_format) { +inline enum row_type row_format_to_row_type( + tokudb::sysvars::row_format_t row_format) { #if TOKU_INCLUDE_ROW_TYPE_COMPRESSION switch (row_format) { - case SRV_ROW_FORMAT_UNCOMPRESSED: + case tokudb::sysvars::SRV_ROW_FORMAT_UNCOMPRESSED: return ROW_TYPE_TOKU_UNCOMPRESSED; - case SRV_ROW_FORMAT_ZLIB: + case tokudb::sysvars::SRV_ROW_FORMAT_ZLIB: return ROW_TYPE_TOKU_ZLIB; - case SRV_ROW_FORMAT_SNAPPY: + case tokudb::sysvars::SRV_ROW_FORMAT_SNAPPY: return ROW_TYPE_TOKU_SNAPPY; - case SRV_ROW_FORMAT_QUICKLZ: + case tokudb::sysvars::SRV_ROW_FORMAT_QUICKLZ: return ROW_TYPE_TOKU_QUICKLZ; - case SRV_ROW_FORMAT_LZMA: + case tokudb::sysvars::SRV_ROW_FORMAT_LZMA: return ROW_TYPE_TOKU_LZMA; - case SRV_ROW_FORMAT_SMALL: + case tokudb::sysvars::SRV_ROW_FORMAT_SMALL: return ROW_TYPE_TOKU_SMALL; - case SRV_ROW_FORMAT_FAST: + case tokudb::sysvars::SRV_ROW_FORMAT_FAST: return ROW_TYPE_TOKU_FAST; - case SRV_ROW_FORMAT_DEFAULT: + case tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT: return ROW_TYPE_DEFAULT; } #endif return ROW_TYPE_DEFAULT; } -static inline srv_row_format_t row_type_to_row_format(enum row_type type) { +inline tokudb::sysvars::row_format_t row_type_to_row_format( + enum row_type type) { #if TOKU_INCLUDE_ROW_TYPE_COMPRESSION switch (type) { case ROW_TYPE_TOKU_UNCOMPRESSED: - return SRV_ROW_FORMAT_UNCOMPRESSED; + return tokudb::sysvars::SRV_ROW_FORMAT_UNCOMPRESSED; case ROW_TYPE_TOKU_ZLIB: - return SRV_ROW_FORMAT_ZLIB; + return tokudb::sysvars::SRV_ROW_FORMAT_ZLIB; case ROW_TYPE_TOKU_SNAPPY: - return SRV_ROW_FORMAT_SNAPPY; + return tokudb::sysvars::SRV_ROW_FORMAT_SNAPPY; case ROW_TYPE_TOKU_QUICKLZ: - return SRV_ROW_FORMAT_QUICKLZ; + return tokudb::sysvars::SRV_ROW_FORMAT_QUICKLZ; case ROW_TYPE_TOKU_LZMA: - return SRV_ROW_FORMAT_LZMA; + return tokudb::sysvars::SRV_ROW_FORMAT_LZMA; case ROW_TYPE_TOKU_SMALL: - return SRV_ROW_FORMAT_SMALL; + return tokudb::sysvars::SRV_ROW_FORMAT_SMALL; case ROW_TYPE_TOKU_FAST: - return SRV_ROW_FORMAT_FAST; + return tokudb::sysvars::SRV_ROW_FORMAT_FAST; case ROW_TYPE_DEFAULT: - return SRV_ROW_FORMAT_DEFAULT; + return tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT; default: - return SRV_ROW_FORMAT_DEFAULT; + return tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT; } #endif - return SRV_ROW_FORMAT_DEFAULT; -} - -static inline enum row_type toku_compression_method_to_row_type(toku_compression_method method) { - return row_format_to_row_type(toku_compression_method_to_row_format(method)); -} - -static inline toku_compression_method row_type_to_toku_compression_method(enum row_type type) { - return row_format_to_toku_compression_method(row_type_to_row_format(type)); -} - -// thread variables - -static MYSQL_THDVAR_BOOL(commit_sync, - PLUGIN_VAR_THDLOCAL, - "sync on txn commit", - /* check */ NULL, - /* update */ NULL, - /* default*/ true -); - -static MYSQL_THDVAR_UINT(pk_insert_mode, - 0, - "set the primary key insert mode", - NULL, - NULL, - 1, // default - 0, // min? - 2, // max - 1 // blocksize -); - -static uint get_pk_insert_mode(THD* thd) { - return THDVAR(thd, pk_insert_mode); -} - -static MYSQL_THDVAR_BOOL(load_save_space, - 0, - "compress intermediate bulk loader files to save space", - NULL, - NULL, - true -); - -static bool get_load_save_space(THD* thd) { - return (THDVAR(thd, load_save_space) != 0); -} - -static MYSQL_THDVAR_BOOL(disable_slow_alter, - 0, - "if on, alter tables that require copy are disabled", - NULL, - NULL, - false -); - -static bool get_disable_slow_alter(THD* thd) { - return (THDVAR(thd, disable_slow_alter) != 0); -} - -static MYSQL_THDVAR_BOOL(disable_hot_alter, - 0, - "if on, hot alter table is disabled", - NULL, - NULL, - false -); - -static bool get_disable_hot_alter(THD* thd) { - return THDVAR(thd, disable_hot_alter) != 0; -} - -static MYSQL_THDVAR_BOOL(create_index_online, - 0, - "if on, create index done online", - NULL, - NULL, - true -); - -static bool get_create_index_online(THD* thd) { - return (THDVAR(thd, create_index_online) != 0); -} - -static MYSQL_THDVAR_BOOL(alter_print_error, - 0, - "Print errors for alter table operations", - NULL, - NULL, - false -); - -static MYSQL_THDVAR_BOOL(disable_prefetching, - 0, - "if on, prefetching disabled", - NULL, - NULL, - false -); - -static bool get_disable_prefetching(THD* thd) { - return (THDVAR(thd, disable_prefetching) != 0); -} - -static MYSQL_THDVAR_BOOL(prelock_empty, - 0, - "Tokudb Prelock Empty Table", - NULL, - NULL, - true -); - -static bool get_prelock_empty(THD* thd) { - return (THDVAR(thd, prelock_empty) != 0); -} - -static MYSQL_THDVAR_UINT(block_size, - 0, - "fractal tree block size", - NULL, - NULL, - 4<<20, // default - 4096, // min - ~0U, // max - 1 // blocksize??? -); - -static uint get_tokudb_block_size(THD* thd) { - return THDVAR(thd, block_size); -} - -static MYSQL_THDVAR_UINT(read_block_size, - 0, - "fractal tree read block size", - NULL, - NULL, - 64*1024, // default - 4096, // min - ~0U, // max - 1 // blocksize??? -); - -static uint get_tokudb_read_block_size(THD* thd) { - return THDVAR(thd, read_block_size); + return tokudb::sysvars::SRV_ROW_FORMAT_DEFAULT; } -static MYSQL_THDVAR_UINT(read_buf_size, - 0, - "fractal tree read block size", //TODO: Is this a typo? - NULL, - NULL, - 128*1024, // default - 0, // min - 1*1024*1024, // max - 1 // blocksize??? -); - -static uint get_tokudb_read_buf_size(THD* thd) { - return THDVAR(thd, read_buf_size); -} - -#if TOKU_INCLUDE_UPSERT -static MYSQL_THDVAR_BOOL(disable_slow_update, - PLUGIN_VAR_THDLOCAL, - "disable slow update", - NULL, // check - NULL, // update - false // default -); - -static MYSQL_THDVAR_BOOL(disable_slow_upsert, - PLUGIN_VAR_THDLOCAL, - "disable slow upsert", - NULL, // check - NULL, // update - false // default -); -#endif +inline enum row_type toku_compression_method_to_row_type( + toku_compression_method method) { -static MYSQL_THDVAR_UINT(fanout, - 0, - "fractal tree fanout", - NULL, - NULL, - 16, // default - 2, // min - 16*1024, // max - 1 // blocksize??? -); - -static uint get_tokudb_fanout(THD* thd) { - return THDVAR(thd, fanout); + return row_format_to_row_type( + toku_compression_method_to_row_format(method)); } -static MYSQL_THDVAR_UINT(analyze_time, 0, "analyze time (seconds)", NULL /*check*/, NULL /*update*/, 5 /*default*/, 0 /*min*/, ~0U /*max*/, 1 /*blocksize*/); - -static MYSQL_THDVAR_DOUBLE(analyze_delete_fraction, 0, "fraction of rows allowed to be deleted", NULL /*check*/, NULL /*update*/, 1.0 /*def*/, 0 /*min*/, 1.0 /*max*/, 1); +inline toku_compression_method row_type_to_toku_compression_method( + enum row_type type) { -static void tokudb_checkpoint_lock(THD * thd); -static void tokudb_checkpoint_unlock(THD * thd); - -static void tokudb_checkpoint_lock_update( - THD* thd, - struct st_mysql_sys_var* var, - void* var_ptr, - const void* save) -{ - my_bool* val = (my_bool *) var_ptr; - *val= *(my_bool *) save ? true : false; - if (*val) { - tokudb_checkpoint_lock(thd); - } - else { - tokudb_checkpoint_unlock(thd); - } -} - -static MYSQL_THDVAR_BOOL(checkpoint_lock, - 0, - "Tokudb Checkpoint Lock", - NULL, - tokudb_checkpoint_lock_update, - false -); - -static const char *tokudb_row_format_names[] = { - "tokudb_uncompressed", - "tokudb_zlib", - "tokudb_snappy", - "tokudb_quicklz", - "tokudb_lzma", - "tokudb_fast", - "tokudb_small", - "tokudb_default", - NullS -}; - -static TYPELIB tokudb_row_format_typelib = { - array_elements(tokudb_row_format_names) - 1, - "tokudb_row_format_typelib", - tokudb_row_format_names, - NULL -}; - -static MYSQL_THDVAR_ENUM(row_format, PLUGIN_VAR_OPCMDARG, - "Specifies the compression method for a table during this session. " - "Possible values are TOKUDB_UNCOMPRESSED, TOKUDB_ZLIB, TOKUDB_SNAPPY, " - "TOKUDB_QUICKLZ, TOKUDB_LZMA, TOKUDB_FAST, TOKUDB_SMALL and TOKUDB_DEFAULT", - NULL, NULL, SRV_ROW_FORMAT_ZLIB, &tokudb_row_format_typelib); - -static inline srv_row_format_t get_row_format(THD *thd) { - return (srv_row_format_t) THDVAR(thd, row_format); + return row_format_to_toku_compression_method(row_type_to_row_format(type)); } -static MYSQL_THDVAR_UINT(lock_timeout_debug, 0, "TokuDB lock timeout debug", NULL /*check*/, NULL /*update*/, 1 /*default*/, 0 /*min*/, ~0U /*max*/, 1); - -static MYSQL_THDVAR_STR(last_lock_timeout, PLUGIN_VAR_MEMALLOC, "last TokuDB lock timeout", NULL /*check*/, NULL /*update*/, NULL /*default*/); - -static MYSQL_THDVAR_BOOL(hide_default_row_format, 0, "hide the default row format", NULL /*check*/, NULL /*update*/, true); - -static const uint64_t DEFAULT_TOKUDB_LOCK_TIMEOUT = 4000; /*milliseconds*/ +void tokudb_checkpoint_lock(THD * thd); +void tokudb_checkpoint_unlock(THD * thd); -static MYSQL_THDVAR_ULONGLONG(lock_timeout, 0, "TokuDB lock timeout", NULL, NULL, DEFAULT_TOKUDB_LOCK_TIMEOUT, 0 /*min*/, ~0ULL /*max*/, 1 /*blocksize*/); - -static uint64_t tokudb_get_lock_wait_time_callback(uint64_t default_wait_time) { +inline uint64_t tokudb_get_lock_wait_time_callback(uint64_t default_wait_time) { THD *thd = current_thd; - uint64_t wait_time = THDVAR(thd, lock_timeout); - return wait_time; + return tokudb::sysvars::lock_timeout(thd); } -static MYSQL_THDVAR_ULONGLONG(loader_memory_size, - 0, - "TokuDB loader memory size", - NULL, - NULL, - 100*1000*1000, /*default*/ - 0, /*min*/ - ~0ULL, /*max*/ - 1 /*blocksize*/ -); - -static uint64_t tokudb_get_loader_memory_size_callback(void) { +inline uint64_t tokudb_get_loader_memory_size_callback(void) { THD *thd = current_thd; - uint64_t memory_size = THDVAR(thd, loader_memory_size); - return memory_size; + return tokudb::sysvars::loader_memory_size(thd); } -static const uint64_t DEFAULT_TOKUDB_KILLED_TIME = 4000; - -static MYSQL_THDVAR_ULONGLONG(killed_time, 0, "TokuDB killed time", NULL, NULL, DEFAULT_TOKUDB_KILLED_TIME, 0 /*min*/, ~0ULL /*max*/, 1 /*blocksize*/); - -static uint64_t tokudb_get_killed_time_callback(uint64_t default_killed_time) { +inline uint64_t tokudb_get_killed_time_callback(uint64_t default_killed_time) { THD *thd = current_thd; - uint64_t killed_time = THDVAR(thd, killed_time); - return killed_time; + return tokudb::sysvars::killed_time(thd); } -static int tokudb_killed_callback(void) { +inline int tokudb_killed_callback(void) { THD *thd = current_thd; return thd_killed(thd); } -static bool tokudb_killed_thd_callback(void *extra, uint64_t deleted_rows) { +inline bool tokudb_killed_thd_callback(void *extra, uint64_t deleted_rows) { THD *thd = static_cast(extra); return thd_killed(thd) != 0; } -enum { - TOKUDB_EMPTY_SCAN_DISABLED = 0, - TOKUDB_EMPTY_SCAN_LR = 1, - TOKUDB_EMPTY_SCAN_RL = 2, -}; - -static const char *tokudb_empty_scan_names[] = { - "disabled", - "lr", - "rl", - NullS -}; - -static TYPELIB tokudb_empty_scan_typelib = { - array_elements(tokudb_empty_scan_names) - 1, - "tokudb_empty_scan_typelib", - tokudb_empty_scan_names, - NULL -}; - -static MYSQL_THDVAR_ENUM(empty_scan, PLUGIN_VAR_OPCMDARG, - "TokuDB algorithm to check if the table is empty when opened. ", - NULL, NULL, TOKUDB_EMPTY_SCAN_RL, &tokudb_empty_scan_typelib -); - -#if TOKUDB_CHECK_JEMALLOC -static uint tokudb_check_jemalloc; -static MYSQL_SYSVAR_UINT(check_jemalloc, tokudb_check_jemalloc, 0, "Check if jemalloc is linked", - NULL, NULL, 1, 0, 1, 0); -#endif - -static MYSQL_THDVAR_BOOL(bulk_fetch, PLUGIN_VAR_THDLOCAL, "enable bulk fetch", - NULL /*check*/, NULL /*update*/, true /*default*/); - -#if TOKU_INCLUDE_XA -static MYSQL_THDVAR_BOOL(support_xa, - PLUGIN_VAR_OPCMDARG, - "Enable TokuDB support for the XA two-phase commit", - NULL, // check - NULL, // update - true // default -); -#endif - -static MYSQL_THDVAR_BOOL(rpl_unique_checks, PLUGIN_VAR_THDLOCAL, "enable unique checks on replication slave", - NULL /*check*/, NULL /*update*/, true /*default*/); - -static MYSQL_THDVAR_ULONGLONG(rpl_unique_checks_delay, PLUGIN_VAR_THDLOCAL, "time in milliseconds to add to unique checks test on replication slave", - NULL, NULL, 0 /*default*/, 0 /*min*/, ~0ULL /*max*/, 1 /*blocksize*/); - -static MYSQL_THDVAR_BOOL(rpl_lookup_rows, PLUGIN_VAR_THDLOCAL, "lookup a row on rpl slave", - NULL /*check*/, NULL /*update*/, true /*default*/); - -static MYSQL_THDVAR_ULONGLONG(rpl_lookup_rows_delay, PLUGIN_VAR_THDLOCAL, "time in milliseconds to add to lookups on replication slave", - NULL, NULL, 0 /*default*/, 0 /*min*/, ~0ULL /*max*/, 1 /*blocksize*/); - -static MYSQL_THDVAR_BOOL(rpl_check_readonly, PLUGIN_VAR_THDLOCAL, "check if the slave is read only", - NULL /*check*/, NULL /*update*/, true /*default*/); - -static MYSQL_THDVAR_STR(optimize_index_name, PLUGIN_VAR_THDLOCAL + PLUGIN_VAR_MEMALLOC, "optimize index name (default all indexes)", NULL /*check*/, NULL /*update*/, NULL /*default*/); - -static MYSQL_THDVAR_DOUBLE(optimize_index_fraction, 0, "optimize index fraction (default 1.0 all)", NULL /*check*/, NULL /*update*/, 1.0 /*def*/, 0 /*min*/, 1.0 /*max*/, 1); - -static MYSQL_THDVAR_ULONGLONG(optimize_throttle, 0, "optimize throttle (default no throttle)", NULL /*check*/, NULL /*update*/, 0 /*def*/, 0 /*min*/, ~0ULL /*max*/, 1); extern HASH tokudb_open_tables; -extern pthread_mutex_t tokudb_mutex; -extern uint32_t tokudb_write_status_frequency; -extern uint32_t tokudb_read_status_frequency; +extern tokudb::thread::mutex_t tokudb_mutex; +extern const char* tokudb_hton_name; +extern int tokudb_hton_initialized; +extern tokudb::thread::rwlock_t tokudb_hton_initialized_lock; void toku_hton_update_primary_key_bytes_inserted(uint64_t row_size); +void tokudb_split_dname( + const char* dname, + String& database_name, + String& table_name, + String& dictionary_name); + +void tokudb_pretty_left_key(const DB* db, const DBT* key, String* out); +void tokudb_pretty_right_key(const DB* db, const DBT* key, String* out); +const char *tokudb_get_index_name(DB* db); + +inline uint get_key_parts(const KEY *key) { +#if (50609 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ + (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ + (100009 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099) + return key->user_defined_key_parts; +#else + return key->key_parts; +#endif +} + #endif //#ifdef _HATOKU_HTON diff --git a/storage/tokudb/tokudb_background.cc b/storage/tokudb/tokudb_background.cc new file mode 100644 index 0000000000000..d8ef54a59729e --- /dev/null +++ b/storage/tokudb/tokudb_background.cc @@ -0,0 +1,253 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "tokudb_background.h" +#include "tokudb_sysvars.h" + +namespace tokudb { +namespace background { + + +std::atomic job_manager_t::job_t::_next_id(1); + +job_manager_t::job_t::job_t(bool user_scheduled) : + _running(false), + _cancelled(false), + _id(_next_id++), + _user_scheduled(user_scheduled), + _scheduled_time(::time(0)), + _started_time(0) { +} +job_manager_t::job_t::~job_t() { +} +void* job_manager_t::operator new(size_t sz) { + return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE)); +} +void job_manager_t::operator delete(void* p) { + tokudb::memory::free(p); +} +job_manager_t::job_manager_t() : + _sem(0, 65535), + _shutdown(false) { +} +job_manager_t::~job_manager_t() { +} +void job_manager_t::initialize() { + int r = _thread.start(thread_func, this); + assert_always(r == 0); +} +void job_manager_t::destroy() { + assert_always(!_shutdown); + assert_always(_foreground_jobs.size() == 0); + _shutdown = true; + _sem.set_interrupt(); + + while (_background_jobs.size()) { + _mutex.lock(); + job_t* job = _background_jobs.front(); + cancel(job); + _background_jobs.pop_front(); + delete job; + _mutex.unlock(); + } + + void* result; + int r = _thread.join(&result); + assert_always(r == 0); +} +bool job_manager_t::run_job(job_t* newjob, bool background) { + bool ret = false; + const char* jobkey = newjob->key(); + + _mutex.lock(); + assert_always(!_shutdown); + + for (jobs_t::iterator it = _background_jobs.begin(); + it != _background_jobs.end(); + it++) { + job_t* job = *it; + if (!job->cancelled() && strcmp(job->key(), jobkey) == 0) { + // if this is a foreground job being run and + // there is an existing background job of the same type + // and it is not running yet, we can cancel the background job + // and just run this one in the foreground, might have different + // params, but that is up to the user to figure out. + if (!background && !job->running()) { + job->cancel(); + } else { + // can't schedule or run another job on the same key + goto cleanup; + } + } + } + for (jobs_t::iterator it = _foreground_jobs.begin(); + it != _foreground_jobs.end(); + it++) { + job_t* job = *it; + if (strcmp(job->key(), jobkey) == 0) { + // can't schedule or run another job on the same key + // as an existing foreground job + goto cleanup; + } + } + + if (background) { + _background_jobs.push_back(newjob); + _sem.signal(); + ret = true; + } else { + _foreground_jobs.push_back(newjob); + + run(newjob); + + for (jobs_t::iterator it = _foreground_jobs.begin(); + it != _foreground_jobs.end(); + it++) { + job_t* job = *it; + if (job == newjob) { + _foreground_jobs.erase(it); + delete job; + break; + } + } + ret = true; + } + +cleanup: + _mutex.unlock(); + return ret; +} +bool job_manager_t::cancel_job(const char* key) { + bool ret = false; + _mutex.lock(); + + for (jobs_t::iterator it = _background_jobs.begin(); + it != _background_jobs.end(); it++) { + job_t* job = *it; + + if (!job->cancelled() && + strcmp(job->key(), key) == 0) { + + cancel(job); + + ret = true; + } + } + + _mutex.unlock(); + return ret; +} +void job_manager_t::iterate_jobs(pfn_iterate_t callback, void* extra) const { + + char database[256], table[256], type[256], params[256], status[256]; + + _mutex.lock(); + + for (jobs_t::const_iterator it = _background_jobs.begin(); + it != _background_jobs.end(); + it++) { + job_t* job = *it; + if (!job->cancelled()) { + database[0] = table[0] = type[0] = params[0] = status[0] = '\0'; + job->status(database, table, type, params, status); + callback( + job->id(), + database, + table, + type, + params, + status, + job->user_scheduled(), + job->scheduled_time(), + job->started_time(), + extra); + } + } + + _mutex.unlock(); +} +void* job_manager_t::thread_func(void* v) { + return ((tokudb::background::job_manager_t*)v)->real_thread_func(); +} +void* job_manager_t::real_thread_func() { + while (_shutdown == false) { + tokudb::thread::semaphore_t::E_WAIT res = _sem.wait(); + if (res == tokudb::thread::semaphore_t::E_INTERRUPTED || _shutdown) { + break; + } else if (res == tokudb::thread::semaphore_t::E_SIGNALLED) { +#if TOKUDB_DEBUG + if (TOKUDB_UNLIKELY( + tokudb::sysvars::debug_pause_background_job_manager)) { + _sem.signal(); + tokudb::time::sleep_microsec(250000); + continue; + } +#endif // TOKUDB_DEBUG + + _mutex.lock(); + assert_debug(_background_jobs.size() > 0); + job_t* job = _background_jobs.front(); + run(job); + _background_jobs.pop_front(); + _mutex.unlock(); + delete job; + } + } + return NULL; +} +void job_manager_t::run(job_t* job) { + assert_debug(_mutex.is_owned_by_me()); + if (!job->cancelled()) { + _mutex.unlock(); + // do job + job->run(); + // done job + _mutex.lock(); + } + if (!job->cancelled()) { + job->destroy(); + } +} +void job_manager_t::cancel(job_t* job) { + assert_debug(_mutex.is_owned_by_me()); + job->cancel(); +} +job_manager_t* _job_manager = NULL; + +bool initialize() { + assert_always(_job_manager == NULL); + _job_manager = new job_manager_t; + _job_manager->initialize(); + return true; +} +bool destroy() { + _job_manager->destroy(); + delete _job_manager; + _job_manager = NULL; + return true; +} +} // namespace background +} // namespace tokudb diff --git a/storage/tokudb/tokudb_background.h b/storage/tokudb/tokudb_background.h new file mode 100644 index 0000000000000..3786701fd0fa0 --- /dev/null +++ b/storage/tokudb/tokudb_background.h @@ -0,0 +1,212 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_BACKGROUND_H +#define _TOKUDB_BACKGROUND_H + +#include "hatoku_hton.h" +#include +#include + +namespace tokudb { +namespace background { + +class job_manager_t { +public: + class job_t { + public: + // NO default constructor + job_t() = delete; + + job_t(bool user_scheduled); + + virtual ~job_t(); + + // method that runs the job + inline void run(); + + // method that tells the job to cancel ASAP + inline void cancel(); + + // method that tells the job to clean up/free resources on cancel + // or completion + inline void destroy(); + + // method that returns a 'key' string for finding a specific job + // (or jobs) usually used to find jobs to cancel + virtual const char* key() = 0; + + // method to get info for information schema, 255 chars per buffer + virtual void status( + char* database, + char* table, + char* type, + char* params, + char* status) = 0; + + inline bool running() const; + + inline bool cancelled() const; + + inline uint64_t id() const; + + inline bool user_scheduled() const; + + inline time_t scheduled_time() const; + + inline time_t started_time() const; + + protected: + // derived classed implement this to actually run their job + virtual void on_run() {}; + + // derived classes implement this to cancel their job + virtual void on_cancel() {}; + + // derived classes implement this to clean up/free resources + virtual void on_destroy() {}; + + private: + static std::atomic _next_id; + std::atomic _running; + std::atomic _cancelled; + uint64_t _id; + bool _user_scheduled; + time_t _scheduled_time; + time_t _started_time; + }; + + // pfn for iterate callback + typedef void (*pfn_iterate_t)( + uint64_t, + const char*, + const char*, + const char*, + const char*, + const char*, + bool, + time_t, + time_t, + void*); + +public: + void* operator new(size_t sz); + void operator delete(void* p); + + job_manager_t(); + + ~job_manager_t(); + + // creates/initializes a singleton bjm + void initialize(); + + // destroys a bjm singleton + // cancels all jobs abd frees all resources + void destroy(); + + // schedules or runs a job depending on the 'background' value + // job specifics all depend on the implementation od 'job' + // background jobs will be executed in a FIFO fashion + // two jobs with the same key can not run concurrently + // if a foreground job is attempted, any currently scheduled or running + // background jobs will be cancelled first + // if another foreground job is already running, a new foreground job with + // the same key will be rejected + bool run_job(job_t* newjob, bool background); + + // cancels any background job with a matching key + bool cancel_job(const char* key); + + // iterates currently pending and running background jobs, calling + // 'callback' with the 'extra' data provided and the original 'extra' + // data passed when the job was scheduled + void iterate_jobs(pfn_iterate_t callback, void* extra) const; + +private: + static void* thread_func(void* v); + + void* real_thread_func(); + + // _mutex MUST be held on entry, will release and reaquire on exit + void run(job_t* job); + + // _mutex MUST be held on entry + void cancel(job_t* job); +private: + typedef std::list jobs_t; + + mutable tokudb::thread::mutex_t _mutex; + mutable tokudb::thread::semaphore_t _sem; + mutable tokudb::thread::thread_t _thread; + jobs_t _background_jobs; + jobs_t _foreground_jobs; + std::atomic _shutdown; +}; + +extern job_manager_t* _job_manager; + +bool initialize(); +bool destroy(); + +inline void job_manager_t::job_t::run() { + if (!_cancelled) { + _running = true; + _started_time = ::time(0); + on_run(); + _running = false; + } +} +inline void job_manager_t::job_t::cancel() { + _cancelled = true; + if (_running) + on_cancel(); + while (_running) tokudb::time::sleep_microsec(500000); + destroy(); +} +void job_manager_t::job_t::destroy() { + on_destroy(); +} +inline bool job_manager_t::job_t::running() const { + return _running; +} +inline bool job_manager_t::job_t::cancelled() const { + return _cancelled; +} +inline uint64_t job_manager_t::job_t::id() const { + return _id; +} +inline bool job_manager_t::job_t::user_scheduled() const { + return _user_scheduled; +} +inline time_t job_manager_t::job_t::scheduled_time() const { + return _scheduled_time; +} +inline time_t job_manager_t::job_t::started_time() const { + return _started_time; +} +} // namespace background +} // namespace tokudb + +#endif // _TOKUDB_BACKGROUND_H diff --git a/storage/tokudb/tokudb_buffer.h b/storage/tokudb/tokudb_buffer.h index 1604ea61e2d9a..022f1b4964308 100644 --- a/storage/tokudb/tokudb_buffer.h +++ b/storage/tokudb/tokudb_buffer.h @@ -23,38 +23,54 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." -#if !defined(_TOKUDB_BUFFER_H) +#ifndef _TOKUDB_BUFFER_H #define _TOKUDB_BUFFER_H +#include "hatoku_defines.h" +#include "tokudb_debug.h" +#include "tokudb_thread.h" #include "tokudb_vlq.h" namespace tokudb { -// A Buffer manages a contiguous chunk of memory and supports appending new data to the end of the buffer, and -// consuming chunks from the beginning of the buffer. The buffer will reallocate memory when appending -// new data to a full buffer. +// A Buffer manages a contiguous chunk of memory and supports appending new +// data to the end of the buffer, and consuming chunks from the beginning of +// the buffer. The buffer will reallocate memory when appending new data to +// a full buffer. class buffer { public: - buffer(void *the_data, size_t s, size_t l) : m_data(the_data), m_size(s), m_limit(l), m_is_static(true) { + inline buffer( + void* the_data, + size_t s, + size_t l) : + m_data(the_data), + m_size(s), + m_limit(l), + m_is_static(true) { } - buffer() : m_data(NULL), m_size(0), m_limit(0), m_is_static(false) { + inline buffer() : + m_data(NULL), + m_size(0), + m_limit(0), + m_is_static(false) { } virtual ~buffer() { if (!m_is_static) free(m_data); } - // Return a pointer to the end of the buffer suitable for appending a fixed number of bytes. - void *append_ptr(size_t s) { + // Return a pointer to the end of the buffer suitable for appending a + // fixed number of bytes. + void* append_ptr(size_t s) { maybe_realloc(s); - void *p = (char *) m_data + m_size; + void* p = (char*)m_data + m_size; m_size += s; return p; } // Append bytes to the buffer - void append(void *p, size_t s) { + void append(void* p, size_t s) { memcpy(append_ptr(s), p, s); } @@ -68,63 +84,70 @@ class buffer { return s; } - // Return a pointer to the next location in the buffer where bytes are consumed from. - void *consume_ptr(size_t s) { + // Return a pointer to the next location in the buffer where bytes are + // consumed from. + void* consume_ptr(size_t s) { if (m_size + s > m_limit) return NULL; - void *p = (char *) m_data + m_size; + void* p = (char*)m_data + m_size; m_size += s; return p; } // Consume bytes from the buffer. - void consume(void *p, size_t s) { + void consume(void* p, size_t s) { memcpy(p, consume_ptr(s), s); } // Consume an unsigned int from the buffer. - // Returns 0 if the unsigned int could not be decoded, probably because the buffer is too short. - // Otherwise return the number of bytes consumed, and stuffs the decoded number in *p. - template size_t consume_ui(T *p) { - size_t s = tokudb::vlq_decode_ui(p, (char *) m_data + m_size, m_limit - m_size); + // Returns 0 if the unsigned int could not be decoded, probably because + // the buffer is too short. + // Otherwise return the number of bytes consumed, and stuffs the decoded + // number in *p. + template size_t consume_ui(T* p) { + size_t s = tokudb::vlq_decode_ui( + p, + (char*)m_data + m_size, + m_limit - m_size); m_size += s; return s; } // Write p_length bytes at an offset in the buffer - void write(void *p, size_t p_length, size_t offset) { - assert(offset + p_length <= m_size); - memcpy((char *)m_data + offset, p, p_length); + void write(void* p, size_t p_length, size_t offset) { + assert_always(offset + p_length <= m_size); + memcpy((char*)m_data + offset, p, p_length); } // Read p_length bytes at an offset in the buffer - void read(void *p, size_t p_length, size_t offset) { - assert(offset + p_length <= m_size); - memcpy(p, (char *)m_data + offset, p_length); + void read(void* p, size_t p_length, size_t offset) { + assert_always(offset + p_length <= m_size); + memcpy(p, (char*)m_data + offset, p_length); } - // Replace a field in the buffer with new data. If the new data size is different, then readjust the - // size of the buffer and move things around. - void replace(size_t offset, size_t old_s, void *new_p, size_t new_s) { - assert(offset + old_s <= m_size); + // Replace a field in the buffer with new data. If the new data size is + // different, then readjust the size of the buffer and move things around. + void replace(size_t offset, size_t old_s, void* new_p, size_t new_s) { + assert_always(offset + old_s <= m_size); if (new_s > old_s) maybe_realloc(new_s - old_s); - char *data_offset = (char *) m_data + offset; + char* data_offset = (char*)m_data + offset; if (new_s != old_s) { size_t n = m_size - (offset + old_s); - assert(offset + new_s + n <= m_limit && offset + old_s + n <= m_limit); + assert_always( + offset + new_s + n <= m_limit && offset + old_s + n <= m_limit); memmove(data_offset + new_s, data_offset + old_s, n); if (new_s > old_s) m_size += new_s - old_s; else m_size -= old_s - new_s; - assert(m_size <= m_limit); + assert_always(m_size <= m_limit); } memcpy(data_offset, new_p, new_s); } // Return a pointer to the data in the buffer - void *data() const { + void* data() const { return m_data; } @@ -145,15 +168,15 @@ class buffer { size_t new_limit = m_limit * 2; if (new_limit < m_size + s) new_limit = m_size + s; - assert(!m_is_static); + assert_always(!m_is_static); void *new_data = realloc(m_data, new_limit); - assert(new_data != NULL); + assert_always(new_data != NULL); m_data = new_data; m_limit = new_limit; } } private: - void *m_data; + void* m_data; size_t m_size; size_t m_limit; bool m_is_static; diff --git a/storage/tokudb/tokudb_card.h b/storage/tokudb/tokudb_card.h index 04eac731aeb4b..fdf18d4ab129f 100644 --- a/storage/tokudb/tokudb_card.h +++ b/storage/tokudb/tokudb_card.h @@ -32,43 +32,49 @@ namespace tokudb { return total_key_parts; } - // Set the key_info cardinality counters for the table. - void set_card_in_key_info(TABLE *table, uint rec_per_keys, uint64_t rec_per_key[]) { - uint next_key_part = 0; - for (uint i = 0; i < table->s->keys; i++) { - bool is_unique_key = (i == table->s->primary_key) || (table->key_info[i].flags & HA_NOSAME); - uint num_key_parts = get_key_parts(&table->key_info[i]); - for (uint j = 0; j < num_key_parts; j++) { - assert(next_key_part < rec_per_keys); - ulong val = rec_per_key[next_key_part++]; - if (is_unique_key && j == num_key_parts-1) - val = 1; - table->key_info[i].rec_per_key[j] = val; - } - } - } - // Put the cardinality counters into the status dictionary. - int set_card_in_status(DB *status_db, DB_TXN *txn, uint rec_per_keys, uint64_t rec_per_key[]) { + int set_card_in_status( + DB* status_db, + DB_TXN* txn, + uint rec_per_keys, + const uint64_t rec_per_key[]) { + // encode cardinality into the buffer tokudb::buffer b; size_t s; s = b.append_ui(rec_per_keys); - assert(s > 0); + assert_always(s > 0); for (uint i = 0; i < rec_per_keys; i++) { s = b.append_ui(rec_per_key[i]); - assert(s > 0); + assert_always(s > 0); } // write cardinality to status - int error = write_to_status(status_db, hatoku_cardinality, b.data(), b.size(), txn); + int error = + tokudb::metadata::write( + status_db, + hatoku_cardinality, + b.data(), + b.size(), + txn); return error; } // Get the cardinality counters from the status dictionary. - int get_card_from_status(DB *status_db, DB_TXN *txn, uint rec_per_keys, uint64_t rec_per_key[]) { + int get_card_from_status( + DB* status_db, + DB_TXN* txn, + uint rec_per_keys, + uint64_t rec_per_key[]) { + // read cardinality from status - void *buf = 0; size_t buf_size = 0; - int error = get_status_realloc(status_db, txn, hatoku_cardinality, &buf, &buf_size); + void* buf = 0; size_t buf_size = 0; + int error = + tokudb::metadata::read_realloc( + status_db, + txn, + hatoku_cardinality, + &buf, + &buf_size); if (error == 0) { // decode cardinality from the buffer tokudb::buffer b(buf, 0, buf_size); @@ -93,12 +99,17 @@ namespace tokudb { } // Delete the cardinality counters from the status dictionary. - int delete_card_from_status(DB *status_db, DB_TXN *txn) { - int error = remove_from_status(status_db, hatoku_cardinality, txn); + int delete_card_from_status(DB* status_db, DB_TXN* txn) { + int error = + tokudb::metadata::remove(status_db, hatoku_cardinality, txn); return error; } - bool find_index_of_key(const char *key_name, TABLE_SHARE *table_share, uint *index_offset_ptr) { + bool find_index_of_key( + const char* key_name, + TABLE_SHARE* table_share, + uint* index_offset_ptr) { + for (uint i = 0; i < table_share->keys; i++) { if (strcmp(key_name, table_share->key_info[i].name) == 0) { *index_offset_ptr = i; @@ -113,16 +124,30 @@ namespace tokudb { dest[i] = src[i]; } - // Altered table cardinality = select cardinality data from current table cardinality for keys that exist + // Altered table cardinality = select cardinality data from current table + // cardinality for keys that exist // in the altered table and the current table. - int alter_card(DB *status_db, DB_TXN *txn, TABLE_SHARE *table_share, TABLE_SHARE *altered_table_share) { + int alter_card( + DB* status_db, + DB_TXN *txn, + TABLE_SHARE* table_share, + TABLE_SHARE* altered_table_share) { + int error; // read existing cardinality data from status - uint table_total_key_parts = tokudb::compute_total_key_parts(table_share); + uint table_total_key_parts = + tokudb::compute_total_key_parts(table_share); + uint64_t rec_per_key[table_total_key_parts]; - error = get_card_from_status(status_db, txn, table_total_key_parts, rec_per_key); + error = + get_card_from_status( + status_db, + txn, + table_total_key_parts, + rec_per_key); // set altered records per key to unknown - uint altered_table_total_key_parts = tokudb::compute_total_key_parts(altered_table_share); + uint altered_table_total_key_parts = + tokudb::compute_total_key_parts(altered_table_share); uint64_t altered_rec_per_key[altered_table_total_key_parts]; for (uint i = 0; i < altered_table_total_key_parts; i++) altered_rec_per_key[i] = 0; @@ -139,113 +164,28 @@ namespace tokudb { for (uint i = 0; error == 0 && i < altered_table_share->keys; i++) { uint ith_key_parts = get_key_parts(&altered_table_share->key_info[i]); uint orig_key_index; - if (find_index_of_key(altered_table_share->key_info[i].name, table_share, &orig_key_index)) { - copy_card(&altered_rec_per_key[next_key_parts], &rec_per_key[orig_key_offset[orig_key_index]], ith_key_parts); + if (find_index_of_key( + altered_table_share->key_info[i].name, + table_share, + &orig_key_index)) { + copy_card( + &altered_rec_per_key[next_key_parts], + &rec_per_key[orig_key_offset[orig_key_index]], + ith_key_parts); } next_key_parts += ith_key_parts; } } - if (error == 0) - error = set_card_in_status(status_db, txn, altered_table_total_key_parts, altered_rec_per_key); - else - error = delete_card_from_status(status_db, txn); - return error; - } - - struct analyze_card_cursor_callback_extra { - int (*analyze_progress)(void *extra, uint64_t rows); - void *analyze_extra; - uint64_t *rows; - uint64_t *deleted_rows; - }; - - bool analyze_card_cursor_callback(void *extra, uint64_t deleted_rows) { - analyze_card_cursor_callback_extra *a_extra = static_cast(extra); - *a_extra->deleted_rows += deleted_rows; - int r = a_extra->analyze_progress(a_extra->analyze_extra, *a_extra->rows); - sql_print_information("tokudb analyze_card_cursor_callback %u %" PRIu64 " %" PRIu64, r, *a_extra->deleted_rows, deleted_rows); - return r != 0; - } - - // Compute records per key for all key parts of the ith key of the table. - // For each key part, put records per key part in *rec_per_key_part[key_part_index]. - // Returns 0 if success, otherwise an error number. - // TODO statistical dives into the FT - int analyze_card(DB *db, DB_TXN *txn, bool is_unique, uint64_t num_key_parts, uint64_t *rec_per_key_part, - int (*key_compare)(DB *, const DBT *, const DBT *, uint), - int (*analyze_progress)(void *extra, uint64_t rows), void *progress_extra, - uint64_t *return_rows, uint64_t *return_deleted_rows) { - int error = 0; - uint64_t rows = 0; - uint64_t deleted_rows = 0; - uint64_t unique_rows[num_key_parts]; - if (is_unique && num_key_parts == 1) { - // dont compute for unique keys with a single part. we already know the answer. - rows = unique_rows[0] = 1; + if (error == 0) { + error = + set_card_in_status( + status_db, + txn, + altered_table_total_key_parts, + altered_rec_per_key); } else { - DBC *cursor = NULL; - error = db->cursor(db, txn, &cursor, 0); - if (error == 0) { - analyze_card_cursor_callback_extra e = { analyze_progress, progress_extra, &rows, &deleted_rows }; - cursor->c_set_check_interrupt_callback(cursor, analyze_card_cursor_callback, &e); - for (uint64_t i = 0; i < num_key_parts; i++) - unique_rows[i] = 1; - // stop looking when the entire dictionary was analyzed, or a cap on execution time was reached, or the analyze was killed. - DBT key = {}; key.flags = DB_DBT_REALLOC; - DBT prev_key = {}; prev_key.flags = DB_DBT_REALLOC; - while (1) { - error = cursor->c_get(cursor, &key, 0, DB_NEXT); - if (error != 0) { - if (error == DB_NOTFOUND || error == TOKUDB_INTERRUPTED) - error = 0; // not an error - break; - } - rows++; - // first row is a unique row, otherwise compare with the previous key - bool copy_key = false; - if (rows == 1) { - copy_key = true; - } else { - // compare this key with the previous key. ignore appended PK for SK's. - // TODO if a prefix is different, then all larger keys that include the prefix are also different. - // TODO if we are comparing the entire primary key or the entire unique secondary key, then the cardinality must be 1, - // so we can avoid computing it. - for (uint64_t i = 0; i < num_key_parts; i++) { - int cmp = key_compare(db, &prev_key, &key, i+1); - if (cmp != 0) { - unique_rows[i]++; - copy_key = true; - } - } - } - // prev_key = key - if (copy_key) { - prev_key.data = realloc(prev_key.data, key.size); - assert(prev_key.data); - prev_key.size = key.size; - memcpy(prev_key.data, key.data, prev_key.size); - } - // check for limit - if (analyze_progress && (rows % 1000) == 0) { - error = analyze_progress(progress_extra, rows); - if (error) - break; - } - } - // cleanup - free(key.data); - free(prev_key.data); - int close_error = cursor->c_close(cursor); - assert(close_error == 0); - } + error = delete_card_from_status(status_db, txn); } - // return cardinality - if (return_rows) - *return_rows = rows; - if (return_deleted_rows) - *return_deleted_rows = deleted_rows; - for (uint64_t i = 0; i < num_key_parts; i++) - rec_per_key_part[i] = rows / unique_rows[i]; return error; } } diff --git a/storage/tokudb/tokudb_debug.h b/storage/tokudb/tokudb_debug.h new file mode 100644 index 0000000000000..db66cab050cbf --- /dev/null +++ b/storage/tokudb/tokudb_debug.h @@ -0,0 +1,171 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_DEBUG_H +#define _TOKUDB_DEBUG_H + +#include "hatoku_defines.h" + +#define TOKU_INCLUDE_BACKTRACE 0 +#if TOKU_INCLUDE_BACKTRACE +static void tokudb_backtrace(void); +#endif + +// tokudb debug tracing for tokudb_debug declared in tokudb_sysvars.h/.cc +#define TOKUDB_DEBUG_INIT (1<<0) +#define TOKUDB_DEBUG_OPEN (1<<1) +#define TOKUDB_DEBUG_ENTER (1<<2) +#define TOKUDB_DEBUG_RETURN (1<<3) +#define TOKUDB_DEBUG_ERROR (1<<4) +#define TOKUDB_DEBUG_TXN (1<<5) +#define TOKUDB_DEBUG_AUTO_INCREMENT (1<<6) +#define TOKUDB_DEBUG_INDEX_KEY (1<<7) +#define TOKUDB_DEBUG_LOCK (1<<8) +#define TOKUDB_DEBUG_CHECK_KEY (1<<9) +#define TOKUDB_DEBUG_HIDE_DDL_LOCK_ERRORS (1<<10) +#define TOKUDB_DEBUG_ALTER_TABLE (1<<11) +#define TOKUDB_DEBUG_UPSERT (1<<12) +#define TOKUDB_DEBUG_CHECK (1<<13) +#define TOKUDB_DEBUG_ANALYZE (1<<14) + +#define TOKUDB_TRACE(_fmt, ...) { \ + fprintf(stderr, "%u %s:%u %s " _fmt "\n", tokudb::thread::my_tid(), \ + __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); \ +} + +#define TOKUDB_DEBUG_FLAGS(_flags) \ + (tokudb::sysvars::debug & _flags) + +#define TOKUDB_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \ + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \ + TOKUDB_TRACE(_fmt, ##__VA_ARGS__); \ + } \ +} + +#define TOKUDB_DBUG_ENTER(_fmt, ...) { \ + if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER)) { \ + TOKUDB_TRACE(_fmt, ##__VA_ARGS__); \ + } \ +} \ + DBUG_ENTER(__FUNCTION__); + +#define TOKUDB_DBUG_RETURN(r) { \ + int rr = (r); \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ + (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \ + TOKUDB_TRACE("return %d", rr); \ + } \ + DBUG_RETURN(rr); \ +} + +#define TOKUDB_HANDLER_TRACE(_fmt, ...) \ + fprintf(stderr, "%u %p %s:%u ha_tokudb::%s " _fmt "\n", \ + tokudb::thread::my_tid(), this, __FILE__, __LINE__, \ + __FUNCTION__, ##__VA_ARGS__); + +#define TOKUDB_HANDLER_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \ + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \ + TOKUDB_HANDLER_TRACE(_fmt, ##__VA_ARGS__); \ + } \ +} + + +#define TOKUDB_HANDLER_DBUG_ENTER(_fmt, ...) { \ + if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER)) { \ + TOKUDB_HANDLER_TRACE(_fmt, ##__VA_ARGS__); \ + } \ +} \ + DBUG_ENTER(__FUNCTION__); + +#define TOKUDB_HANDLER_DBUG_RETURN(r) { \ + int rr = (r); \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ + (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \ + TOKUDB_HANDLER_TRACE("return %d", rr); \ + } \ + DBUG_RETURN(rr); \ +} + +#define TOKUDB_HANDLER_DBUG_RETURN_DOUBLE(r) { \ + double rr = (r); \ + if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ + TOKUDB_HANDLER_TRACE("return %f", rr); \ + } \ + DBUG_RETURN(rr); \ +} + +#define TOKUDB_HANDLER_DBUG_RETURN_PTR(r) { \ + if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ + TOKUDB_HANDLER_TRACE("return 0x%p", r); \ + } \ + DBUG_RETURN(r); \ +} + + +#define TOKUDB_HANDLER_DBUG_VOID_RETURN { \ + if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ + TOKUDB_HANDLER_TRACE("return"); \ + } \ + DBUG_VOID_RETURN; \ +} + +#define TOKUDB_DBUG_DUMP(s, p, len) \ +{ \ + TOKUDB_TRACE("%s", s); \ + uint i; \ + for (i=0; i. + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "hatoku_hton.h" +#include "tokudb_information_schema.h" +#include "sql_time.h" +#include "tokudb_background.h" + + +namespace tokudb { +namespace information_schema { + +static void field_store_time_t(Field* field, time_t time) { + MYSQL_TIME my_time; + struct tm tm_time; + + if (time) { + localtime_r(&time, &tm_time); + localtime_to_TIME(&my_time, &tm_time); + my_time.time_type = MYSQL_TIMESTAMP_DATETIME; + field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME); + field->set_notnull(); + } else { + memset(&my_time, 0, sizeof(my_time)); + field->store_time(&my_time, MYSQL_TIMESTAMP_DATETIME); + field->set_null(); + } +} + +st_mysql_information_schema trx_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + +ST_FIELD_INFO trx_field_info[] = { + {"trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"trx_mysql_thread_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"trx_time", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +struct trx_extra_t { + THD *thd; + TABLE *table; +}; + +int trx_callback( + DB_TXN* txn, + iterate_row_locks_callback iterate_locks, + void* locks_extra, + void *extra) { + + uint64_t txn_id = txn->id64(txn); + uint64_t client_id = txn->get_client_id(txn); + uint64_t start_time = txn->get_start_time(txn); + trx_extra_t* e = reinterpret_cast(extra); + THD* thd = e->thd; + TABLE* table = e->table; + table->field[0]->store(txn_id, false); + table->field[1]->store(client_id, false); + uint64_t tnow = (uint64_t) ::time(NULL); + table->field[2]->store(tnow >= start_time ? tnow - start_time : 0, false); + int error = schema_table_store_record(thd, table); + if (!error && thd_killed(thd)) + error = ER_QUERY_INTERRUPTED; + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int trx_fill_table(THD* thd, TABLE_LIST* tables, Item* cond) { +#else +int trx_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + trx_extra_t e = { thd, tables->table }; + error = db_env->iterate_live_transactions(db_env, trx_callback, &e); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int trx_init(void* p) { + ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE*) p; + schema->fields_info = trx_field_info; + schema->fill_table = trx_fill_table; + return 0; +} + +int trx_done(void* p) { + return 0; +} + +st_mysql_plugin trx = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &trx_information_schema, + "TokuDB_trx", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + trx_init, /* plugin init */ + trx_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + + + +st_mysql_information_schema lock_waits_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + +ST_FIELD_INFO lock_waits_field_info[] = { + {"requesting_trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"blocking_trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_dname", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_key_left", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_key_right", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_start_time", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"lock_waits_table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +struct lock_waits_extra_t { + THD* thd; + TABLE* table; +}; + +int lock_waits_callback( + DB* db, + uint64_t requesting_txnid, + const DBT* left_key, + const DBT* right_key, + uint64_t blocking_txnid, + uint64_t start_time, + void *extra) { + + lock_waits_extra_t* e = + reinterpret_cast(extra); + THD* thd = e->thd; + TABLE* table = e->table; + table->field[0]->store(requesting_txnid, false); + table->field[1]->store(blocking_txnid, false); + const char* dname = tokudb_get_index_name(db); + size_t dname_length = strlen(dname); + table->field[2]->store(dname, dname_length, system_charset_info); + String left_str; + tokudb_pretty_left_key(db, left_key, &left_str); + table->field[3]->store( + left_str.ptr(), + left_str.length(), + system_charset_info); + String right_str; + tokudb_pretty_right_key(db, right_key, &right_str); + table->field[4]->store( + right_str.ptr(), + right_str.length(), + system_charset_info); + table->field[5]->store(start_time, false); + + String database_name, table_name, dictionary_name; + tokudb_split_dname(dname, database_name, table_name, dictionary_name); + table->field[6]->store( + database_name.c_ptr(), + database_name.length(), + system_charset_info); + table->field[7]->store( + table_name.c_ptr(), + table_name.length(), + system_charset_info); + table->field[8]->store( + dictionary_name.c_ptr(), + dictionary_name.length(), + system_charset_info); + + int error = schema_table_store_record(thd, table); + + if (!error && thd_killed(thd)) + error = ER_QUERY_INTERRUPTED; + + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int lock_waits_fill_table(THD* thd, TABLE_LIST* tables, Item* cond) { +#else +int lock_waits_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + lock_waits_extra_t e = { thd, tables->table }; + error = db_env->iterate_pending_lock_requests( + db_env, + lock_waits_callback, + &e); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int lock_waits_init(void* p) { + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*)p; + schema->fields_info = lock_waits_field_info; + schema->fill_table = lock_waits_fill_table; + return 0; +} + +int lock_waits_done(void *p) { + return 0; +} + +st_mysql_plugin lock_waits = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &lock_waits_information_schema, + "TokuDB_lock_waits", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + lock_waits_init, /* plugin init */ + lock_waits_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + + + +st_mysql_information_schema locks_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + + ST_FIELD_INFO locks_field_info[] = { + {"locks_trx_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_mysql_thread_id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_dname", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_key_left", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_key_right", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"locks_table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +struct locks_extra_t { + THD* thd; + TABLE* table; +}; + +int locks_callback( + DB_TXN* txn, + iterate_row_locks_callback iterate_locks, + void* locks_extra, + void* extra) { + + uint64_t txn_id = txn->id64(txn); + uint64_t client_id = txn->get_client_id(txn); + locks_extra_t* e = reinterpret_cast(extra); + THD* thd = e->thd; + TABLE* table = e->table; + int error = 0; + DB* db; + DBT left_key, right_key; + while (error == 0 && + iterate_locks(&db, &left_key, &right_key, locks_extra) == 0) { + table->field[0]->store(txn_id, false); + table->field[1]->store(client_id, false); + + const char* dname = tokudb_get_index_name(db); + size_t dname_length = strlen(dname); + table->field[2]->store(dname, dname_length, system_charset_info); + + String left_str; + tokudb_pretty_left_key(db, &left_key, &left_str); + table->field[3]->store( + left_str.ptr(), + left_str.length(), + system_charset_info); + + String right_str; + tokudb_pretty_right_key(db, &right_key, &right_str); + table->field[4]->store( + right_str.ptr(), + right_str.length(), + system_charset_info); + + String database_name, table_name, dictionary_name; + tokudb_split_dname(dname, database_name, table_name, dictionary_name); + table->field[5]->store( + database_name.c_ptr(), + database_name.length(), + system_charset_info); + table->field[6]->store( + table_name.c_ptr(), + table_name.length(), + system_charset_info); + table->field[7]->store( + dictionary_name.c_ptr(), + dictionary_name.length(), + system_charset_info); + + error = schema_table_store_record(thd, table); + + if (!error && thd_killed(thd)) + error = ER_QUERY_INTERRUPTED; + } + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int locks_fill_table(THD* thd, TABLE_LIST* tables, Item* cond) { +#else +int locks_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + locks_extra_t e = { thd, tables->table }; + error = db_env->iterate_live_transactions(db_env, locks_callback, &e); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int locks_init(void* p) { + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*)p; + schema->fields_info = locks_field_info; + schema->fill_table = locks_fill_table; + return 0; +} + +int locks_done(void* p) { + return 0; +} + +st_mysql_plugin locks = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &locks_information_schema, + "TokuDB_locks", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + locks_init, /* plugin init */ + locks_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + + + +st_mysql_information_schema file_map_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + +ST_FIELD_INFO file_map_field_info[] = { + {"dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"internal_file_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +int report_file_map(TABLE* table, THD* thd) { + int error; + DB_TXN* txn = NULL; + DBC* tmp_cursor = NULL; + DBT curr_key; + DBT curr_val; + memset(&curr_key, 0, sizeof curr_key); + memset(&curr_val, 0, sizeof curr_val); + error = txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED, thd); + if (error) { + goto cleanup; + } + error = db_env->get_cursor_for_directory(db_env, txn, &tmp_cursor); + if (error) { + goto cleanup; + } + while (error == 0) { + error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT); + if (!error) { + // We store the NULL terminator in the directory so it's included + // in the size. + // See #5789 + // Recalculate and check just to be safe. + const char *dname = (const char *) curr_key.data; + size_t dname_len = strlen(dname); + assert(dname_len == curr_key.size - 1); + table->field[0]->store(dname, dname_len, system_charset_info); + + const char *iname = (const char *) curr_val.data; + size_t iname_len = strlen(iname); + assert(iname_len == curr_val.size - 1); + table->field[1]->store(iname, iname_len, system_charset_info); + + // split the dname + String database_name, table_name, dictionary_name; + tokudb_split_dname( + dname, + database_name, + table_name, + dictionary_name); + table->field[2]->store( + database_name.c_ptr(), + database_name.length(), + system_charset_info); + table->field[3]->store( + table_name.c_ptr(), + table_name.length(), + system_charset_info); + table->field[4]->store( + dictionary_name.c_ptr(), + dictionary_name.length(), + system_charset_info); + + error = schema_table_store_record(thd, table); + } + if (!error && thd_killed(thd)) + error = ER_QUERY_INTERRUPTED; + } + if (error == DB_NOTFOUND) { + error = 0; + } +cleanup: + if (tmp_cursor) { + int r = tmp_cursor->c_close(tmp_cursor); + assert(r == 0); + } + if (txn) { + commit_txn(txn, 0); + } + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int file_map_fill_table(THD* thd, TABLE_LIST* tables, Item* cond) { +#else +int file_map_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + TABLE* table = tables->table; + + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + error = report_file_map(table, thd); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int file_map_init(void* p) { + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*)p; + schema->fields_info = file_map_field_info; + schema->fill_table = file_map_fill_table; + return 0; +} + +int file_map_done(void* p) { + return 0; +} + +st_mysql_plugin file_map = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &file_map_information_schema, + "TokuDB_file_map", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + file_map_init, /* plugin init */ + file_map_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + + + +st_mysql_information_schema fractal_tree_info_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + +ST_FIELD_INFO fractal_tree_info_field_info[] = { + {"dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"internal_file_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"bt_num_blocks_allocated", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"bt_num_blocks_in_use", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"bt_size_allocated", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"bt_size_in_use", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +int report_fractal_tree_info_for_db( + const DBT* dname, + const DBT* iname, + TABLE* table, + THD* thd) { + + int error; + uint64_t bt_num_blocks_allocated; + uint64_t bt_num_blocks_in_use; + uint64_t bt_size_allocated; + uint64_t bt_size_in_use; + + DB *db = NULL; + error = db_create(&db, db_env, 0); + if (error) { + goto exit; + } + error = db->open(db, NULL, (char *)dname->data, NULL, DB_BTREE, 0, 0666); + if (error) { + goto exit; + } + error = db->get_fractal_tree_info64( + db, + &bt_num_blocks_allocated, + &bt_num_blocks_in_use, + &bt_size_allocated, + &bt_size_in_use); + if (error) { + goto exit; + } + + // We store the NULL terminator in the directory so it's included in the + // size. + // See #5789 + // Recalculate and check just to be safe. + { + size_t dname_len = strlen((const char*)dname->data); + assert(dname_len == dname->size - 1); + table->field[0]->store( + (char*)dname->data, + dname_len, + system_charset_info); + size_t iname_len = strlen((const char*)iname->data); + assert(iname_len == iname->size - 1); + table->field[1]->store( + (char*)iname->data, + iname_len, + system_charset_info); + } + table->field[2]->store(bt_num_blocks_allocated, false); + table->field[3]->store(bt_num_blocks_in_use, false); + table->field[4]->store(bt_size_allocated, false); + table->field[5]->store(bt_size_in_use, false); + + // split the dname + { + String database_name, table_name, dictionary_name; + tokudb_split_dname( + (const char*)dname->data, + database_name, + table_name, + dictionary_name); + table->field[6]->store( + database_name.c_ptr(), + database_name.length(), + system_charset_info); + table->field[7]->store( + table_name.c_ptr(), + table_name.length(), + system_charset_info); + table->field[8]->store( + dictionary_name.c_ptr(), + dictionary_name.length(), + system_charset_info); + } + error = schema_table_store_record(thd, table); + +exit: + if (db) { + int close_error = db->close(db, 0); + if (error == 0) + error = close_error; + } + return error; +} + +int report_fractal_tree_info(TABLE* table, THD* thd) { + int error; + DB_TXN* txn = NULL; + DBC* tmp_cursor = NULL; + DBT curr_key; + DBT curr_val; + memset(&curr_key, 0, sizeof curr_key); + memset(&curr_val, 0, sizeof curr_val); + error = txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED, thd); + if (error) { + goto cleanup; + } + error = db_env->get_cursor_for_directory(db_env, txn, &tmp_cursor); + if (error) { + goto cleanup; + } + while (error == 0) { + error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT); + if (!error) { + error = report_fractal_tree_info_for_db( + &curr_key, + &curr_val, + table, + thd); + if (error) + error = 0; // ignore read uncommitted errors + } + if (!error && thd_killed(thd)) + error = ER_QUERY_INTERRUPTED; + } + if (error == DB_NOTFOUND) { + error = 0; + } +cleanup: + if (tmp_cursor) { + int r = tmp_cursor->c_close(tmp_cursor); + assert(r == 0); + } + if (txn) { + commit_txn(txn, 0); + } + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int fractal_tree_info_fill_table(THD* thd, TABLE_LIST* tables, Item* cond) { +#else +int fractal_tree_info_fill_table(THD* thd, TABLE_LIST* tables, COND* cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + TABLE* table = tables->table; + + // 3938: Get a read lock on the status flag, since we must + // read it before safely proceeding + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + error = report_fractal_tree_info(table, thd); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + //3938: unlock the status flag lock + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int fractal_tree_info_init(void* p) { + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*)p; + schema->fields_info = fractal_tree_info_field_info; + schema->fill_table = fractal_tree_info_fill_table; + return 0; +} + +int fractal_tree_info_done(void* p) { + return 0; +} + +st_mysql_plugin fractal_tree_info = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &fractal_tree_info_information_schema, + "TokuDB_fractal_tree_info", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + fractal_tree_info_init, /* plugin init */ + fractal_tree_info_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + + + +st_mysql_information_schema fractal_tree_block_map_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + +ST_FIELD_INFO fractal_tree_block_map_field_info[] = { + {"dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"internal_file_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"checkpoint_count", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"blocknum", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"offset", 0, MYSQL_TYPE_LONGLONG, 0, MY_I_S_MAYBE_NULL, NULL, SKIP_OPEN_TABLE }, + {"size", 0, MYSQL_TYPE_LONGLONG, 0, MY_I_S_MAYBE_NULL, NULL, SKIP_OPEN_TABLE }, + {"table_schema", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_dictionary_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +struct report_fractal_tree_block_map_iterator_extra_t { + int64_t num_rows; + int64_t i; + uint64_t* checkpoint_counts; + int64_t* blocknums; + int64_t* diskoffs; + int64_t* sizes; +}; + +// This iterator is called while holding the blocktable lock. +// We should be as quick as possible. +// We don't want to do one call to get the number of rows, release the +// blocktable lock, and then do another call to get all the rows because +// the number of rows may change if we don't hold the lock. +// As a compromise, we'll do some mallocs inside the lock on the first call, +// but everything else should be fast. +int report_fractal_tree_block_map_iterator( + uint64_t checkpoint_count, + int64_t num_rows, + int64_t blocknum, + int64_t diskoff, + int64_t size, + void* iter_extra) { + + struct report_fractal_tree_block_map_iterator_extra_t* e = + static_cast(iter_extra); + + assert(num_rows > 0); + if (e->num_rows == 0) { + e->checkpoint_counts = + (uint64_t*)tokudb::memory::malloc( + num_rows * (sizeof *e->checkpoint_counts), + MYF(MY_WME|MY_ZEROFILL|MY_FAE)); + e->blocknums = + (int64_t*)tokudb::memory::malloc( + num_rows * (sizeof *e->blocknums), + MYF(MY_WME|MY_ZEROFILL|MY_FAE)); + e->diskoffs = + (int64_t*)tokudb::memory::malloc( + num_rows * (sizeof *e->diskoffs), + MYF(MY_WME|MY_ZEROFILL|MY_FAE)); + e->sizes = + (int64_t*)tokudb::memory::malloc( + num_rows * (sizeof *e->sizes), + MYF(MY_WME|MY_ZEROFILL|MY_FAE)); + e->num_rows = num_rows; + } + + e->checkpoint_counts[e->i] = checkpoint_count; + e->blocknums[e->i] = blocknum; + e->diskoffs[e->i] = diskoff; + e->sizes[e->i] = size; + ++(e->i); + + return 0; +} + +int report_fractal_tree_block_map_for_db( + const DBT* dname, + const DBT* iname, + TABLE* table, + THD* thd) { + + int error; + DB* db; + // avoid struct initializers so that we can compile with older gcc versions + report_fractal_tree_block_map_iterator_extra_t e = {}; + + error = db_create(&db, db_env, 0); + if (error) { + goto exit; + } + error = db->open(db, NULL, (char *)dname->data, NULL, DB_BTREE, 0, 0666); + if (error) { + goto exit; + } + error = db->iterate_fractal_tree_block_map( + db, + report_fractal_tree_block_map_iterator, + &e); + { + int close_error = db->close(db, 0); + if (!error) { + error = close_error; + } + } + if (error) { + goto exit; + } + + // If not, we should have gotten an error and skipped this section of code + assert(e.i == e.num_rows); + for (int64_t i = 0; error == 0 && i < e.num_rows; ++i) { + // We store the NULL terminator in the directory so it's included in the size. + // See #5789 + // Recalculate and check just to be safe. + size_t dname_len = strlen((const char*)dname->data); + assert(dname_len == dname->size - 1); + table->field[0]->store( + (char*)dname->data, + dname_len, + system_charset_info); + + size_t iname_len = strlen((const char*)iname->data); + assert(iname_len == iname->size - 1); + table->field[1]->store( + (char*)iname->data, + iname_len, + system_charset_info); + + table->field[2]->store(e.checkpoint_counts[i], false); + table->field[3]->store(e.blocknums[i], false); + static const int64_t freelist_null = -1; + static const int64_t diskoff_unused = -2; + if (e.diskoffs[i] == diskoff_unused || e.diskoffs[i] == freelist_null) { + table->field[4]->set_null(); + } else { + table->field[4]->set_notnull(); + table->field[4]->store(e.diskoffs[i], false); + } + static const int64_t size_is_free = -1; + if (e.sizes[i] == size_is_free) { + table->field[5]->set_null(); + } else { + table->field[5]->set_notnull(); + table->field[5]->store(e.sizes[i], false); + } + + // split the dname + String database_name, table_name, dictionary_name; + tokudb_split_dname( + (const char*)dname->data, + database_name, + table_name, + dictionary_name); + table->field[6]->store( + database_name.c_ptr(), + database_name.length(), + system_charset_info); + table->field[7]->store( + table_name.c_ptr(), + table_name.length(), + system_charset_info); + table->field[8]->store( + dictionary_name.c_ptr(), + dictionary_name.length(), + system_charset_info); + + error = schema_table_store_record(thd, table); + } + +exit: + if (e.checkpoint_counts != NULL) { + tokudb::memory::free(e.checkpoint_counts); + e.checkpoint_counts = NULL; + } + if (e.blocknums != NULL) { + tokudb::memory::free(e.blocknums); + e.blocknums = NULL; + } + if (e.diskoffs != NULL) { + tokudb::memory::free(e.diskoffs); + e.diskoffs = NULL; + } + if (e.sizes != NULL) { + tokudb::memory::free(e.sizes); + e.sizes = NULL; + } + return error; +} + +int report_fractal_tree_block_map(TABLE* table, THD* thd) { + int error; + DB_TXN* txn = NULL; + DBC* tmp_cursor = NULL; + DBT curr_key; + DBT curr_val; + memset(&curr_key, 0, sizeof curr_key); + memset(&curr_val, 0, sizeof curr_val); + error = txn_begin(db_env, 0, &txn, DB_READ_UNCOMMITTED, thd); + if (error) { + goto cleanup; + } + error = db_env->get_cursor_for_directory(db_env, txn, &tmp_cursor); + if (error) { + goto cleanup; + } + while (error == 0) { + error = tmp_cursor->c_get(tmp_cursor, &curr_key, &curr_val, DB_NEXT); + if (!error) { + error = report_fractal_tree_block_map_for_db( + &curr_key, + &curr_val, + table, + thd); + } + if (!error && thd_killed(thd)) + error = ER_QUERY_INTERRUPTED; + } + if (error == DB_NOTFOUND) { + error = 0; + } +cleanup: + if (tmp_cursor) { + int r = tmp_cursor->c_close(tmp_cursor); + assert(r == 0); + } + if (txn) { + commit_txn(txn, 0); + } + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int fractal_tree_block_map_fill_table( + THD* thd, + TABLE_LIST* tables, + Item* cond) { +#else +int fractal_tree_block_map_fill_table( + THD* thd, + TABLE_LIST* tables, + COND* cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + TABLE* table = tables->table; + + // 3938: Get a read lock on the status flag, since we must + // read it before safely proceeding + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + error = report_fractal_tree_block_map(table, thd); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + //3938: unlock the status flag lock + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int fractal_tree_block_map_init(void* p) { + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*)p; + schema->fields_info = fractal_tree_block_map_field_info; + schema->fill_table = fractal_tree_block_map_fill_table; + return 0; +} + +int fractal_tree_block_map_done(void *p) { + return 0; +} + +st_mysql_plugin fractal_tree_block_map = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &fractal_tree_block_map_information_schema, + "TokuDB_fractal_tree_block_map", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + fractal_tree_block_map_init, /* plugin init */ + fractal_tree_block_map_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + + +st_mysql_information_schema background_job_status_information_schema = { + MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION +}; + +ST_FIELD_INFO background_job_status_field_info[] = { + {"id", 0, MYSQL_TYPE_LONGLONG, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"database_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"table_name", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"job_type", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"job_params", 256, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"scheduler", 32, MYSQL_TYPE_STRING, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"scheduled_time", 0, MYSQL_TYPE_DATETIME, 0, 0, NULL, SKIP_OPEN_TABLE }, + {"started_time", 0, MYSQL_TYPE_DATETIME, 0, MY_I_S_MAYBE_NULL, NULL, SKIP_OPEN_TABLE }, + {"status", 256, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, SKIP_OPEN_TABLE }, + {NULL, 0, MYSQL_TYPE_NULL, 0, 0, NULL, SKIP_OPEN_TABLE} +}; + +struct background_job_status_extra { + THD* thd; + TABLE* table; +}; + +void background_job_status_callback( + uint64_t id, + const char* database_name, + const char* table_name, + const char* type, + const char* params, + const char* status, + bool user_scheduled, + time_t scheduled_time, + time_t started_time, + void* extra) { + + background_job_status_extra* e = + reinterpret_cast(extra); + + THD* thd = e->thd; + TABLE* table = e->table; + + table->field[0]->store(id, false); + table->field[1]->store( + database_name, + strlen(database_name), + system_charset_info); + table->field[2]->store(table_name, strlen(table_name), system_charset_info); + table->field[3]->store(type, strlen(type), system_charset_info); + table->field[4]->store(params, strlen(params), system_charset_info); + if (user_scheduled) + table->field[5]->store("USER", sizeof("USER"), system_charset_info); + else + table->field[5]->store("AUTO", sizeof("AUTO"), system_charset_info); + + field_store_time_t(table->field[6], scheduled_time); + field_store_time_t(table->field[7], started_time); + if (status[0] != '\0') { + table->field[8]->store(status, strlen(status), system_charset_info); + table->field[8]->set_notnull(); + } else { + table->field[8]->store(NULL, 0, system_charset_info); + table->field[8]->set_null(); + } + + schema_table_store_record(thd, table); +} + +int report_background_job_status(TABLE *table, THD *thd) { + int error = 0; + background_job_status_extra extra = { + thd, + table + }; + tokudb::background::_job_manager->iterate_jobs( + background_job_status_callback, + &extra); + return error; +} + +#if MYSQL_VERSION_ID >= 50600 +int background_job_status_fill_table(THD *thd, TABLE_LIST *tables, Item *cond) { +#else +int background_job_status_fill_table(THD *thd, TABLE_LIST *tables, COND *cond) { +#endif + TOKUDB_DBUG_ENTER(""); + int error; + TABLE* table = tables->table; + + tokudb_hton_initialized_lock.lock_read(); + + if (!tokudb_hton_initialized) { + error = ER_PLUGIN_IS_NOT_LOADED; + my_error(error, MYF(0), tokudb_hton_name); + } else { + error = report_background_job_status(table, thd); + if (error) + my_error(ER_GET_ERRNO, MYF(0), error, tokudb_hton_name); + } + + tokudb_hton_initialized_lock.unlock(); + TOKUDB_DBUG_RETURN(error); +} + +int background_job_status_init(void* p) { + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*)p; + schema->fields_info = background_job_status_field_info; + schema->fill_table = background_job_status_fill_table; + return 0; +} + +int background_job_status_done(void* p) { + return 0; +} + +st_mysql_plugin background_job_status = { + MYSQL_INFORMATION_SCHEMA_PLUGIN, + &background_job_status_information_schema, + "TokuDB_background_job_status", + "Percona", + "Percona TokuDB Storage Engine with Fractal Tree(tm) Technology", + PLUGIN_LICENSE_GPL, + background_job_status_init, /* plugin init */ + background_job_status_done, /* plugin deinit */ + TOKUDB_PLUGIN_VERSION, + NULL, /* status variables */ + NULL, /* system variables */ +#ifdef MARIA_PLUGIN_INTERFACE_VERSION + tokudb::sysvars::version, + MariaDB_PLUGIN_MATURITY_STABLE /* maturity */ +#else + NULL, /* config options */ + 0, /* flags */ +#endif +}; + +} // namespace information_schema +} // namespace tokudb diff --git a/storage/tokudb/tokudb_information_schema.h b/storage/tokudb/tokudb_information_schema.h new file mode 100644 index 0000000000000..7f42d68ef59a6 --- /dev/null +++ b/storage/tokudb/tokudb_information_schema.h @@ -0,0 +1,46 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_INFORMATION_SCHEMA_H +#define _TOKUDB_INFORMATION_SCHEMA_H + +#include "hatoku_defines.h" + +namespace tokudb { +namespace information_schema { + +extern st_mysql_plugin trx; +extern st_mysql_plugin lock_waits; +extern st_mysql_plugin locks; +extern st_mysql_plugin file_map; +extern st_mysql_plugin fractal_tree_info; +extern st_mysql_plugin fractal_tree_block_map; +extern st_mysql_plugin background_job_status; + +} // namespace information_schema +} // namespace tokudb + +#endif // _TOKUDB_INFORMATION_SCHEMA_H diff --git a/storage/tokudb/tokudb_math.h b/storage/tokudb/tokudb_math.h index c49af2a6a213b..0338bf3871e5c 100644 --- a/storage/tokudb/tokudb_math.h +++ b/storage/tokudb/tokudb_math.h @@ -32,30 +32,34 @@ namespace tokudb { // Overflow detection adapted from "Hackers Delight", Henry S. Warren // Return a bit mask for bits 0 .. length_bits-1 -static uint64_t uint_mask(uint length_bits) __attribute__((unused)); +TOKUDB_UNUSED(static uint64_t uint_mask(uint length_bits)); static uint64_t uint_mask(uint length_bits) { return length_bits == 64 ? ~0ULL : (1ULL< x; // check for overflow return s; } // Return the highest int with a given number of bits -static int64_t int_high_endpoint(uint length_bits) __attribute__((unused)); +TOKUDB_UNUSED(static int64_t int_high_endpoint(uint length_bits)); static int64_t int_high_endpoint(uint length_bits) { return (1ULL<<(length_bits-1))-1; } // Return the lowest int with a given number of bits -static int64_t int_low_endpoint(uint length_bits) __attribute__((unused)); +TOKUDB_UNUSED(static int64_t int_low_endpoint(uint length_bits)); static int64_t int_low_endpoint(uint length_bits) { int64_t mask = uint_mask(length_bits); return (1ULL<<(length_bits-1)) | ~mask; } // Sign extend to 64 bits an int with a given number of bits -static int64_t int_sign_extend(int64_t n, uint length_bits) __attribute__((unused)); +TOKUDB_UNUSED(static int64_t int_sign_extend(int64_t n, uint length_bits)); static int64_t int_sign_extend(int64_t n, uint length_bits) { if (n & (1ULL<<(length_bits-1))) n |= ~uint_mask(length_bits); @@ -99,7 +107,11 @@ static int64_t int_sign_extend(int64_t n, uint length_bits) { // depending on the sign bit. // Sign extend to 64 bits. // Return the sum and the overflow. -static int64_t int_add(int64_t x, int64_t y, uint length_bits, bool *over) __attribute__((unused)); +TOKUDB_UNUSED(static int64_t int_add( + int64_t x, + int64_t y, + uint length_bits, + bool* over)); static int64_t int_add(int64_t x, int64_t y, uint length_bits, bool *over) { int64_t mask = uint_mask(length_bits); int64_t n = (x + y) & mask; @@ -114,7 +126,11 @@ static int64_t int_add(int64_t x, int64_t y, uint length_bits, bool *over) { // depending on the sign bit. // Sign extend to 64 bits. // Return the sum and the overflow. -static int64_t int_sub(int64_t x, int64_t y, uint length_bits, bool *over) __attribute__((unused)); +TOKUDB_UNUSED(static int64_t int_sub( + int64_t x, + int64_t y, + uint length_bits, + bool* over)); static int64_t int_sub(int64_t x, int64_t y, uint length_bits, bool *over) { int64_t mask = uint_mask(length_bits); int64_t n = (x - y) & mask; diff --git a/storage/tokudb/tokudb_memory.h b/storage/tokudb/tokudb_memory.h new file mode 100644 index 0000000000000..26587de6062f8 --- /dev/null +++ b/storage/tokudb/tokudb_memory.h @@ -0,0 +1,102 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_MEMORY_H +#define _TOKUDB_MEMORY_H + +#include "hatoku_defines.h" + +namespace tokudb { +namespace memory { + +void* malloc(size_t s, myf flags); +void* realloc(void* p, size_t s, myf flags); +void free(void* ptr); +char* strdup(const char* p, myf flags); +void* multi_malloc(myf myFlags, ...); + + +inline void* malloc(size_t s, myf flags) { +#if 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799 + return ::my_malloc(0, s, flags); +#else + return ::my_malloc(s, flags); +#endif +} +inline void* realloc(void* p, size_t s, myf flags) { + if (s == 0) + return p; +#if 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799 + return ::my_realloc(0, p, s, flags); +#else + return ::my_realloc(p, s, flags); +#endif +} +inline void free(void* ptr) { + if (ptr) + ::my_free(ptr); +} +inline char* strdup(const char* p, myf flags) { +#if 50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799 + return ::my_strdup(0, p, flags); +#else + return ::my_strdup(p, flags); +#endif +} +inline void* multi_malloc(myf myFlags, ...) { + va_list args; + char** ptr; + char* start; + char* res; + size_t tot_length,length; + + va_start(args,myFlags); + 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*)malloc(tot_length, myFlags))) { + return 0; + } + + va_start(args, myFlags); + res = start; + while ((ptr = va_arg(args, char**))) { + *ptr = res; + length = va_arg(args,uint); + res += ALIGN_SIZE(length); + } + va_end(args); + return start; +} + +} // namespace thread +} // namespace tokudb + +#endif // _TOKUDB_MEMORY_H diff --git a/storage/tokudb/tokudb_status.h b/storage/tokudb/tokudb_status.h index 4600e04596fc4..5cca54e52c9fd 100644 --- a/storage/tokudb/tokudb_status.h +++ b/storage/tokudb/tokudb_status.h @@ -43,118 +43,374 @@ typedef ulonglong HA_METADATA_KEY; #define status_dict_pagesize 1024 namespace tokudb { +namespace metadata { - // get the value for a given key in the status dictionary. copy the value to the supplied buffer. - // returns 0 if successful. - int get_status(DB *status_db, DB_TXN *txn, HA_METADATA_KEY k, void *p, size_t s, size_t *sp) { - DBT key = {}; key.data = &k; key.size = sizeof k; - DBT val = {}; val.data = p; val.ulen = (uint32_t) s; val.flags = DB_DBT_USERMEM; - int error = status_db->get(status_db, txn, &key, &val, 0); - if (error == 0) { - *sp = val.size; - } - return error; - } +// get the value for a given key in the status dictionary. +// copy the value to the supplied buffer. +// returns 0 if successful. +int read( + DB* status_db, + DB_TXN* txn, + HA_METADATA_KEY k, + void* p, + size_t s, + size_t* sp) { - // get the value for a given key in the status dictionary. put the value in a realloced buffer. - // returns 0 if successful. - int get_status_realloc(DB *status_db, DB_TXN *txn, HA_METADATA_KEY k, void **pp, size_t *sp) { - DBT key = {}; key.data = &k; key.size = sizeof k; - DBT val = {}; val.data = *pp; val.size = (uint32_t) *sp; val.flags = DB_DBT_REALLOC; - int error = status_db->get(status_db, txn, &key, &val, 0); - if (error == 0) { - *pp = val.data; - *sp = val.size; - } - return error; + DBT key = {}; + key.data = &k; + key.size = sizeof(k); + DBT val = {}; + val.data = p; + val.ulen = (uint32_t)s; + val.flags = DB_DBT_USERMEM; + int error = status_db->get(status_db, txn, &key, &val, 0); + if (error == 0) { + *sp = val.size; } + return error; +} - // write a key value pair into the status dictionary, overwriting the previous value if any. - // auto create a txn if necessary. - // returns 0 if successful. - int write_metadata(DB *status_db, void *key_data, uint key_size, void* val_data, uint val_size, DB_TXN *txn) { - DBT key = {}; key.data = key_data; key.size = key_size; - DBT value = {}; value.data = val_data; value.size = val_size; - int error = status_db->put(status_db, txn, &key, &value, 0); - return error; - } +// get the value for a given key in the status dictionary. +// put the value in a realloced buffer. +// returns 0 if successful. +int read_realloc( + DB* status_db, + DB_TXN* txn, + HA_METADATA_KEY k, + void** pp, + size_t* sp) { - // write a key value pair into the status dictionary, overwriting the previous value if any. - // the key must be a HA_METADATA_KEY. - // returns 0 if successful. - int write_to_status(DB *status_db, HA_METADATA_KEY curr_key_data, void *val, size_t val_size, DB_TXN *txn) { - return write_metadata(status_db, &curr_key_data, sizeof curr_key_data, val, val_size, txn); + DBT key = {}; + key.data = &k; + key.size = sizeof(k); + DBT val = {}; + val.data = *pp; + val.size = (uint32_t)*sp; + val.flags = DB_DBT_REALLOC; + int error = status_db->get(status_db, txn, &key, &val, 0); + if (error == 0) { + *pp = val.data; + *sp = val.size; } + return error; +} - // remove a key from the status dictionary. - // auto create a txn if necessary. - // returns 0 if successful. - int remove_metadata(DB *status_db, void *key_data, uint key_size, DB_TXN *txn) { - DBT key = {}; key.data = key_data; key.size = key_size; - int error = status_db->del(status_db, txn, &key, DB_DELETE_ANY); - return error; - } +// write a key value pair into the status dictionary, +// overwriting the previous value if any. +// auto create a txn if necessary. +// returns 0 if successful. +int write_low( + DB* status_db, + void* key_data, + uint key_size, + void* val_data, + uint val_size, + DB_TXN *txn) { - // remove a key from the status dictionary. - // the key must be a HA_METADATA_KEY - // returns 0 if successful. - int remove_from_status(DB *status_db, HA_METADATA_KEY curr_key_data, DB_TXN *txn) { - return remove_metadata(status_db, &curr_key_data, sizeof curr_key_data, txn); + DBT key = {}; + key.data = key_data; + key.size = key_size; + DBT value = {}; + value.data = val_data; + value.size = val_size; + int error = status_db->put(status_db, txn, &key, &value, 0); + return error; +} + +// write a key value pair into the status dictionary, +// overwriting the previous value if any. +// the key must be a HA_METADATA_KEY. +// returns 0 if successful. +int write( + DB* status_db, + HA_METADATA_KEY curr_key_data, + void* val, + size_t val_size, + DB_TXN* txn) { + + return + tokudb::metadata::write_low( + status_db, + &curr_key_data, + sizeof(curr_key_data), + val, + val_size, + txn); +} + +// remove a key from the status dictionary. +// auto create a txn if necessary. +// returns 0 if successful. +int remove_low( + DB* status_db, + void* key_data, + uint key_size, + DB_TXN* txn) { + + DBT key = {}; + key.data = key_data; + key.size = key_size; + int error = status_db->del(status_db, txn, &key, DB_DELETE_ANY); + return error; +} + +// remove a key from the status dictionary. +// the key must be a HA_METADATA_KEY +// returns 0 if successful. +int remove( + DB* status_db, + HA_METADATA_KEY curr_key_data, + DB_TXN* txn) { + return + tokudb::metadata::remove_low( + status_db, + &curr_key_data, + sizeof(curr_key_data), + txn); +} + +int close(DB** status_db_ptr) { + int error = 0; + DB* status_db = *status_db_ptr; + if (status_db) { + error = status_db->close(status_db, 0); + if (error == 0) + *status_db_ptr = NULL; } + return error; +} - int close_status(DB **status_db_ptr) { - int error = 0; - DB *status_db = *status_db_ptr; - if (status_db) { - error = status_db->close(status_db, 0); - if (error == 0) - *status_db_ptr = NULL; - } - return error; +int create( + DB_ENV* env, + DB** status_db_ptr, + const char* name, + DB_TXN* txn) { + + int error; + DB *status_db = NULL; + + error = db_create(&status_db, env, 0); + if (error == 0) { + error = status_db->set_pagesize(status_db, status_dict_pagesize); } + if (error == 0) { + error = + status_db->open( + status_db, + txn, + name, + NULL, + DB_BTREE, DB_CREATE | DB_EXCL, + 0); + } + if (error == 0) { + *status_db_ptr = status_db; + } else { + int r = tokudb::metadata::close(&status_db); + assert_always(r == 0); + } + return error; +} - int create_status(DB_ENV *env, DB **status_db_ptr, const char *name, DB_TXN *txn) { - int error; - DB *status_db = NULL; +int open( + DB_ENV* env, + DB** status_db_ptr, + const char* name, + DB_TXN* txn) { - error = db_create(&status_db, env, 0); - if (error == 0) { - error = status_db->set_pagesize(status_db, status_dict_pagesize); - } - if (error == 0) { - error = status_db->open(status_db, txn, name, NULL, DB_BTREE, DB_CREATE | DB_EXCL, 0); - } - if (error == 0) { - *status_db_ptr = status_db; - } else { - int r = close_status(&status_db); - assert(r == 0); + int error = 0; + DB* status_db = NULL; + error = db_create(&status_db, env, 0); + if (error == 0) { + error = + status_db->open( + status_db, + txn, + name, + NULL, + DB_BTREE, + DB_THREAD, + 0); + } + if (error == 0) { + uint32_t pagesize = 0; + error = status_db->get_pagesize(status_db, &pagesize); + if (error == 0 && pagesize > status_dict_pagesize) { + error = + status_db->change_pagesize(status_db, status_dict_pagesize); } - return error; } + if (error == 0) { + *status_db_ptr = status_db; + } else { + int r = tokudb::metadata::close(&status_db); + assert_always(r == 0); + } + return error; +} - int open_status(DB_ENV *env, DB **status_db_ptr, const char *name, DB_TXN *txn) { - int error = 0; - DB *status_db = NULL; - error = db_create(&status_db, env, 0); - if (error == 0) { - error = status_db->open(status_db, txn, name, NULL, DB_BTREE, DB_THREAD, 0); - } - if (error == 0) { - uint32_t pagesize = 0; - error = status_db->get_pagesize(status_db, &pagesize); - if (error == 0 && pagesize > status_dict_pagesize) { - error = status_db->change_pagesize(status_db, status_dict_pagesize); +int strip_frm_data(DB_ENV* env) { + int r; + DB_TXN* txn = NULL; + + fprintf(stderr, "TokuDB strip_frm_data : Beginning stripping process.\n"); + + r = db_env->txn_begin(env, NULL, &txn, 0); + assert_always(r == 0); + + DBC* c = NULL; + r = env->get_cursor_for_directory(env, txn, &c); + assert_always(r == 0); + + DBT key = { }; + key.flags = DB_DBT_REALLOC; + + DBT val = { }; + val.flags = DB_DBT_REALLOC; + while (1) { + r = c->c_get(c, &key, &val, DB_NEXT); + if (r == DB_NOTFOUND) + break; + const char* dname = (const char*) key.data; + const char* iname = (const char*) val.data; + assert_always(r == 0); + + if (strstr(iname, "_status_")) { + fprintf( + stderr, + "TokuDB strip_frm_data : stripping from dname=%s iname=%s\n", + dname, + iname); + + DB* status_db; + r = tokudb::metadata::open(db_env, &status_db, dname, txn); + if (r != 0) { + fprintf( + stderr, + "TokuDB strip_frm_data : unable to open status file %s, " + "error = %d\n", + dname, + r); + continue; } + + // GOL : this is a godawful hack. The inventors of this did not + // think it would be a good idea to use some kind of magic + // identifier k/v pair so that you can in fact tell a proper status + // file from any other file that might have the string _status_ in + // it. Out in ha_tokudb::create, when the status file is initially + // created, it is immediately populated with: + // uint hatoku_new_version=HA_TOKU_VERSION=4 and + // uint hatoku_capabilities=HA_TOKU_CAP=0 + // Since I can't count on the fact that these values are/were + // _always_ 4 and 0, I can count on the fact that they _must_ be + // there and the _must_ be sizeof(uint). That will at least give us + // a much better idea that these are in fact status files. + void* p = NULL; + size_t sz; + r = + tokudb::metadata::read_realloc( + status_db, + txn, + hatoku_new_version, + &p, + &sz); + if (r != 0) { + fprintf( + stderr, + "TokuDB strip_frm_data : does not look like a real TokuDB " + "status file, new_verion is missing, leaving alone %s \n", + dname); + + r = tokudb::metadata::close(&status_db); + assert_always(r == 0); + continue; + } else if (sz != sizeof(uint)) { + fprintf( + stderr, + "TokuDB strip_frm_data : does not look like a real TokuDB " + "status file, new_verion is the wrong size, " + "leaving alone %s \n", + dname); + + tokudb::memory::free(p); + r = tokudb::metadata::close(&status_db); + assert_always(r == 0); + continue; + } + tokudb::memory::free(p); + p = NULL; + + r = + tokudb::metadata::read_realloc( + status_db, + txn, + hatoku_capabilities, + &p, + &sz); + if (r != 0) { + fprintf( + stderr, + "TokuDB strip_frm_data : does not look like a real TokuDB " + "status file, capabilities is missing, leaving alone %s \n", + dname); + + r = tokudb::metadata::close(&status_db); + assert_always(r == 0); + continue; + } else if (sz != sizeof(uint)) { + fprintf( + stderr, + "TokuDB strip_frm_data : does not look like a real TokuDB " + "status file, capabilities is the wrong size, " + "leaving alone %s \n", + dname); + + tokudb::memory::free(p); + r = tokudb::metadata::close(&status_db); + assert_always(r == 0); + continue; + } + tokudb::memory::free(p); + + // OK, st this point, it is probably a status file, not 100% but + // it looks like it :( + r = tokudb::metadata::remove(status_db, hatoku_frm_data, txn); + if (r != 0) { + fprintf( + stderr, + "TokuDB strip_frm_data : unable to find/strip frm data " + "from status file %s, error = %d\n", + dname, + r); + } + + r = tokudb::metadata::close(&status_db); + assert_always(r == 0); } - if (error == 0) { - *status_db_ptr = status_db; - } else { - int r = close_status(&status_db); - assert(r == 0); - } - return error; } + tokudb::memory::free(key.data); + tokudb::memory::free(val.data); + + fprintf( + stderr, + "TokuDB strip_frm_data : Stripping process complete, beginning " + "commit, this may take some time.\n"); + + r = c->c_close(c); + assert_always(r == 0); + + r = txn->commit(txn, 0); + assert_always(r == 0); + + fprintf( + stderr, + "TokuDB strip_frm_data : Commit complete, resuming server init " + "process."); + + return 0; } +} // namespace metadata +} // namespace tokudb #endif diff --git a/storage/tokudb/tokudb_sysvars.cc b/storage/tokudb/tokudb_sysvars.cc new file mode 100644 index 0000000000000..168fb0cc647e2 --- /dev/null +++ b/storage/tokudb/tokudb_sysvars.cc @@ -0,0 +1,1099 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "hatoku_hton.h" + +namespace tokudb { +namespace sysvars { + +//****************************************************************************** +// global variables +//****************************************************************************** +#ifdef TOKUDB_VERSION +#define tokudb_stringify_2(x) #x +#define tokudb_stringify(x) tokudb_stringify_2(x) +#define TOKUDB_VERSION_STR tokudb_stringify(TOKUDB_VERSION) +#else +#define TOKUDB_VERSION_STR NULL +#endif + +ulonglong cache_size = 0; +uint cachetable_pool_threads = 0; +int cardinality_scale_percent = 0; +my_bool checkpoint_on_flush_logs = FALSE; +uint checkpoint_pool_threads = 0; +uint checkpointing_period = 0; +ulong cleaner_iterations = 0; +ulong cleaner_period = 0; +uint client_pool_threads = 0; +my_bool compress_buffers_before_eviction = TRUE; +char* data_dir = NULL; +ulong debug = 0; +#if TOKUDB_DEBUG +// used to control background job manager +my_bool debug_pause_background_job_manager = FALSE; +#endif +my_bool directio = FALSE; +my_bool enable_partial_eviction = TRUE; +int fs_reserve_percent = 0; +uint fsync_log_period = 0; +char* log_dir = NULL; +ulonglong max_lock_memory = 0; +uint read_status_frequency = 0; +my_bool strip_frm_data = FALSE; +char* tmp_dir = NULL; +uint write_status_frequency = 0; +char* version = (char*) TOKUDB_VERSION_STR; + +// file system reserve as a percentage of total disk space +#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL +char* gdb_path = NULL; +my_bool gdb_on_fatal = FALSE; +#endif + +#if TOKUDB_CHECK_JEMALLOC +uint check_jemalloc = 0; +#endif + +static MYSQL_SYSVAR_ULONGLONG( + cache_size, + cache_size, + PLUGIN_VAR_READONLY, + "cache table size", + NULL, + NULL, + 0, + 0, + ~0ULL, + 0); + +static MYSQL_SYSVAR_UINT( + cachetable_pool_threads, + cachetable_pool_threads, + PLUGIN_VAR_READONLY, + "cachetable ops thread pool size", + NULL, + NULL, + 0, + 0, + 1024, + 0); + +static MYSQL_SYSVAR_INT( + cardinality_scale_percent, + cardinality_scale_percent, + 0, + "index cardinality scale percentage", + NULL, + NULL, + 50, + 0, + 100, + 0); + +static MYSQL_SYSVAR_BOOL( + checkpoint_on_flush_logs, + checkpoint_on_flush_logs, + 0, + "checkpoint on flush logs", + NULL, + NULL, + FALSE); + +static MYSQL_SYSVAR_UINT( + checkpoint_pool_threads, + checkpoint_pool_threads, + PLUGIN_VAR_READONLY, + "checkpoint ops thread pool size", + NULL, + NULL, + 0, + 0, + 1024, + 0); + +static void checkpointing_period_update( + THD* thd, + st_mysql_sys_var* sys_var, + void* var, + const void* save) { + + uint* cp = (uint*)var; + *cp = *(const uint*)save; + int r = db_env->checkpointing_set_period(db_env, *cp); + assert(r == 0); +} + +static MYSQL_SYSVAR_UINT( + checkpointing_period, + checkpointing_period, + 0, + "checkpointing period", + NULL, + checkpointing_period_update, + 60, + 0, + ~0U, + 0); + +static void cleaner_iterations_update( + THD* thd, + st_mysql_sys_var* sys_var, + void* var, + const void* save) { + + ulong* ci = (ulong*)var; + *ci = *(const ulong*)save; + int r = db_env->cleaner_set_iterations(db_env, *ci); + assert(r == 0); +} + +static MYSQL_SYSVAR_ULONG( + cleaner_iterations, + cleaner_iterations, + 0, + "cleaner_iterations", + NULL, + cleaner_iterations_update, + DEFAULT_TOKUDB_CLEANER_ITERATIONS, + 0, + ~0UL, + 0); + +static void cleaner_period_update( + THD* thd, + st_mysql_sys_var* sys_var, + void* var, + const void * save) { + + ulong* cp = (ulong*)var; + *cp = *(const ulong*)save; + int r = db_env->cleaner_set_period(db_env, *cp); + assert(r == 0); +} + +static MYSQL_SYSVAR_ULONG( + cleaner_period, + cleaner_period, + 0, + "cleaner_period", + NULL, + cleaner_period_update, + DEFAULT_TOKUDB_CLEANER_PERIOD, + 0, + ~0UL, + 0); + +static MYSQL_SYSVAR_UINT( + client_pool_threads, + client_pool_threads, + PLUGIN_VAR_READONLY, + "client ops thread pool size", + NULL, + NULL, + 0, + 0, + 1024, + 0); + +static MYSQL_SYSVAR_BOOL( + compress_buffers_before_eviction, + compress_buffers_before_eviction, + PLUGIN_VAR_READONLY, + "enable in-memory buffer compression before partial eviction", + NULL, + NULL, + TRUE); + +static MYSQL_SYSVAR_STR( + data_dir, + data_dir, + PLUGIN_VAR_READONLY, + "data directory", + NULL, + NULL, + NULL); + +static MYSQL_SYSVAR_ULONG( + debug, + debug, + 0, + "plugin debug mask", + NULL, + NULL, + 0, + 0, + ~0UL, + 0); + +#if TOKUDB_DEBUG +static MYSQL_SYSVAR_BOOL( + debug_pause_background_job_manager, + debug_pause_background_job_manager, + 0, + "debug : pause the background job manager", + NULL, + NULL, + FALSE); +#endif // TOKUDB_DEBUG + +static MYSQL_SYSVAR_BOOL( + directio, + directio, + PLUGIN_VAR_READONLY, "enable direct i/o ", + NULL, + NULL, + FALSE); + +static void enable_partial_eviction_update( + THD* thd, + st_mysql_sys_var* sys_var, + void* var, + const void* save) { + + my_bool* epe = (my_bool*)var; + *epe = *(const my_bool*)save; + int r = db_env->evictor_set_enable_partial_eviction(db_env, *epe); + assert(r == 0); +} + +static MYSQL_SYSVAR_BOOL( + enable_partial_eviction, + enable_partial_eviction, + 0, + "enable partial node eviction", + NULL, + enable_partial_eviction_update, + TRUE); + +static MYSQL_SYSVAR_INT( + fs_reserve_percent, + fs_reserve_percent, + PLUGIN_VAR_READONLY, + "file system space reserve (percent free required)", + NULL, + NULL, + 5, + 0, + 100, + 0); + +static void fsync_log_period_update( + THD* thd, + st_mysql_sys_var* sys_var, + void* var, + const void* save) { + + uint* flp = (uint*)var; + *flp = *(const uint*)save; + db_env->change_fsync_log_period(db_env, *flp); +} + +static MYSQL_SYSVAR_UINT( + fsync_log_period, + fsync_log_period, + 0, + "fsync log period", + NULL, + fsync_log_period_update, + 0, + 0, + ~0U, + 0); + +static MYSQL_SYSVAR_STR( + log_dir, + log_dir, + PLUGIN_VAR_READONLY, + "log directory", + NULL, + NULL, + NULL); + +static MYSQL_SYSVAR_ULONGLONG( + max_lock_memory, + max_lock_memory, + PLUGIN_VAR_READONLY, + "max memory for locks", + NULL, + NULL, + 0, + 0, + ~0ULL, + 0); + +static MYSQL_SYSVAR_UINT( + read_status_frequency, + read_status_frequency, + 0, + "frequency that show processlist updates status of reads", + NULL, + NULL, + 10000, + 0, + ~0U, + 0); + +static MYSQL_SYSVAR_BOOL( + strip_frm_data, + strip_frm_data, + PLUGIN_VAR_READONLY, + "strip .frm data from metadata file(s)", + NULL, + NULL, + FALSE); + +static MYSQL_SYSVAR_STR( + tmp_dir, + tmp_dir, + PLUGIN_VAR_READONLY, + "directory to use for temporary files", + NULL, + NULL, + NULL); + +static MYSQL_SYSVAR_STR( + version, + version, + PLUGIN_VAR_READONLY, + "plugin version", + NULL, + NULL, + NULL); + +static MYSQL_SYSVAR_UINT( + write_status_frequency, + write_status_frequency, + 0, + "frequency that show processlist updates status of writes", + NULL, + NULL, + 1000, + 0, + ~0U, + 0); + +#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL +static MYSQL_SYSVAR_STR( + gdb_path, + gdb_path, + PLUGIN_VAR_READONLY|PLUGIN_VAR_RQCMDARG, + "path to gdb for extra debug info on fatal signal", + NULL, + NULL, + "/usr/bin/gdb"); + +static MYSQL_SYSVAR_BOOL( + gdb_on_fatal, + gdb_on_fatal, + 0, + "enable gdb debug info on fatal signal", + NULL, + NULL, + true); +#endif + +#if TOKUDB_CHECK_JEMALLOC +static MYSQL_SYSVAR_UINT( + check_jemalloc, + check_jemalloc, + 0, + "check if jemalloc is linked", + NULL, + NULL, + 1, + 0, + 1, + 0); +#endif + + +//****************************************************************************** +// session variables +//****************************************************************************** +static MYSQL_THDVAR_BOOL( + alter_print_error, + 0, + "print errors for alter table operations", + NULL, + NULL, + false); + +static MYSQL_THDVAR_DOUBLE( + analyze_delete_fraction, + 0, + "fraction of rows allowed to be deleted", + NULL, + NULL, + 1.0, + 0, + 1.0, + 1); + +static MYSQL_THDVAR_BOOL( + analyze_in_background, + 0, + "dispatch ANALYZE TABLE to background job.", + NULL, + NULL, + false); + +const char* srv_analyze_mode_names[] = { + "TOKUDB_ANALYZE_STANDARD", + "TOKUDB_ANALYZE_RECOUNT_ROWS", + "TOKUDB_ANALYZE_CANCEL", + NullS +}; + +static TYPELIB tokudb_analyze_mode_typelib = { + array_elements(srv_analyze_mode_names) - 1, + "tokudb_analyze_mode_typelib", + srv_analyze_mode_names, + NULL +}; + +static MYSQL_THDVAR_ENUM(analyze_mode, + PLUGIN_VAR_RQCMDARG, + "Controls the function of ANALYZE TABLE. Possible values are: " + "TOKUDB_ANALYZE_STANDARD perform standard table analysis (default); " + "TOKUDB_ANALYZE_RECOUNT_ROWS perform logical recount of table rows;" + "TOKUDB_ANALYZE_CANCEL terminate and cancel all scheduled background jobs " + "for a table", + NULL, + NULL, + TOKUDB_ANALYZE_STANDARD, + &tokudb_analyze_mode_typelib); + +static MYSQL_THDVAR_ULONGLONG( + analyze_throttle, + 0, + "analyze throttle (keys)", + NULL, + NULL, + 0, + 0, + ~0U, + 1); + +static MYSQL_THDVAR_UINT( + analyze_time, + 0, + "analyze time (seconds)", + NULL, + NULL, + 5, + 0, + ~0U, + 1); + +static MYSQL_THDVAR_ULONGLONG( + auto_analyze, + 0, + "auto analyze threshold (percent)", + NULL, + NULL, + 0, + 0, + ~0U, + 1); + +static MYSQL_THDVAR_UINT( + block_size, + 0, + "fractal tree block size", + NULL, + NULL, + 4<<20, + 4096, + ~0U, + 1); + +static MYSQL_THDVAR_BOOL( + bulk_fetch, + PLUGIN_VAR_THDLOCAL, + "enable bulk fetch", + NULL, + NULL, + true); + +static void checkpoint_lock_update( + THD* thd, + st_mysql_sys_var* var, + void* var_ptr, + const void* save) { + + my_bool* val = (my_bool*)var_ptr; + *val= *(my_bool*)save ? true : false; + if (*val) { + tokudb_checkpoint_lock(thd); + } else { + tokudb_checkpoint_unlock(thd); + } +} + +static MYSQL_THDVAR_BOOL( + checkpoint_lock, + 0, + "checkpoint lock", + NULL, + checkpoint_lock_update, + false); + +static MYSQL_THDVAR_BOOL( + commit_sync, + PLUGIN_VAR_THDLOCAL, + "sync on txn commit", + NULL, + NULL, + true); + +static MYSQL_THDVAR_BOOL( + create_index_online, + 0, + "if on, create index done online", + NULL, + NULL, + true); + +static MYSQL_THDVAR_BOOL( + disable_hot_alter, + 0, + "if on, hot alter table is disabled", + NULL, + NULL, + false); + +static MYSQL_THDVAR_BOOL( + disable_prefetching, + 0, + "if on, prefetching disabled", + NULL, + NULL, + false); + +static MYSQL_THDVAR_BOOL( + disable_slow_alter, + 0, + "if on, alter tables that require copy are disabled", + NULL, + NULL, + false); + +static const char *tokudb_empty_scan_names[] = { + "disabled", + "lr", + "rl", + NullS +}; + +static TYPELIB tokudb_empty_scan_typelib = { + array_elements(tokudb_empty_scan_names) - 1, + "tokudb_empty_scan_typelib", + tokudb_empty_scan_names, + NULL +}; + +static MYSQL_THDVAR_ENUM( + empty_scan, + PLUGIN_VAR_OPCMDARG, + "algorithm to check if the table is empty when opened", + NULL, + NULL, + TOKUDB_EMPTY_SCAN_RL, + &tokudb_empty_scan_typelib); + +static MYSQL_THDVAR_UINT( + fanout, + 0, + "fractal tree fanout", + NULL, + NULL, + 16, + 2, + 16*1024, + 1); + +static MYSQL_THDVAR_BOOL( + hide_default_row_format, + 0, + "hide the default row format", + NULL, + NULL, + true); + +static MYSQL_THDVAR_ULONGLONG( + killed_time, + 0, + "killed time", + NULL, + NULL, + DEFAULT_TOKUDB_KILLED_TIME, + 0, + ~0ULL, + 1); + +static MYSQL_THDVAR_STR( + last_lock_timeout, + PLUGIN_VAR_MEMALLOC, + "last lock timeout", + NULL, + NULL, + NULL); + +static MYSQL_THDVAR_BOOL( + load_save_space, + 0, + "compress intermediate bulk loader files to save space", + NULL, + NULL, + true); + +static MYSQL_THDVAR_ULONGLONG( + loader_memory_size, + 0, + "loader memory size", + NULL, + NULL, + 100*1000*1000, + 0, + ~0ULL, + 1); + +static MYSQL_THDVAR_ULONGLONG( + lock_timeout, + 0, + "lock timeout", + NULL, + NULL, + DEFAULT_TOKUDB_LOCK_TIMEOUT, + 0, + ~0ULL, + 1); + +static MYSQL_THDVAR_UINT( + lock_timeout_debug, + 0, + "lock timeout debug", + NULL, + NULL, + 1, + 0, + ~0U, + 1); + +static MYSQL_THDVAR_DOUBLE( + optimize_index_fraction, + 0, + "optimize index fraction (default 1.0 all)", + NULL, + NULL, + 1.0, + 0, + 1.0, + 1); + +static MYSQL_THDVAR_STR( + optimize_index_name, + PLUGIN_VAR_THDLOCAL + PLUGIN_VAR_MEMALLOC, + "optimize index name (default all indexes)", + NULL, + NULL, + NULL); + +static MYSQL_THDVAR_ULONGLONG( + optimize_throttle, + 0, + "optimize throttle (default no throttle)", + NULL, + NULL, + 0, + 0, + ~0ULL, + 1); + +static MYSQL_THDVAR_UINT( + pk_insert_mode, + 0, + "set the primary key insert mode", + NULL, + NULL, + 1, + 0, + 2, + 1); + +static MYSQL_THDVAR_BOOL( + prelock_empty, + 0, + "prelock empty table", + NULL, + NULL, + true); + +static MYSQL_THDVAR_UINT( + read_block_size, + 0, + "fractal tree read block size", + NULL, + NULL, + 64*1024, + 4096, + ~0U, + 1); + +static MYSQL_THDVAR_UINT( + read_buf_size, + 0, + "range query read buffer size", + NULL, + NULL, + 128*1024, + 0, + 1*1024*1024, + 1); + +static const char *tokudb_row_format_names[] = { + "tokudb_uncompressed", + "tokudb_zlib", + "tokudb_snappy", + "tokudb_quicklz", + "tokudb_lzma", + "tokudb_fast", + "tokudb_small", + "tokudb_default", + NullS +}; + +static TYPELIB tokudb_row_format_typelib = { + array_elements(tokudb_row_format_names) - 1, + "tokudb_row_format_typelib", + tokudb_row_format_names, + NULL +}; + +static MYSQL_THDVAR_ENUM( + row_format, + PLUGIN_VAR_OPCMDARG, + "Specifies the compression method for a table created during this session. " + "Possible values are TOKUDB_UNCOMPRESSED, TOKUDB_ZLIB, TOKUDB_SNAPPY, " + "TOKUDB_QUICKLZ, TOKUDB_LZMA, TOKUDB_FAST, TOKUDB_SMALL and TOKUDB_DEFAULT", + NULL, + NULL, + SRV_ROW_FORMAT_ZLIB, + &tokudb_row_format_typelib); + +static MYSQL_THDVAR_BOOL( + rpl_check_readonly, + PLUGIN_VAR_THDLOCAL, + "check if the slave is read only", + NULL, + NULL, + true); + +static MYSQL_THDVAR_BOOL( + rpl_lookup_rows, + PLUGIN_VAR_THDLOCAL, + "lookup a row on rpl slave", + NULL, + NULL, + true); + +static MYSQL_THDVAR_ULONGLONG( + rpl_lookup_rows_delay, + PLUGIN_VAR_THDLOCAL, + "time in milliseconds to add to lookups on replication slave", + NULL, + NULL, + 0, + 0, + ~0ULL, + 1); + +static MYSQL_THDVAR_BOOL( + rpl_unique_checks, + PLUGIN_VAR_THDLOCAL, + "enable unique checks on replication slave", + NULL, + NULL, + true); + +static MYSQL_THDVAR_ULONGLONG( + rpl_unique_checks_delay, + PLUGIN_VAR_THDLOCAL, + "time in milliseconds to add to unique checks test on replication slave", + NULL, + NULL, + 0, + 0, + ~0ULL, + 1); + +#if TOKU_INCLUDE_UPSERT +static MYSQL_THDVAR_BOOL( + disable_slow_update, + PLUGIN_VAR_THDLOCAL, + "disable slow update", + NULL, + NULL, + false); + +static MYSQL_THDVAR_BOOL( + disable_slow_upsert, + PLUGIN_VAR_THDLOCAL, + "disable slow upsert", + NULL, + NULL, + false); +#endif + +#if TOKU_INCLUDE_XA +static MYSQL_THDVAR_BOOL( + support_xa, + PLUGIN_VAR_OPCMDARG, + "Enable TokuDB support for the XA two-phase commit", + NULL, + NULL, + true); +#endif + + + +//****************************************************************************** +// all system variables +//****************************************************************************** +st_mysql_sys_var* system_variables[] = { + // global vars + MYSQL_SYSVAR(cache_size), + MYSQL_SYSVAR(checkpoint_on_flush_logs), + MYSQL_SYSVAR(cachetable_pool_threads), + MYSQL_SYSVAR(cardinality_scale_percent), + MYSQL_SYSVAR(checkpoint_pool_threads), + MYSQL_SYSVAR(checkpointing_period), + MYSQL_SYSVAR(cleaner_iterations), + MYSQL_SYSVAR(cleaner_period), + MYSQL_SYSVAR(client_pool_threads), + MYSQL_SYSVAR(compress_buffers_before_eviction), + MYSQL_SYSVAR(data_dir), + MYSQL_SYSVAR(debug), + MYSQL_SYSVAR(directio), + MYSQL_SYSVAR(enable_partial_eviction), + MYSQL_SYSVAR(fs_reserve_percent), + MYSQL_SYSVAR(fsync_log_period), + MYSQL_SYSVAR(log_dir), + MYSQL_SYSVAR(max_lock_memory), + MYSQL_SYSVAR(read_status_frequency), + MYSQL_SYSVAR(strip_frm_data), + MYSQL_SYSVAR(tmp_dir), + MYSQL_SYSVAR(version), + MYSQL_SYSVAR(write_status_frequency), + +#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL + MYSQL_SYSVAR(gdb_path), + MYSQL_SYSVAR(gdb_on_fatal), +#endif + +#if TOKUDB_CHECK_JEMALLOC + MYSQL_SYSVAR(check_jemalloc), +#endif + + // session vars + MYSQL_SYSVAR(alter_print_error), + MYSQL_SYSVAR(analyze_delete_fraction), + MYSQL_SYSVAR(analyze_in_background), + MYSQL_SYSVAR(analyze_mode), + MYSQL_SYSVAR(analyze_throttle), + MYSQL_SYSVAR(analyze_time), + MYSQL_SYSVAR(auto_analyze), + MYSQL_SYSVAR(block_size), + MYSQL_SYSVAR(bulk_fetch), + MYSQL_SYSVAR(checkpoint_lock), + MYSQL_SYSVAR(commit_sync), + MYSQL_SYSVAR(create_index_online), + MYSQL_SYSVAR(disable_hot_alter), + MYSQL_SYSVAR(disable_prefetching), + MYSQL_SYSVAR(disable_slow_alter), + MYSQL_SYSVAR(empty_scan), + MYSQL_SYSVAR(fanout), + MYSQL_SYSVAR(hide_default_row_format), + MYSQL_SYSVAR(killed_time), + MYSQL_SYSVAR(last_lock_timeout), + MYSQL_SYSVAR(load_save_space), + MYSQL_SYSVAR(loader_memory_size), + MYSQL_SYSVAR(lock_timeout), + MYSQL_SYSVAR(lock_timeout_debug), + MYSQL_SYSVAR(optimize_index_fraction), + MYSQL_SYSVAR(optimize_index_name), + MYSQL_SYSVAR(optimize_throttle), + MYSQL_SYSVAR(pk_insert_mode), + MYSQL_SYSVAR(prelock_empty), + MYSQL_SYSVAR(read_block_size), + MYSQL_SYSVAR(read_buf_size), + MYSQL_SYSVAR(row_format), + MYSQL_SYSVAR(rpl_check_readonly), + MYSQL_SYSVAR(rpl_lookup_rows), + MYSQL_SYSVAR(rpl_lookup_rows_delay), + MYSQL_SYSVAR(rpl_unique_checks), + MYSQL_SYSVAR(rpl_unique_checks_delay), + +#if TOKU_INCLUDE_UPSERT + MYSQL_SYSVAR(disable_slow_update), + MYSQL_SYSVAR(disable_slow_upsert), +#endif + +#if TOKU_INCLUDE_XA + MYSQL_SYSVAR(support_xa), +#endif + +#if TOKUDB_DEBUG + MYSQL_SYSVAR(debug_pause_background_job_manager), +#endif // TOKUDB_DEBUG + + NULL +}; + +my_bool alter_print_error(THD* thd) { + return (THDVAR(thd, alter_print_error) != 0); +} +double analyze_delete_fraction(THD* thd) { + return THDVAR(thd, analyze_delete_fraction); +} +my_bool analyze_in_background(THD* thd) { + return (THDVAR(thd, analyze_in_background) != 0); +} +analyze_mode_t analyze_mode(THD* thd) { + return (analyze_mode_t ) THDVAR(thd, analyze_mode); +} +ulonglong analyze_throttle(THD* thd) { + return THDVAR(thd, analyze_throttle); +} +ulonglong analyze_time(THD* thd) { + return THDVAR(thd, analyze_time); +} +ulonglong auto_analyze(THD* thd) { + return THDVAR(thd, auto_analyze); +} +my_bool bulk_fetch(THD* thd) { + return (THDVAR(thd, bulk_fetch) != 0); +} +uint block_size(THD* thd) { + return THDVAR(thd, block_size); +} +my_bool commit_sync(THD* thd) { + return (THDVAR(thd, commit_sync) != 0); +} +my_bool create_index_online(THD* thd) { + return (THDVAR(thd, create_index_online) != 0); +} +my_bool disable_hot_alter(THD* thd) { + return (THDVAR(thd, disable_hot_alter) != 0); +} +my_bool disable_prefetching(THD* thd) { + return (THDVAR(thd, disable_prefetching) != 0); +} +my_bool disable_slow_alter(THD* thd) { + return (THDVAR(thd, disable_slow_alter) != 0); +} +my_bool disable_slow_update(THD* thd) { + return (THDVAR(thd, disable_slow_update) != 0); +} +my_bool disable_slow_upsert(THD* thd) { + return (THDVAR(thd, disable_slow_upsert) != 0); +} +empty_scan_mode_t empty_scan(THD* thd) { + return (empty_scan_mode_t)THDVAR(thd, empty_scan); +} +uint fanout(THD* thd) { + return THDVAR(thd, fanout); +} +my_bool hide_default_row_format(THD* thd) { + return (THDVAR(thd, hide_default_row_format) != 0); +} +ulonglong killed_time(THD* thd) { + return THDVAR(thd, killed_time); +} +char* last_lock_timeout(THD* thd) { + return THDVAR(thd, last_lock_timeout); +} +void set_last_lock_timeout(THD* thd, char* last) { + THDVAR(thd, last_lock_timeout) = last; +} +my_bool load_save_space(THD* thd) { + return (THDVAR(thd, load_save_space) != 0); +} +ulonglong loader_memory_size(THD* thd) { + return THDVAR(thd, loader_memory_size); +} +ulonglong lock_timeout(THD* thd) { + return THDVAR(thd, lock_timeout); +} +uint lock_timeout_debug(THD* thd) { + return THDVAR(thd, lock_timeout_debug); +} +double optimize_index_fraction(THD* thd) { + return THDVAR(thd, optimize_index_fraction); +} +const char* optimize_index_name(THD* thd) { + return THDVAR(thd, optimize_index_name); +} +ulonglong optimize_throttle(THD* thd) { + return THDVAR(thd, optimize_throttle); +} +uint pk_insert_mode(THD* thd) { + return THDVAR(thd, pk_insert_mode); +} +my_bool prelock_empty(THD* thd) { + return (THDVAR(thd, prelock_empty) != 0); +} +uint read_block_size(THD* thd) { + return THDVAR(thd, read_block_size); +} +uint read_buf_size(THD* thd) { + return THDVAR(thd, read_buf_size); +} +row_format_t row_format(THD *thd) { + return (row_format_t) THDVAR(thd, row_format); +} +my_bool rpl_check_readonly(THD* thd) { + return (THDVAR(thd, rpl_check_readonly) != 0); +} +my_bool rpl_lookup_rows(THD* thd) { + return (THDVAR(thd, rpl_lookup_rows) != 0); +} +ulonglong rpl_lookup_rows_delay(THD* thd) { + return THDVAR(thd, rpl_lookup_rows_delay); +} +my_bool rpl_unique_checks(THD* thd) { + return (THDVAR(thd, rpl_unique_checks) != 0); +} +ulonglong rpl_unique_checks_delay(THD* thd) { + return THDVAR(thd, rpl_unique_checks_delay); +} +my_bool support_xa(THD* thd) { + return (THDVAR(thd, support_xa) != 0); +} + +} // namespace sysvars +} // namespace tokudb diff --git a/storage/tokudb/tokudb_sysvars.h b/storage/tokudb/tokudb_sysvars.h new file mode 100644 index 0000000000000..a7490c7b47374 --- /dev/null +++ b/storage/tokudb/tokudb_sysvars.h @@ -0,0 +1,147 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_SYSVARS_H +#define _TOKUDB_SYSVARS_H + +namespace tokudb { +namespace sysvars { + +enum analyze_mode_t { + TOKUDB_ANALYZE_STANDARD = 0, + TOKUDB_ANALYZE_RECOUNT_ROWS = 1, + TOKUDB_ANALYZE_CANCEL = 2 +}; + +enum empty_scan_mode_t { + TOKUDB_EMPTY_SCAN_DISABLED = 0, + TOKUDB_EMPTY_SCAN_LR = 1, + TOKUDB_EMPTY_SCAN_RL = 2, +}; + +enum row_format_t { + SRV_ROW_FORMAT_UNCOMPRESSED = 0, + SRV_ROW_FORMAT_ZLIB = 1, + SRV_ROW_FORMAT_SNAPPY = 2, + SRV_ROW_FORMAT_QUICKLZ = 3, + SRV_ROW_FORMAT_LZMA = 4, + SRV_ROW_FORMAT_FAST = 5, + SRV_ROW_FORMAT_SMALL = 6, + SRV_ROW_FORMAT_DEFAULT = 7 +}; + +#define DEFAULT_TOKUDB_CLEANER_ITERATIONS 5 +#define DEFAULT_TOKUDB_CLEANER_PERIOD 1 +#define DEFAULT_TOKUDB_KILLED_TIME 4000 // milliseconds +#define DEFAULT_TOKUDB_LOCK_TIMEOUT 4000 // milliseconds + + +// globals +extern ulonglong cache_size; +extern uint cachetable_pool_threads; +extern int cardinality_scale_percent; +extern my_bool checkpoint_on_flush_logs; +extern uint checkpoint_pool_threads; +extern uint checkpointing_period; +extern ulong cleaner_iterations; +extern ulong cleaner_period; +extern uint client_pool_threads; +extern my_bool compress_buffers_before_eviction; +extern char* data_dir; +extern ulong debug; +extern my_bool directio; +extern my_bool enable_partial_eviction; +extern int fs_reserve_percent; +extern uint fsync_log_period; +extern char* log_dir; +extern ulonglong max_lock_memory; +extern uint read_status_frequency; +extern my_bool strip_frm_data; +extern char* tmp_dir; +extern uint write_status_frequency; +extern char* version; + +#if TOKU_INCLUDE_HANDLERTON_HANDLE_FATAL_SIGNAL +extern char* gdb_path; +extern my_bool gdb_on_fatal; +#endif + +#if TOKUDB_CHECK_JEMALLOC +extern uint check_jemalloc; +#endif + +#if TOKUDB_DEBUG +// used to control background job manager +extern my_bool debug_pause_background_job_manager; +#endif // TOKUDB_DEBUG + +// session/thread +my_bool alter_print_error(THD* thd); +double analyze_delete_fraction(THD* thd); +my_bool analyze_in_background(THD* thd); +analyze_mode_t analyze_mode(THD* thd); +ulonglong analyze_throttle(THD* thd); +ulonglong analyze_time(THD* thd); +ulonglong auto_analyze(THD* thd); +uint block_size(THD* thd); +my_bool bulk_fetch(THD* thd); +my_bool commit_sync(THD* thd); +my_bool create_index_online(THD* thd); +my_bool disable_hot_alter(THD* thd); +my_bool disable_prefetching(THD* thd); +my_bool disable_slow_alter(THD* thd); +my_bool disable_slow_update(THD* thd); +my_bool disable_slow_upsert(THD* thd); +empty_scan_mode_t empty_scan(THD* thd); +uint fanout(THD* thd); +my_bool hide_default_row_format(THD* thd); +ulonglong killed_time(THD* thd); +my_bool load_save_space(THD* thd); +char* last_lock_timeout(THD* thd); +void set_last_lock_timeout(THD* thd, char* last); +ulonglong loader_memory_size(THD* thd); +ulonglong lock_timeout(THD* thd); +uint lock_timeout_debug(THD* thd); +double optimize_index_fraction(THD* thd); +const char* optimize_index_name(THD* thd); +ulonglong optimize_throttle(THD* thd); +uint pk_insert_mode(THD* thd); +my_bool prelock_empty(THD* thd); +uint read_block_size(THD* thd); +uint read_buf_size(THD* thd); +row_format_t row_format(THD *thd); +my_bool rpl_check_readonly(THD* thd); +my_bool rpl_lookup_rows(THD* thd); +ulonglong rpl_lookup_rows_delay(THD* thd); +my_bool rpl_unique_checks(THD* thd); +ulonglong rpl_unique_checks_delay(THD* thd); +my_bool support_xa(THD* thd); + +extern st_mysql_sys_var* system_variables[]; + +} // namespace sysvars +} // namespace tokudb + +#endif // _TOKUDB_SYSVARS_H diff --git a/storage/tokudb/tokudb_thread.cc b/storage/tokudb/tokudb_thread.cc new file mode 100644 index 0000000000000..f27e803a0655f --- /dev/null +++ b/storage/tokudb/tokudb_thread.cc @@ -0,0 +1,35 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#include "tokudb_thread.h" + +namespace tokudb { +namespace thread { + +pthread_t mutex_t::_null_owner = 0; + +} // namespace thread +} // namespace tokudb diff --git a/storage/tokudb/tokudb_thread.h b/storage/tokudb/tokudb_thread.h new file mode 100644 index 0000000000000..ab1633a16cab9 --- /dev/null +++ b/storage/tokudb/tokudb_thread.h @@ -0,0 +1,548 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_SYNC_H +#define _TOKUDB_SYNC_H + +#include "hatoku_defines.h" +#include "tokudb_debug.h" +#include "tokudb_time.h" + +namespace tokudb { +namespace thread { + +uint my_tid(void); + +// Your basic mutex +class mutex_t { +public: + mutex_t(void); + ~mutex_t(void); + + void lock(void); + int lock(ulonglong microseconds); + void unlock(void); +#ifdef TOKUDB_DEBUG + bool is_owned_by_me(void) const; +#endif +private: + static pthread_t _null_owner; + pthread_mutex_t _mutex; +#ifdef TOKUDB_DEBUG + uint _owners; + pthread_t _owner; +#endif +}; + +// Simple read write lock +class rwlock_t { +public: + rwlock_t(void); + ~rwlock_t(void); + + void lock_read(void); + int lock_read(ulonglong microseconds); + void lock_write(void); + int lock_write(ulonglong microseconds); + void unlock(void); + +private: + rwlock_t(const rwlock_t&); + rwlock_t& operator=(const rwlock_t&); + + pthread_rwlock_t _rwlock; +}; + +// Simple event signal/wait class +class event_t { +public: + // create_signalled - create the event in a signalled state + // manual_reset - create an event that must be manually reset + // after signaling + event_t( + bool create_signalled = false, + bool manual_reset = false); + ~event_t(void); + + // wait for the event to become signalled + void wait(void); + int wait(ulonglong microseconds); + + // signal the event + void signal(void); + + // pulse the event (signal and free exactly one waiter) + void pulse(void); + + // is the event currently signalled + bool signalled(void); + + // unsignal/clear the event + void reset(void); + +private: + event_t(const event_t&); + event_t& operator=(const event_t&); + + pthread_mutex_t _mutex; + pthread_cond_t _cond; + bool _signalled; + bool _pulsed; + bool _manual_reset; +}; + +// Semaphore signal/wait class +class semaphore_t { +public: + // initial_count - the initial signal count of the semaphore + // max_count - the maximum signal count for the semaphore. + semaphore_t(int initial_count, int max_count); + ~semaphore_t(void); + + enum E_WAIT { + E_SIGNALLED = 0, + E_INTERRUPTED = 1, + E_TIMEDOUT = 2 + }; + + // wait for the semaphore to become signalled + E_WAIT wait(void); + E_WAIT wait(ulonglong microseconds); + + // signal the semaphore to increase the count + // return true if signalled, false if ignored due to count + bool signal(void); + + // what is the semaphore signal count + int signalled(void); + + // unsignal a signalled semaphore + void reset(void); + + // set to interrupt any waiters, as long as is set, + // waiters will return immediately with E_INTERRUPTED. + // the semaphore signal count and tracking will continue + // accepting signals and leave the signalled state intact + void set_interrupt(void); + void clear_interrupt(void); + +private: + semaphore_t(const semaphore_t&); + semaphore_t& operator=(const semaphore_t&); + + pthread_mutex_t _mutex; + pthread_cond_t _cond; + bool _interrupted; + int _signalled; + int _initial_count; + int _max_count; +}; + +// Thread class +class thread_t { +public: + thread_t(void); + ~thread_t(void); + + int start(void* (*pfn)(void*), void* arg); + int join(void** value_ptr); + int detach(void); + +private: + pthread_t _thread; +}; + + +inline uint my_tid(void) { + return (uint)toku_os_gettid(); +} + + +inline mutex_t::mutex_t(void) { + #ifdef TOKUDB_DEBUG + _owners = 0; + _owner = _null_owner; + #endif + int r = pthread_mutex_init(&_mutex, MY_MUTEX_INIT_FAST); + assert_debug(r == 0); +} +inline mutex_t::~mutex_t(void) { + #ifdef TOKUDB_DEBUG + assert_debug(_owners == 0); + #endif + int r = pthread_mutex_destroy(&_mutex); + assert_debug(r == 0); +} +inline void mutex_t::lock(void) { + assert_debug(is_owned_by_me() == false); + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + #ifdef TOKUDB_DEBUG + _owners++; + _owner = pthread_self(); + #endif +} +inline int mutex_t::lock(ulonglong microseconds) { + assert_debug(is_owned_by_me() == false); + timespec waittime = time::offset_timespec(microseconds); + int r = pthread_mutex_timedlock(&_mutex, &waittime); + #ifdef TOKUDB_DEBUG + if (r == 0) { + _owners++; + _owner = pthread_self(); + } + #endif + assert_debug(r == 0 || r == ETIMEDOUT); + return r; +} +inline void mutex_t::unlock(void) { + #ifdef TOKUDB_DEBUG + assert_debug(_owners > 0); + assert_debug(is_owned_by_me()); + _owners--; + _owner = _null_owner; + #endif + int r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); +} +#ifdef TOKUDB_DEBUG +inline bool mutex_t::is_owned_by_me(void) const { + return pthread_equal(pthread_self(), _owner) != 0 ? true : false; +} +#endif + + +inline rwlock_t::rwlock_t(void) { + int r = pthread_rwlock_init(&_rwlock, NULL); + assert_debug(r == 0); +} +inline rwlock_t::~rwlock_t(void) { + int r = pthread_rwlock_destroy(&_rwlock); + assert_debug(r == 0); +} +inline void rwlock_t::lock_read(void) { + int r; + while ((r = pthread_rwlock_rdlock(&_rwlock)) != 0) { + if (r == EBUSY || r == EAGAIN) { + time::sleep_microsec(1000); + continue; + } + break; + } + assert_debug(r == 0); +} +inline int rwlock_t::lock_read(ulonglong microseconds) { + int r; + timespec waittime = time::offset_timespec(microseconds); + while ((r = pthread_rwlock_timedrdlock(&_rwlock, &waittime)) != 0) { + if (r == EBUSY || r == EAGAIN) { + time::sleep_microsec(1000); + continue; + } else if (r == ETIMEDOUT) { + return ETIMEDOUT; + } + break; + } + assert_debug(r == 0); + return r; +} +inline void rwlock_t::lock_write(void) { + int r; + while ((r = pthread_rwlock_wrlock(&_rwlock)) != 0) { + if (r == EBUSY || r == EAGAIN) { + time::sleep_microsec(1000); + continue; + } + break; + } + assert_debug(r == 0); +} +inline int rwlock_t::lock_write(ulonglong microseconds) { + int r; + timespec waittime = time::offset_timespec(microseconds); + while ((r = pthread_rwlock_timedwrlock(&_rwlock, &waittime)) != 0) { + if (r == EBUSY || r == EAGAIN) { + time::sleep_microsec(1000); + continue; + } else if (r == ETIMEDOUT) { + return ETIMEDOUT; + } + break; + } + assert_debug(r == 0); + return r; +} +inline void rwlock_t::unlock(void) { + int r = pthread_rwlock_unlock(&_rwlock); + assert_debug(r == 0); +} +inline rwlock_t::rwlock_t(const rwlock_t&) { +} +inline rwlock_t& rwlock_t::operator=(const rwlock_t&) { + return *this; +} + + +inline event_t::event_t(bool create_signalled, bool manual_reset) : + _manual_reset(manual_reset) { + + int r = pthread_mutex_init(&_mutex, NULL); + assert_debug(r == 0); + r = pthread_cond_init(&_cond, NULL); + assert_debug(r == 0); + if (create_signalled) { + _signalled = true; + } else { + _signalled = false; + } + _pulsed = false; +} +inline event_t::~event_t(void) { + int r = pthread_mutex_destroy(&_mutex); + assert_debug(r == 0); + r = pthread_cond_destroy(&_cond); + assert_debug(r == 0); +} +inline void event_t::wait(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + while (_signalled == false && _pulsed == false) { + r = pthread_cond_wait(&_cond, &_mutex); + assert_debug(r == 0); + } + if (_manual_reset == false) + _signalled = false; + if (_pulsed) + _pulsed = false; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return; +} +inline int event_t::wait(ulonglong microseconds) { + timespec waittime = time::offset_timespec(microseconds); + int r = pthread_mutex_timedlock(&_mutex, &waittime); + if (r == ETIMEDOUT) return ETIMEDOUT; + assert_debug(r == 0); + while (_signalled == false && _pulsed == false) { + r = pthread_cond_timedwait(&_cond, &_mutex, &waittime); + if (r == ETIMEDOUT) { + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return ETIMEDOUT; + } + assert_debug(r == 0); + } + if (_manual_reset == false) + _signalled = false; + if (_pulsed) + _pulsed = false; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return 0; +} +inline void event_t::signal(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + _signalled = true; + if (_manual_reset) { + r = pthread_cond_broadcast(&_cond); + assert_debug(r == 0); + } else { + r = pthread_cond_signal(&_cond); + assert_debug(r == 0); + } + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); +} +inline void event_t::pulse(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + _pulsed = true; + r = pthread_cond_signal(&_cond); + assert_debug(r == 0); + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); +} +inline bool event_t::signalled(void) { + bool ret = false; + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + ret = _signalled; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return ret; +} +inline void event_t::reset(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + _signalled = false; + _pulsed = false; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return; +} +inline event_t::event_t(const event_t&) { +} +inline event_t& event_t::operator=(const event_t&) { + return *this; +} + + +inline semaphore_t::semaphore_t( + int initial_count, + int max_count) : + _interrupted(false), + _initial_count(initial_count), + _max_count(max_count) { + + int r = pthread_mutex_init(&_mutex, NULL); + assert_debug(r == 0); + r = pthread_cond_init(&_cond, NULL); + assert_debug(r == 0); + _signalled = _initial_count; +} +inline semaphore_t::~semaphore_t(void) { + int r = pthread_mutex_destroy(&_mutex); + assert_debug(r == 0); + r = pthread_cond_destroy(&_cond); + assert_debug(r == 0); +} +inline semaphore_t::E_WAIT semaphore_t::wait(void) { + E_WAIT ret; + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + while (_signalled == 0 && _interrupted == false) { + r = pthread_cond_wait(&_cond, &_mutex); + assert_debug(r == 0); + } + if (_interrupted) { + ret = E_INTERRUPTED; + } else { + _signalled--; + ret = E_SIGNALLED; + } + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return ret; +} +inline semaphore_t::E_WAIT semaphore_t::wait(ulonglong microseconds) { + E_WAIT ret; + timespec waittime = time::offset_timespec(microseconds); + int r = pthread_mutex_timedlock(&_mutex, &waittime); + if (r == ETIMEDOUT) return E_TIMEDOUT; + assert_debug(r == 0); + while (_signalled == 0 && _interrupted == false) { + r = pthread_cond_timedwait(&_cond, &_mutex, &waittime); + if (r == ETIMEDOUT) { + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return E_TIMEDOUT; + } + assert_debug(r == 0); + } + if (_interrupted) { + ret = E_INTERRUPTED; + } else { + _signalled--; + ret = E_SIGNALLED; + } + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return ret; +} +inline bool semaphore_t::signal(void) { + bool ret = false; + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + if (_signalled < _max_count) { + _signalled++; + ret = true; + } + r = pthread_cond_signal(&_cond); + assert_debug(r == 0); + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return ret; +} +inline int semaphore_t::signalled(void) { + int ret = 0; + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + ret = _signalled; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return ret; +} +inline void semaphore_t::reset(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + _signalled = 0; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); + return; +} +inline void semaphore_t::set_interrupt(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + _interrupted = true; + r = pthread_cond_broadcast(&_cond); + assert_debug(r == 0); + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); +} +inline void semaphore_t::clear_interrupt(void) { + int r = pthread_mutex_lock(&_mutex); + assert_debug(r == 0); + _interrupted = false; + r = pthread_mutex_unlock(&_mutex); + assert_debug(r == 0); +} +inline semaphore_t::semaphore_t(const semaphore_t&) { +} +inline semaphore_t& semaphore_t::operator=(const semaphore_t&) { + return *this; +} + + +inline thread_t::thread_t(void) : _thread(0) { +} +inline thread_t::~thread_t(void) { +} +inline int thread_t::start(void*(*pfn)(void*), void* arg) { + return pthread_create(&_thread, NULL, pfn, arg); +} +inline int thread_t::join(void** value_ptr) { + return pthread_join(_thread, value_ptr); +} +inline int thread_t::detach(void) { + return pthread_detach(_thread); +} + +} // namespace thread +} // namespace tokudb + + +#endif // _TOKUDB_SYNC_H diff --git a/storage/tokudb/tokudb_time.h b/storage/tokudb/tokudb_time.h new file mode 100644 index 0000000000000..12baa0de24d9f --- /dev/null +++ b/storage/tokudb/tokudb_time.h @@ -0,0 +1,73 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_TIME_H +#define _TOKUDB_TIME_H + +#include "hatoku_defines.h" + +namespace tokudb { +namespace time { + +static const ulonglong MILLISECONDS = 1000; +static const ulonglong MICROSECONDS = 1000000; +static const ulonglong NANOSECONDS = 1000000000; + +// gets curent time of day in microseconds +ulonglong microsec(void); + +// gets a timespec in the future based on the current time and an offset forward +timespec offset_timespec(ulonglong offset); + +// sleep microseconds +void sleep_microsec(ulong tm); + + + +inline ulonglong microsec(void) { + timeval t; + gettimeofday(&t, NULL); + return t.tv_sec * (1UL * 1000 * 1000) + t.tv_usec; +} +inline timespec offset_timespec(ulonglong offset) { + timespec ret; + ulonglong tm = offset + microsec(); + ret.tv_sec = tm / MICROSECONDS; + ret.tv_nsec = (tm % MICROSECONDS) * 1000; + return ret; +} +inline void sleep_microsec(ulong tm) { + timeval t; + t.tv_sec = tm / MICROSECONDS; + t.tv_usec = tm % MICROSECONDS; + + select(0, NULL, NULL, NULL, &t); +} + +} // namespace time +} // namespace tokudb + +#endif // _TOKUDB_TIME_H diff --git a/storage/tokudb/tokudb_txn.h b/storage/tokudb/tokudb_txn.h new file mode 100644 index 0000000000000..67bf591d088d7 --- /dev/null +++ b/storage/tokudb/tokudb_txn.h @@ -0,0 +1,155 @@ +/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +// vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: +/* -*- mode: C; c-basic-offset: 4 -*- */ +#ident "$Id$" +/*====== +This file is part of TokuDB + + +Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. + + TokuDBis is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License, version 2, + as published by the Free Software Foundation. + + TokuDB 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 TokuDB. If not, see . + +======= */ + +#ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." + +#ifndef _TOKUDB_TXN_H +#define _TOKUDB_TXN_H + +#include "hatoku_defines.h" +#include "tokudb_debug.h" +#include "tokudb_sysvars.h" + +typedef enum { + hatoku_iso_not_set = 0, + hatoku_iso_read_uncommitted, + hatoku_iso_read_committed, + hatoku_iso_repeatable_read, + hatoku_iso_serializable +} HA_TOKU_ISO_LEVEL; + +typedef struct st_tokudb_stmt_progress { + ulonglong inserted; + ulonglong updated; + ulonglong deleted; + ulonglong queried; + bool using_loader; +} tokudb_stmt_progress; + +typedef struct st_tokudb_trx_data { + DB_TXN* all; + DB_TXN* stmt; + DB_TXN* sp_level; + DB_TXN* sub_sp_level; + uint tokudb_lock_count; + uint create_lock_count; + tokudb_stmt_progress stmt_progress; + bool checkpoint_lock_taken; + LIST* handlers; +} tokudb_trx_data; + +extern char* tokudb_data_dir; +extern const char* ha_tokudb_ext; + +inline void reset_stmt_progress(tokudb_stmt_progress* val) { + val->deleted = 0; + val->inserted = 0; + val->updated = 0; + val->queried = 0; +} + +inline int get_name_length(const char* name) { + int n = 0; + const char* newname = name; + n += strlen(newname); + n += strlen(ha_tokudb_ext); + return n; +} + +// +// returns maximum length of path to a dictionary +// +inline int get_max_dict_name_path_length(const char* tablename) { + int n = 0; + n += get_name_length(tablename); + n += 1; //for the '-' + n += MAX_DICT_NAME_LEN; + return n; +} + +inline void make_name( + char* newname, + size_t newname_len, + const char* tablename, + const char* dictname) { + + assert_always(tablename); + assert_always(dictname); + size_t real_size = snprintf( + newname, + newname_len, + "%s-%s", + tablename, + dictname); + assert_always(real_size < newname_len); +} + +inline int txn_begin( + DB_ENV* env, + DB_TXN* parent, + DB_TXN** txn, + uint32_t flags, + THD* thd) { + + *txn = NULL; + int r = env->txn_begin(env, parent, txn, flags); + if (r == 0 && thd) { + DB_TXN* this_txn = *txn; + this_txn->set_client_id(this_txn, thd_get_thread_id(thd)); + } + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_TXN, + "begin txn %p %p %u r=%d", + parent, + *txn, + flags, + r); + return r; +} + +inline void commit_txn(DB_TXN* txn, uint32_t flags) { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "commit txn %p", txn); + int r = txn->commit(txn, flags); + if (r != 0) { + sql_print_error( + "tried committing transaction %p and got error code %d", + txn, + r); + } + assert_always(r == 0); +} + +inline void abort_txn(DB_TXN* txn) { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "abort txn %p", txn); + int r = txn->abort(txn); + if (r != 0) { + sql_print_error( + "tried aborting transaction %p and got error code %d", + txn, + r); + } + assert_always(r == 0); +} + +#endif // _TOKUDB_TXN_H diff --git a/storage/tokudb/tokudb_update_fun.cc b/storage/tokudb/tokudb_update_fun.cc index 4647c91880bd2..05149d17317b4 100644 --- a/storage/tokudb/tokudb_update_fun.cc +++ b/storage/tokudb/tokudb_update_fun.cc @@ -105,7 +105,8 @@ enum { // at most, 4 0's // So, upperbound is num_blobs(1+4+1+4) = num_columns*10 -// The expand varchar offsets message is used to expand the size of an offset from 1 to 2 bytes. Not VLQ coded. +// The expand varchar offsets message is used to expand the size of an offset +// from 1 to 2 bytes. Not VLQ coded. // uint8 operation = UPDATE_OP_EXPAND_VARIABLE_OFFSETS // uint32 number of offsets // uint32 starting offset of the variable length field offsets @@ -132,8 +133,8 @@ enum { // uint8 old lengths[N] // uint8 new lengths[N] -// Update and Upsert version 1 messages. Not VLQ coded. Not used anymore, but may be in the -// fractal tree from a previous build. +// Update and Upsert version 1 messages. Not VLQ coded. Not used anymore, but +// may be in the fractal tree from a previous build. // // Field descriptor: // Operations: @@ -143,8 +144,10 @@ enum { // x = x - k // field type 4 see field types above // unused 4 unused -// field null num 4 bit 31 is 1 if the field is nullible and the remaining bits contain the null bit number -// field offset 4 for fixed fields, this is the offset from begining of the row of the field +// field null num 4 bit 31 is 1 if the field is nullible and the +// remaining bits contain the null bit number +// field offset 4 for fixed fields, this is the offset from +// begining of the row of the field // value: // value length 4 == N, length of the value // value N value to add or subtract @@ -234,7 +237,11 @@ static inline bool is_overall_null_position_set(uchar* data, uint32_t pos) { // // sets the bit at index pos in data to 1 if is_null, 0 otherwise // -static inline void set_overall_null_position(uchar* data, uint32_t pos, bool is_null) { +static inline void set_overall_null_position( + uchar* data, + uint32_t pos, + bool is_null) { + uint32_t offset = pos/8; uchar remainder = pos%8; uchar null_bit = 1<size + extra->size + new_len_of_offsets + new_fixed_field_size; - new_val_data = (uchar *)tokudb_my_malloc( - max_num_bytes, - MYF(MY_FAE) - ); - if (new_val_data == NULL) { goto cleanup; } + max_num_bytes = + old_val->size + extra->size + new_len_of_offsets + new_fixed_field_size; + new_val_data = (uchar *)tokudb::memory::malloc( + max_num_bytes, + MYF(MY_FAE)); + if (new_val_data == NULL) { + error = ENOMEM; + goto cleanup; + } old_fixed_field_ptr = (uchar *) old_val->data; old_fixed_field_ptr += old_num_null_bytes; @@ -465,7 +486,7 @@ static int tokudb_hcad_update_fun( bool is_null_default = false; extra_pos++; - assert(op_type == COL_DROP || op_type == COL_ADD); + assert_always(op_type == COL_DROP || op_type == COL_ADD); bool nullable = (extra_pos[0] != 0); extra_pos++; if (nullable) { @@ -474,11 +495,10 @@ static int tokudb_hcad_update_fun( extra_pos += sizeof(uint32_t); uint32_t num_bits; if (op_type == COL_DROP) { - assert(curr_old_null_pos <= null_bit_position); + assert_always(curr_old_null_pos <= null_bit_position); num_bits = null_bit_position - curr_old_null_pos; - } - else { - assert(curr_new_null_pos <= null_bit_position); + } else { + assert_always(curr_new_null_pos <= null_bit_position); num_bits = null_bit_position - curr_new_null_pos; } copy_null_bits( @@ -486,22 +506,19 @@ static int tokudb_hcad_update_fun( curr_new_null_pos, num_bits, old_null_bytes, - new_null_bytes - ); + new_null_bytes); // update the positions curr_new_null_pos += num_bits; curr_old_null_pos += num_bits; if (op_type == COL_DROP) { curr_old_null_pos++; // account for dropped column - } - else { + } else { is_null_default = (extra_pos[0] != 0); extra_pos++; set_overall_null_position( new_null_bytes, null_bit_position, - is_null_default - ); + is_null_default); curr_new_null_pos++; //account for added column } } @@ -518,47 +535,44 @@ static int tokudb_hcad_update_fun( if (op_type == COL_DROP) { num_bytes_to_copy = col_offset - curr_old_fixed_offset; - } - else { + } else { num_bytes_to_copy = col_offset - curr_new_fixed_offset; } memcpy( new_fixed_field_ptr + curr_new_fixed_offset, - old_fixed_field_ptr + curr_old_fixed_offset, - num_bytes_to_copy - ); + old_fixed_field_ptr + curr_old_fixed_offset, + num_bytes_to_copy); curr_old_fixed_offset += num_bytes_to_copy; curr_new_fixed_offset += num_bytes_to_copy; if (op_type == COL_DROP) { - // move old_fixed_offset val to skip OVER column that is being dropped + // move old_fixed_offset val to skip OVER column that is + // being dropped curr_old_fixed_offset += col_size; - } - else { + } else { if (is_null_default) { // copy zeroes - memset(new_fixed_field_ptr + curr_new_fixed_offset, 0, col_size); - } - else { + memset( + new_fixed_field_ptr + curr_new_fixed_offset, + 0, + col_size); + } else { // copy data from extra_pos into new row memcpy( new_fixed_field_ptr + curr_new_fixed_offset, extra_pos, - col_size - ); + col_size); extra_pos += col_size; } curr_new_fixed_offset += col_size; } - } - else if (col_type == COL_VAR) { + } else if (col_type == COL_VAR) { uint32_t var_col_index; memcpy(&var_col_index, extra_pos, sizeof(uint32_t)); extra_pos += sizeof(uint32_t); if (op_type == COL_DROP) { num_var_fields_to_copy = var_col_index - curr_old_num_var_field; - } - else { + } else { num_var_fields_to_copy = var_col_index - curr_new_num_var_field; } copy_var_fields( @@ -568,20 +582,21 @@ static int tokudb_hcad_update_fun( old_num_offset_bytes, curr_new_var_field_data_ptr, curr_new_var_field_offset_ptr, - new_var_field_data_ptr, // pointer to beginning of var fields in new row - old_var_field_data_ptr, // pointer to beginning of var fields in old row - new_num_offset_bytes, // number of offset bytes used in new row + // pointer to beginning of var fields in new row + new_var_field_data_ptr, + // pointer to beginning of var fields in old row + old_var_field_data_ptr, + // number of offset bytes used in new row + new_num_offset_bytes, &num_data_bytes_written, - &num_offset_bytes_written - ); + &num_offset_bytes_written); curr_new_var_field_data_ptr += num_data_bytes_written; curr_new_var_field_offset_ptr += num_offset_bytes_written; curr_new_num_var_field += num_var_fields_to_copy; curr_old_num_var_field += num_var_fields_to_copy; if (op_type == COL_DROP) { curr_old_num_var_field++; // skip over dropped field - } - else { + } else { if (is_null_default) { curr_new_var_field_data_ptr = write_var_field( curr_new_var_field_offset_ptr, @@ -589,11 +604,9 @@ static int tokudb_hcad_update_fun( new_var_field_data_ptr, NULL, //copying no data 0, //copying 0 bytes - new_num_offset_bytes - ); + new_num_offset_bytes); curr_new_var_field_offset_ptr += new_num_offset_bytes; - } - else { + } else { uint32_t data_length; memcpy(&data_length, extra_pos, sizeof(data_length)); extra_pos += sizeof(data_length); @@ -603,20 +616,17 @@ static int tokudb_hcad_update_fun( new_var_field_data_ptr, extra_pos, //copying data from mutator data_length, //copying data_length bytes - new_num_offset_bytes - ); + new_num_offset_bytes); extra_pos += data_length; curr_new_var_field_offset_ptr += new_num_offset_bytes; } curr_new_num_var_field++; //account for added column } - } - else if (col_type == COL_BLOB) { + } else if (col_type == COL_BLOB) { // handle blob data later continue; - } - else { - assert(false); + } else { + assert_unreachable(); } } // finish copying the null stuff @@ -629,19 +639,17 @@ static int tokudb_hcad_update_fun( curr_new_null_pos, overall_null_bits_left, old_null_bytes, - new_null_bytes - ); + new_null_bytes); // finish copying fixed field stuff num_bytes_left = old_fixed_field_size - curr_old_fixed_offset; memcpy( new_fixed_field_ptr + curr_new_fixed_offset, old_fixed_field_ptr + curr_old_fixed_offset, - num_bytes_left - ); + num_bytes_left); curr_old_fixed_offset += num_bytes_left; curr_new_fixed_offset += num_bytes_left; // sanity check - assert(curr_new_fixed_offset == new_fixed_field_size); + assert_always(curr_new_fixed_offset == new_fixed_field_size); // finish copying var field stuff num_var_fields_to_copy = old_num_var_fields - curr_old_num_var_field; @@ -652,33 +660,34 @@ static int tokudb_hcad_update_fun( old_num_offset_bytes, curr_new_var_field_data_ptr, curr_new_var_field_offset_ptr, - new_var_field_data_ptr, // pointer to beginning of var fields in new row - old_var_field_data_ptr, // pointer to beginning of var fields in old row - new_num_offset_bytes, // number of offset bytes used in new row + // pointer to beginning of var fields in new row + new_var_field_data_ptr, + // pointer to beginning of var fields in old row + old_var_field_data_ptr, + // number of offset bytes used in new row + new_num_offset_bytes, &num_data_bytes_written, - &num_offset_bytes_written - ); + &num_offset_bytes_written); curr_new_var_field_offset_ptr += num_offset_bytes_written; curr_new_var_field_data_ptr += num_data_bytes_written; // sanity check - assert(curr_new_var_field_offset_ptr == new_var_field_data_ptr); + assert_always(curr_new_var_field_offset_ptr == new_var_field_data_ptr); // start handling blobs get_blob_field_info( &start_blob_offset, old_len_of_offsets, old_var_field_data_ptr, - old_num_offset_bytes - ); + old_num_offset_bytes); start_blob_ptr = old_var_field_data_ptr + start_blob_offset; - // if nothing else in extra, then there are no blobs to add or drop, so can copy blobs straight + // if nothing else in extra, then there are no blobs to add or drop, so + // can copy blobs straight if ((extra_pos - extra_pos_start) == extra->size) { num_blob_bytes = old_val->size - (start_blob_ptr - old_null_bytes); memcpy(curr_new_var_field_data_ptr, start_blob_ptr, num_blob_bytes); curr_new_var_field_data_ptr += num_blob_bytes; - } - // else, there is blob information to process - else { + } else { + // else, there is blob information to process uchar* len_bytes = NULL; uint32_t curr_old_blob = 0; uint32_t curr_new_blob = 0; @@ -696,11 +705,10 @@ static int tokudb_hcad_update_fun( uint32_t blob_index; memcpy(&blob_index, extra_pos, sizeof(blob_index)); extra_pos += sizeof(blob_index); - assert (op_type == COL_DROP || op_type == COL_ADD); + assert_always (op_type == COL_DROP || op_type == COL_ADD); if (op_type == COL_DROP) { num_blobs_to_copy = blob_index - curr_old_blob; - } - else { + } else { num_blobs_to_copy = blob_index - curr_new_blob; } for (uint32_t i = 0; i < num_blobs_to_copy; i++) { @@ -708,8 +716,7 @@ static int tokudb_hcad_update_fun( curr_new_var_field_data_ptr, curr_old_blob_ptr, len_bytes[curr_old_blob + i], - false - ); + false); curr_old_blob_ptr += num_bytes_written; curr_new_var_field_data_ptr += num_bytes_written; } @@ -721,12 +728,10 @@ static int tokudb_hcad_update_fun( NULL, curr_old_blob_ptr, len_bytes[curr_old_blob], - true - ); + true); curr_old_blob++; curr_old_blob_ptr += num_bytes; - } - else { + } else { // copy new data uint32_t new_len_bytes = extra_pos[0]; extra_pos++; @@ -734,8 +739,7 @@ static int tokudb_hcad_update_fun( curr_new_var_field_data_ptr, extra_pos, new_len_bytes, - false - ); + false); curr_new_blob++; curr_new_var_field_data_ptr += num_bytes; extra_pos += num_bytes; @@ -751,27 +755,27 @@ static int tokudb_hcad_update_fun( error = 0; cleanup: - tokudb_my_free(new_val_data); + tokudb::memory::free(new_val_data); return error; } -// Expand the variable offset array in the old row given the update mesage in the extra. +// Expand the variable offset array in the old row given the update mesage +// in the extra. static int tokudb_expand_variable_offsets( DB* db, - const DBT *key, - const DBT *old_val, - const DBT *extra, - void (*set_val)(const DBT *new_val, void *set_extra), - void *set_extra - ) -{ + const DBT* key, + const DBT* old_val, + const DBT* extra, + void (*set_val)(const DBT* new_val, void* set_extra), + void* set_extra) { + int error = 0; tokudb::buffer extra_val(extra->data, 0, extra->size); // decode the operation uint8_t operation; extra_val.consume(&operation, sizeof operation); - assert(operation == UPDATE_OP_EXPAND_VARIABLE_OFFSETS); + assert_always(operation == UPDATE_OP_EXPAND_VARIABLE_OFFSETS); // decode number of offsets uint32_t number_of_offsets; @@ -781,18 +785,20 @@ static int tokudb_expand_variable_offsets( uint32_t offset_start; extra_val.consume(&offset_start, sizeof offset_start); - assert(extra_val.size() == extra_val.limit()); + assert_always(extra_val.size() == extra_val.limit()); DBT new_val; memset(&new_val, 0, sizeof new_val); if (old_val != NULL) { - assert(offset_start + number_of_offsets <= old_val->size); + assert_always(offset_start + number_of_offsets <= old_val->size); // compute the new val from the old val - uchar *old_val_ptr = (uchar *)old_val->data; + uchar* old_val_ptr = (uchar*)old_val->data; // allocate space for the new val's data - uchar *new_val_ptr = (uchar *)tokudb_my_malloc(number_of_offsets + old_val->size, MYF(MY_FAE)); + uchar* new_val_ptr = (uchar*)tokudb::memory::malloc( + number_of_offsets + old_val->size, + MYF(MY_FAE)); if (!new_val_ptr) { error = ENOMEM; goto cleanup; @@ -819,8 +825,8 @@ static int tokudb_expand_variable_offsets( old_val_ptr += n; new_val.size = new_val_ptr - (uchar *)new_val.data; - assert(new_val_ptr == (uchar *)new_val.data + new_val.size); - assert(old_val_ptr == (uchar *)old_val->data + old_val->size); + assert_always(new_val_ptr == (uchar *)new_val.data + new_val.size); + assert_always(old_val_ptr == (uchar *)old_val->data + old_val->size); // set the new val set_val(&new_val, set_extra); @@ -829,46 +835,50 @@ static int tokudb_expand_variable_offsets( error = 0; cleanup: - tokudb_my_free(new_val.data); + tokudb::memory::free(new_val.data); return error; } // Expand an int field in a old row given the expand message in the extra. static int tokudb_expand_int_field( DB* db, - const DBT *key, - const DBT *old_val, - const DBT *extra, - void (*set_val)(const DBT *new_val, void *set_extra), - void *set_extra - ) -{ + const DBT* key, + const DBT* old_val, + const DBT* extra, + void (*set_val)(const DBT* new_val, void* set_extra), + void* set_extra) { + int error = 0; tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t operation; extra_val.consume(&operation, sizeof operation); - assert(operation == UPDATE_OP_EXPAND_INT || operation == UPDATE_OP_EXPAND_UINT); + assert_always( + operation == UPDATE_OP_EXPAND_INT || + operation == UPDATE_OP_EXPAND_UINT); uint32_t the_offset; extra_val.consume(&the_offset, sizeof the_offset); uint32_t old_length; extra_val.consume(&old_length, sizeof old_length); uint32_t new_length; extra_val.consume(&new_length, sizeof new_length); - assert(extra_val.size() == extra_val.limit()); + assert_always(extra_val.size() == extra_val.limit()); - assert(new_length >= old_length); // expand only + assert_always(new_length >= old_length); // expand only DBT new_val; memset(&new_val, 0, sizeof new_val); if (old_val != NULL) { - assert(the_offset + old_length <= old_val->size); // old field within the old val + // old field within the old val + assert_always(the_offset + old_length <= old_val->size); // compute the new val from the old val - uchar *old_val_ptr = (uchar *)old_val->data; + uchar* old_val_ptr = (uchar*)old_val->data; // allocate space for the new val's data - uchar *new_val_ptr = (uchar *)tokudb_my_malloc(old_val->size + (new_length - old_length), MYF(MY_FAE)); + uchar* new_val_ptr = (uchar*)tokudb::memory::malloc( + old_val->size + (new_length - old_length), + MYF(MY_FAE)); if (!new_val_ptr) { error = ENOMEM; goto cleanup; @@ -882,21 +892,27 @@ static int tokudb_expand_int_field( switch (operation) { case UPDATE_OP_EXPAND_INT: - // fill the entire new value with ones or zeros depending on the sign bit - // the encoding is little endian - memset(new_val_ptr, (old_val_ptr[old_length-1] & 0x80) ? 0xff : 0x00, new_length); - memcpy(new_val_ptr, old_val_ptr, old_length); // overlay the low bytes of the new value with the old value + // fill the entire new value with ones or zeros depending on the + // sign bit the encoding is little endian + memset( + new_val_ptr, + (old_val_ptr[old_length-1] & 0x80) ? 0xff : 0x00, + new_length); + // overlay the low bytes of the new value with the old value + memcpy(new_val_ptr, old_val_ptr, old_length); new_val_ptr += new_length; old_val_ptr += old_length; break; case UPDATE_OP_EXPAND_UINT: - memset(new_val_ptr, 0, new_length); // fill the entire new value with zeros - memcpy(new_val_ptr, old_val_ptr, old_length); // overlay the low bytes of the new value with the old value + // fill the entire new value with zeros + memset(new_val_ptr, 0, new_length); + // overlay the low bytes of the new value with the old value + memcpy(new_val_ptr, old_val_ptr, old_length); new_val_ptr += new_length; old_val_ptr += old_length; break; default: - assert(0); + assert_unreachable(); } // copy the rest @@ -906,8 +922,8 @@ static int tokudb_expand_int_field( old_val_ptr += n; new_val.size = new_val_ptr - (uchar *)new_val.data; - assert(new_val_ptr == (uchar *)new_val.data + new_val.size); - assert(old_val_ptr == (uchar *)old_val->data + old_val->size); + assert_always(new_val_ptr == (uchar *)new_val.data + new_val.size); + assert_always(old_val_ptr == (uchar *)old_val->data + old_val->size); // set the new val set_val(&new_val, set_extra); @@ -916,26 +932,27 @@ static int tokudb_expand_int_field( error = 0; cleanup: - tokudb_my_free(new_val.data); + tokudb::memory::free(new_val.data); return error; } // Expand a char field in a old row given the expand message in the extra. static int tokudb_expand_char_field( DB* db, - const DBT *key, - const DBT *old_val, - const DBT *extra, - void (*set_val)(const DBT *new_val, void *set_extra), - void *set_extra - ) -{ + const DBT* key, + const DBT* old_val, + const DBT* extra, + void (*set_val)(const DBT* new_val, void* set_extra), + void* set_extra) { + int error = 0; tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t operation; extra_val.consume(&operation, sizeof operation); - assert(operation == UPDATE_OP_EXPAND_CHAR || operation == UPDATE_OP_EXPAND_BINARY); + assert_always( + operation == UPDATE_OP_EXPAND_CHAR || + operation == UPDATE_OP_EXPAND_BINARY); uint32_t the_offset; extra_val.consume(&the_offset, sizeof the_offset); uint32_t old_length; @@ -944,20 +961,23 @@ static int tokudb_expand_char_field( extra_val.consume(&new_length, sizeof new_length); uchar pad_char; extra_val.consume(&pad_char, sizeof pad_char); - assert(extra_val.size() == extra_val.limit()); + assert_always(extra_val.size() == extra_val.limit()); - assert(new_length >= old_length); // expand only + assert_always(new_length >= old_length); // expand only DBT new_val; memset(&new_val, 0, sizeof new_val); if (old_val != NULL) { - assert(the_offset + old_length <= old_val->size); // old field within the old val + // old field within the old val + assert_always(the_offset + old_length <= old_val->size); // compute the new val from the old val - uchar *old_val_ptr = (uchar *)old_val->data; + uchar* old_val_ptr = (uchar*)old_val->data; // allocate space for the new val's data - uchar *new_val_ptr = (uchar *)tokudb_my_malloc(old_val->size + (new_length - old_length), MYF(MY_FAE)); + uchar* new_val_ptr = (uchar*)tokudb::memory::malloc( + old_val->size + (new_length - old_length), + MYF(MY_FAE)); if (!new_val_ptr) { error = ENOMEM; goto cleanup; @@ -972,13 +992,15 @@ static int tokudb_expand_char_field( switch (operation) { case UPDATE_OP_EXPAND_CHAR: case UPDATE_OP_EXPAND_BINARY: - memset(new_val_ptr, pad_char, new_length); // fill the entire new value with the pad char - memcpy(new_val_ptr, old_val_ptr, old_length); // overlay the low bytes of the new value with the old value + // fill the entire new value with the pad char + memset(new_val_ptr, pad_char, new_length); + // overlay the low bytes of the new value with the old value + memcpy(new_val_ptr, old_val_ptr, old_length); new_val_ptr += new_length; old_val_ptr += old_length; break; default: - assert(0); + assert_unreachable(); } // copy the rest @@ -988,8 +1010,8 @@ static int tokudb_expand_char_field( old_val_ptr += n; new_val.size = new_val_ptr - (uchar *)new_val.data; - assert(new_val_ptr == (uchar *)new_val.data + new_val.size); - assert(old_val_ptr == (uchar *)old_val->data + old_val->size); + assert_always(new_val_ptr == (uchar *)new_val.data + new_val.size); + assert_always(old_val_ptr == (uchar *)old_val->data + old_val->size); // set the new val set_val(&new_val, set_extra); @@ -998,7 +1020,7 @@ static int tokudb_expand_char_field( error = 0; cleanup: - tokudb_my_free(new_val.data); + tokudb::memory::free(new_val.data); return error; } @@ -1006,17 +1028,25 @@ namespace tokudb { class var_fields { public: - var_fields() { + inline var_fields() { } - void init_var_fields(uint32_t var_offset, uint32_t offset_bytes, uint32_t bytes_per_offset, tokudb::buffer *val_buffer) { - assert(bytes_per_offset == 0 || bytes_per_offset == 1 || bytes_per_offset == 2); + inline void init_var_fields( + uint32_t var_offset, + uint32_t offset_bytes, + uint32_t bytes_per_offset, + tokudb::buffer* val_buffer) { + + assert_always( + bytes_per_offset == 0 || + bytes_per_offset == 1 || + bytes_per_offset == 2); m_var_offset = var_offset; m_val_offset = m_var_offset + offset_bytes; m_bytes_per_offset = bytes_per_offset; if (bytes_per_offset > 0) { m_num_fields = offset_bytes / bytes_per_offset; } else { - assert(offset_bytes == 0); + assert_always(offset_bytes == 0); m_num_fields = 0; } m_val_buffer = val_buffer; @@ -1025,7 +1055,10 @@ class var_fields { uint32_t value_length(uint32_t var_index); void update_offsets(uint32_t var_index, uint32_t old_s, uint32_t new_s); uint32_t end_offset(); - void replace(uint32_t var_index, void *new_val_ptr, uint32_t new_val_length); + void replace( + uint32_t var_index, + void* new_val_ptr, + uint32_t new_val_length); private: uint32_t read_offset(uint32_t var_index); void write_offset(uint32_t var_index, uint32_t v); @@ -1034,24 +1067,28 @@ class var_fields { uint32_t m_val_offset; uint32_t m_bytes_per_offset; uint32_t m_num_fields; - tokudb::buffer *m_val_buffer; + tokudb::buffer* m_val_buffer; }; // Return the ith variable length offset uint32_t var_fields::read_offset(uint32_t var_index) { uint32_t offset = 0; - m_val_buffer->read(&offset, m_bytes_per_offset, m_var_offset + var_index * m_bytes_per_offset); + m_val_buffer->read( + &offset, m_bytes_per_offset, m_var_offset + var_index * m_bytes_per_offset); return offset; } // Write the ith variable length offset with a new offset. void var_fields::write_offset(uint32_t var_index, uint32_t new_offset) { - m_val_buffer->write(&new_offset, m_bytes_per_offset, m_var_offset + var_index * m_bytes_per_offset); + m_val_buffer->write( + &new_offset, + m_bytes_per_offset, + m_var_offset + var_index * m_bytes_per_offset); } // Return the offset of the ith variable length field uint32_t var_fields::value_offset(uint32_t var_index) { - assert(var_index < m_num_fields); + assert_always(var_index < m_num_fields); if (var_index == 0) return m_val_offset; else @@ -1060,16 +1097,21 @@ uint32_t var_fields::value_offset(uint32_t var_index) { // Return the length of the ith variable length field uint32_t var_fields::value_length(uint32_t var_index) { - assert(var_index < m_num_fields); + assert_always(var_index < m_num_fields); if (var_index == 0) return read_offset(0); else return read_offset(var_index) - read_offset(var_index-1); } -// The length of the ith variable length fields changed. Update all of the subsequent offsets. -void var_fields::update_offsets(uint32_t var_index, uint32_t old_s, uint32_t new_s) { - assert(var_index < m_num_fields); +// The length of the ith variable length fields changed. +// Update all of the subsequent offsets. +void var_fields::update_offsets( + uint32_t var_index, + uint32_t old_s, + uint32_t new_s) { + + assert_always(var_index < m_num_fields); if (old_s == new_s) return; for (uint i = var_index; i < m_num_fields; i++) { @@ -1088,7 +1130,11 @@ uint32_t var_fields::end_offset() { return m_val_offset + read_offset(m_num_fields-1); } -void var_fields::replace(uint32_t var_index, void *new_val_ptr, uint32_t new_val_length) { +void var_fields::replace( + uint32_t var_index, + void* new_val_ptr, + uint32_t new_val_length) { + // replace the new val with the extra val uint32_t the_offset = value_offset(var_index); uint32_t old_s = value_length(var_index); @@ -1103,15 +1149,23 @@ class blob_fields { public: blob_fields() { } - void init_blob_fields(uint32_t num_blobs, const uint8_t *blob_lengths, tokudb::buffer *val_buffer) { - m_num_blobs = num_blobs; m_blob_lengths = blob_lengths; m_val_buffer = val_buffer; + void init_blob_fields( + uint32_t num_blobs, + const uint8_t* blob_lengths, + tokudb::buffer* val_buffer) { + m_num_blobs = num_blobs; + m_blob_lengths = blob_lengths; + m_val_buffer = val_buffer; } void start_blobs(uint32_t offset) { m_blob_offset = offset; } void replace(uint32_t blob_index, uint32_t length, void *p); - void expand_length(uint32_t blob_index, uint8_t old_length_length, uint8_t new_length_length); + void expand_length( + uint32_t blob_index, + uint8_t old_length_length, + uint8_t new_length_length); private: uint32_t read_length(uint32_t offset, size_t size); void write_length(uint32_t offset, size_t size, uint32_t new_length); @@ -1129,12 +1183,15 @@ uint32_t blob_fields::read_length(uint32_t offset, size_t blob_length) { return length; } -void blob_fields::write_length(uint32_t offset, size_t size, uint32_t new_length) { +void blob_fields::write_length( + uint32_t offset, + size_t size, + uint32_t new_length) { m_val_buffer->write(&new_length, size, offset); } uint32_t blob_fields::blob_offset(uint32_t blob_index) { - assert(blob_index < m_num_blobs); + assert_always(blob_index < m_num_blobs); uint32_t offset = m_blob_offset; for (uint i = 0; i < blob_index; i++) { uint32_t blob_length = m_blob_lengths[i]; @@ -1144,8 +1201,12 @@ uint32_t blob_fields::blob_offset(uint32_t blob_index) { return offset; } -void blob_fields::replace(uint32_t blob_index, uint32_t new_length, void *new_value) { - assert(blob_index < m_num_blobs); +void blob_fields::replace( + uint32_t blob_index, + uint32_t new_length, + void* new_value) { + + assert_always(blob_index < m_num_blobs); // compute the ith blob offset uint32_t offset = blob_offset(blob_index); @@ -1155,15 +1216,23 @@ void blob_fields::replace(uint32_t blob_index, uint32_t new_length, void *new_va uint32_t old_length = read_length(offset, blob_length); // replace the data - m_val_buffer->replace(offset + blob_length, old_length, new_value, new_length); + m_val_buffer->replace( + offset + blob_length, + old_length, + new_value, + new_length); // write the new length write_length(offset, blob_length, new_length); } -void blob_fields::expand_length(uint32_t blob_index, uint8_t old_length_length, uint8_t new_length_length) { - assert(blob_index < m_num_blobs); - assert(old_length_length == m_blob_lengths[blob_index]); +void blob_fields::expand_length( + uint32_t blob_index, + uint8_t old_length_length, + uint8_t new_length_length) { + + assert_always(blob_index < m_num_blobs); + assert_always(old_length_length == m_blob_lengths[blob_index]); // compute the ith blob offset uint32_t offset = blob_offset(blob_index); @@ -1172,7 +1241,11 @@ void blob_fields::expand_length(uint32_t blob_index, uint8_t old_length_length, uint32_t blob_length = read_length(offset, old_length_length); // expand the length - m_val_buffer->replace(offset, old_length_length, &blob_length, new_length_length); + m_val_buffer->replace( + offset, + old_length_length, + &blob_length, + new_length_length); } class value_map { @@ -1180,8 +1253,16 @@ class value_map { value_map(tokudb::buffer *val_buffer) : m_val_buffer(val_buffer) { } - void init_var_fields(uint32_t var_offset, uint32_t offset_bytes, uint32_t bytes_per_offset) { - m_var_fields.init_var_fields(var_offset, offset_bytes, bytes_per_offset, m_val_buffer); + void init_var_fields( + uint32_t var_offset, + uint32_t offset_bytes, + uint32_t bytes_per_offset) { + + m_var_fields.init_var_fields( + var_offset, + offset_bytes, + bytes_per_offset, + m_val_buffer); } void init_blob_fields(uint32_t num_blobs, const uint8_t *blob_lengths) { @@ -1189,31 +1270,63 @@ class value_map { } // Replace the value of a fixed length field - void replace_fixed(uint32_t the_offset, uint32_t field_null_num, void *new_val_ptr, uint32_t new_val_length) { - m_val_buffer->replace(the_offset, new_val_length, new_val_ptr, new_val_length); + void replace_fixed( + uint32_t the_offset, + uint32_t field_null_num, + void* new_val_ptr, + uint32_t new_val_length) { + + m_val_buffer->replace( + the_offset, + new_val_length, + new_val_ptr, + new_val_length); maybe_clear_null(field_null_num); } // Replace the value of a variable length field - void replace_varchar(uint32_t var_index, uint32_t field_null_num, void *new_val_ptr, uint32_t new_val_length) { + void replace_varchar( + uint32_t var_index, + uint32_t field_null_num, + void* new_val_ptr, + uint32_t new_val_length) { + m_var_fields.replace(var_index, new_val_ptr, new_val_length); maybe_clear_null(field_null_num); } // Replace the value of a blob field - void replace_blob(uint32_t blob_index, uint32_t field_null_num, void *new_val_ptr, uint32_t new_val_length) { + void replace_blob( + uint32_t blob_index, + uint32_t field_null_num, + void* new_val_ptr, + uint32_t new_val_length) { + m_blob_fields.start_blobs(m_var_fields.end_offset()); m_blob_fields.replace(blob_index, new_val_length, new_val_ptr); maybe_clear_null(field_null_num); } - void expand_blob_lengths(uint32_t num_blob, const uint8_t *old_length, const uint8_t *new_length); - - void int_op(uint32_t operation, uint32_t the_offset, uint32_t length, uint32_t field_null_num, - tokudb::buffer &old_val, void *extra_val); - - void uint_op(uint32_t operation, uint32_t the_offset, uint32_t length, uint32_t field_null_num, - tokudb::buffer &old_val, void *extra_val); + void expand_blob_lengths( + uint32_t num_blob, + const uint8_t* old_length, + const uint8_t* new_length); + + void int_op( + uint32_t operation, + uint32_t the_offset, + uint32_t length, + uint32_t field_null_num, + tokudb::buffer& old_val, + void* extra_val); + + void uint_op( + uint32_t operation, + uint32_t the_offset, + uint32_t length, + uint32_t field_null_num, + tokudb::buffer& old_val, + void* extra_val); private: bool is_null(uint32_t null_num, uchar *null_bytes) { @@ -1234,7 +1347,10 @@ class value_map { null_num &= ~(1<<31); else null_num -= 1; - set_overall_null_position((uchar *) m_val_buffer->data(), null_num, false); + set_overall_null_position( + (uchar*)m_val_buffer->data(), + null_num, + false); } } @@ -1245,11 +1361,19 @@ class value_map { }; // Update an int field: signed newval@offset = old_val@offset OP extra_val -void value_map::int_op(uint32_t operation, uint32_t the_offset, uint32_t length, uint32_t field_null_num, - tokudb::buffer &old_val, void *extra_val) { - assert(the_offset + length <= m_val_buffer->size()); - assert(the_offset + length <= old_val.size()); - assert(length == 1 || length == 2 || length == 3 || length == 4 || length == 8); +void value_map::int_op( + uint32_t operation, + uint32_t the_offset, + uint32_t length, + uint32_t field_null_num, + tokudb::buffer &old_val, + void* extra_val) { + + assert_always(the_offset + length <= m_val_buffer->size()); + assert_always(the_offset + length <= old_val.size()); + assert_always( + length == 1 || length == 2 || length == 3 || + length == 4 || length == 8); uchar *old_val_ptr = (uchar *) old_val.data(); bool field_is_null = is_null(field_null_num, old_val_ptr); @@ -1287,16 +1411,24 @@ void value_map::int_op(uint32_t operation, uint32_t the_offset, uint32_t length, } break; default: - assert(0); + assert_unreachable(); } } // Update an unsigned field: unsigned newval@offset = old_val@offset OP extra_val -void value_map::uint_op(uint32_t operation, uint32_t the_offset, uint32_t length, uint32_t field_null_num, - tokudb::buffer &old_val, void *extra_val) { - assert(the_offset + length <= m_val_buffer->size()); - assert(the_offset + length <= old_val.size()); - assert(length == 1 || length == 2 || length == 3 || length == 4 || length == 8); +void value_map::uint_op( + uint32_t operation, + uint32_t the_offset, + uint32_t length, + uint32_t field_null_num, + tokudb::buffer& old_val, + void* extra_val) { + + assert_always(the_offset + length <= m_val_buffer->size()); + assert_always(the_offset + length <= old_val.size()); + assert_always( + length == 1 || length == 2 || length == 3 || + length == 4 || length == 8); uchar *old_val_ptr = (uchar *) old_val.data(); bool field_is_null = is_null(field_null_num, old_val_ptr); @@ -1326,16 +1458,23 @@ void value_map::uint_op(uint32_t operation, uint32_t the_offset, uint32_t length } break; default: - assert(0); + assert_unreachable(); } } -void value_map::expand_blob_lengths(uint32_t num_blob, const uint8_t *old_length, const uint8_t *new_length) { +void value_map::expand_blob_lengths( + uint32_t num_blob, + const uint8_t* old_length, + const uint8_t* new_length) { + uint8_t current_length[num_blob]; memcpy(current_length, old_length, num_blob); for (uint32_t i = 0; i < num_blob; i++) { if (new_length[i] > current_length[i]) { - m_blob_fields.init_blob_fields(num_blob, current_length, m_val_buffer); + m_blob_fields.init_blob_fields( + num_blob, + current_length, + m_val_buffer); m_blob_fields.start_blobs(m_var_fields.end_offset()); m_blob_fields.expand_length(i, current_length[i], new_length[i]); current_length[i] = new_length[i]; @@ -1348,30 +1487,29 @@ void value_map::expand_blob_lengths(uint32_t num_blob, const uint8_t *old_length static uint32_t consume_uint32(tokudb::buffer &b) { uint32_t n; size_t s = b.consume_ui(&n); - assert(s > 0); + assert_always(s > 0); return n; } static uint8_t *consume_uint8_array(tokudb::buffer &b, uint32_t array_size) { uint8_t *p = (uint8_t *) b.consume_ptr(array_size); - assert(p); + assert_always(p); return p; } static int tokudb_expand_blobs( DB* db, - const DBT *key_dbt, - const DBT *old_val_dbt, - const DBT *extra, - void (*set_val)(const DBT *new_val_dbt, void *set_extra), - void *set_extra - ) -{ + const DBT* key_dbt, + const DBT* old_val_dbt, + const DBT* extra, + void (*set_val)(const DBT* new_val_dbt, void* set_extra), + void* set_extra) { + tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t operation; extra_val.consume(&operation, sizeof operation); - assert(operation == UPDATE_OP_EXPAND_BLOB); + assert_always(operation == UPDATE_OP_EXPAND_BLOB); if (old_val_dbt != NULL) { // new val = old val @@ -1384,13 +1522,18 @@ static int tokudb_expand_blobs( uint32_t var_field_offset = consume_uint32(extra_val); uint32_t var_offset_bytes = consume_uint32(extra_val); uint32_t bytes_per_offset = consume_uint32(extra_val); - vd.init_var_fields(var_field_offset, var_offset_bytes, bytes_per_offset); + vd.init_var_fields( + var_field_offset, + var_offset_bytes, + bytes_per_offset); // decode blob info uint32_t num_blob = consume_uint32(extra_val); - const uint8_t *old_blob_length = consume_uint8_array(extra_val, num_blob); - const uint8_t *new_blob_length = consume_uint8_array(extra_val, num_blob); - assert(extra_val.size() == extra_val.limit()); + const uint8_t* old_blob_length = + consume_uint8_array(extra_val, num_blob); + const uint8_t* new_blob_length = + consume_uint8_array(extra_val, num_blob); + assert_always(extra_val.size() == extra_val.limit()); // expand blob lengths vd.expand_blob_lengths(num_blob, old_blob_length, new_blob_length); @@ -1404,8 +1547,14 @@ static int tokudb_expand_blobs( return 0; } -// Decode and apply a sequence of update operations defined in the extra to the old value and put the result in the new value. -static void apply_1_updates(tokudb::value_map &vd, tokudb::buffer &new_val, tokudb::buffer &old_val, tokudb::buffer &extra_val) { +// Decode and apply a sequence of update operations defined in the extra to +// the old value and put the result in the new value. +static void apply_1_updates( + tokudb::value_map& vd, + tokudb::buffer& new_val, + tokudb::buffer& old_val, + tokudb::buffer& extra_val) { + uint32_t num_updates; extra_val.consume(&num_updates, sizeof num_updates); for ( ; num_updates > 0; num_updates--) { @@ -1428,46 +1577,70 @@ static void apply_1_updates(tokudb::value_map &vd, tokudb::buffer &new_val, toku switch (field_type) { case UPDATE_TYPE_INT: if (update_operation == '=') - vd.replace_fixed(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_fixed( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - vd.int_op(update_operation, the_offset, extra_val_length, field_null_num, old_val, extra_val_ptr); + vd.int_op( + update_operation, + the_offset, + extra_val_length, + field_null_num, + old_val, + extra_val_ptr); break; case UPDATE_TYPE_UINT: if (update_operation == '=') - vd.replace_fixed(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_fixed( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - vd.uint_op(update_operation, the_offset, extra_val_length, field_null_num, old_val, extra_val_ptr); + vd.uint_op( + update_operation, + the_offset, + extra_val_length, + field_null_num, + old_val, + extra_val_ptr); break; case UPDATE_TYPE_CHAR: case UPDATE_TYPE_BINARY: if (update_operation == '=') - vd.replace_fixed(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_fixed( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - assert(0); + assert_unreachable(); break; default: - assert(0); + assert_unreachable(); break; } } - assert(extra_val.size() == extra_val.limit()); + assert_always(extra_val.size() == extra_val.limit()); } -// Simple update handler. Decode the update message, apply the update operations to the old value, and set the new value. +// Simple update handler. Decode the update message, apply the update operations +// to the old value, and set the new value. static int tokudb_update_1_fun( DB* db, - const DBT *key_dbt, - const DBT *old_val_dbt, - const DBT *extra, - void (*set_val)(const DBT *new_val_dbt, void *set_extra), - void *set_extra - ) -{ + const DBT* key_dbt, + const DBT* old_val_dbt, + const DBT* extra, + void (*set_val)(const DBT* new_val_dbt, void* set_extra), + void* set_extra) { + tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t operation; extra_val.consume(&operation, sizeof operation); - assert(operation == UPDATE_OP_UPDATE_1); + assert_always(operation == UPDATE_OP_UPDATE_1); if (old_val_dbt != NULL) { // get the simple descriptor @@ -1480,14 +1653,20 @@ static int tokudb_update_1_fun( uint32_t m_bytes_per_offset; extra_val.consume(&m_bytes_per_offset, sizeof m_bytes_per_offset); - tokudb::buffer old_val(old_val_dbt->data, old_val_dbt->size, old_val_dbt->size); + tokudb::buffer old_val( + old_val_dbt->data, + old_val_dbt->size, + old_val_dbt->size); // new val = old val tokudb::buffer new_val; new_val.append(old_val_dbt->data, old_val_dbt->size); tokudb::value_map vd(&new_val); - vd.init_var_fields(m_var_field_offset, m_var_offset_bytes, m_bytes_per_offset); + vd.init_var_fields( + m_var_field_offset, + m_var_offset_bytes, + m_bytes_per_offset); // apply updates to new val apply_1_updates(vd, new_val, old_val, extra_val); @@ -1502,22 +1681,23 @@ static int tokudb_update_1_fun( return 0; } -// Simple upsert handler. Decode the upsert message. If the key does not exist, then insert a new value from the extra. -// Otherwise, apply the update operations to the old value, and then set the new value. +// Simple upsert handler. Decode the upsert message. If the key does not exist, +// then insert a new value from the extra. +// Otherwise, apply the update operations to the old value, and then set the +// new value. static int tokudb_upsert_1_fun( DB* db, - const DBT *key_dbt, - const DBT *old_val_dbt, - const DBT *extra, - void (*set_val)(const DBT *new_val_dbt, void *set_extra), - void *set_extra - ) -{ + const DBT* key_dbt, + const DBT* old_val_dbt, + const DBT* extra, + void (*set_val)(const DBT* new_val_dbt, void* set_extra), + void* set_extra) { + tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t operation; extra_val.consume(&operation, sizeof operation); - assert(operation == UPDATE_OP_UPSERT_1); + assert_always(operation == UPDATE_OP_UPSERT_1); uint32_t insert_length; extra_val.consume(&insert_length, sizeof insert_length); @@ -1540,14 +1720,20 @@ static int tokudb_upsert_1_fun( uint32_t m_bytes_per_offset; extra_val.consume(&m_bytes_per_offset, sizeof m_bytes_per_offset); - tokudb::buffer old_val(old_val_dbt->data, old_val_dbt->size, old_val_dbt->size); + tokudb::buffer old_val( + old_val_dbt->data, + old_val_dbt->size, + old_val_dbt->size); // new val = old val tokudb::buffer new_val; new_val.append(old_val_dbt->data, old_val_dbt->size); tokudb::value_map vd(&new_val); - vd.init_var_fields(m_var_field_offset, m_var_offset_bytes, m_bytes_per_offset); + vd.init_var_fields( + m_var_field_offset, + m_var_offset_bytes, + m_bytes_per_offset); // apply updates to new val apply_1_updates(vd, new_val, old_val, extra_val); @@ -1562,8 +1748,14 @@ static int tokudb_upsert_1_fun( return 0; } -// Decode and apply a sequence of update operations defined in the extra to the old value and put the result in the new value. -static void apply_2_updates(tokudb::value_map &vd, tokudb::buffer &new_val, tokudb::buffer &old_val, tokudb::buffer &extra_val) { +// Decode and apply a sequence of update operations defined in the extra to the +// old value and put the result in the new value. +static void apply_2_updates( + tokudb::value_map& vd, + tokudb::buffer& new_val, + tokudb::buffer& old_val, + tokudb::buffer& extra_val) { + uint32_t num_updates = consume_uint32(extra_val); for (uint32_t i = 0; i < num_updates; i++) { uint32_t update_operation = consume_uint32(extra_val); @@ -1571,79 +1763,118 @@ static void apply_2_updates(tokudb::value_map &vd, tokudb::buffer &new_val, toku uint32_t var_field_offset = consume_uint32(extra_val); uint32_t var_offset_bytes = consume_uint32(extra_val); uint32_t bytes_per_offset = consume_uint32(extra_val); - vd.init_var_fields(var_field_offset, var_offset_bytes, bytes_per_offset); + vd.init_var_fields( + var_field_offset, + var_offset_bytes, + bytes_per_offset); } else if (update_operation == 'b') { uint32_t num_blobs = consume_uint32(extra_val); - const uint8_t *blob_lengths = consume_uint8_array(extra_val, num_blobs); + const uint8_t* blob_lengths = + consume_uint8_array(extra_val, num_blobs); vd.init_blob_fields(num_blobs, blob_lengths); } else { uint32_t field_type = consume_uint32(extra_val); uint32_t field_null_num = consume_uint32(extra_val); uint32_t the_offset = consume_uint32(extra_val); uint32_t extra_val_length = consume_uint32(extra_val); - void *extra_val_ptr = extra_val.consume_ptr(extra_val_length); assert(extra_val_ptr); + void* extra_val_ptr = extra_val.consume_ptr(extra_val_length); + assert_always(extra_val_ptr); switch (field_type) { case UPDATE_TYPE_INT: if (update_operation == '=') - vd.replace_fixed(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_fixed( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - vd.int_op(update_operation, the_offset, extra_val_length, field_null_num, old_val, extra_val_ptr); + vd.int_op( + update_operation, + the_offset, + extra_val_length, + field_null_num, + old_val, + extra_val_ptr); break; case UPDATE_TYPE_UINT: if (update_operation == '=') - vd.replace_fixed(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_fixed( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - vd.uint_op(update_operation, the_offset, extra_val_length, field_null_num, old_val, extra_val_ptr); + vd.uint_op( + update_operation, + the_offset, + extra_val_length, + field_null_num, + old_val, + extra_val_ptr); break; case UPDATE_TYPE_CHAR: case UPDATE_TYPE_BINARY: if (update_operation == '=') - vd.replace_fixed(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_fixed( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - assert(0); + assert_unreachable(); break; case UPDATE_TYPE_VARBINARY: case UPDATE_TYPE_VARCHAR: if (update_operation == '=') - vd.replace_varchar(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_varchar( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - assert(0); + assert_unreachable(); break; case UPDATE_TYPE_TEXT: case UPDATE_TYPE_BLOB: if (update_operation == '=') - vd.replace_blob(the_offset, field_null_num, extra_val_ptr, extra_val_length); + vd.replace_blob( + the_offset, + field_null_num, + extra_val_ptr, + extra_val_length); else - assert(0); + assert_unreachable(); break; default: - assert(0); - break; + assert_unreachable(); } } } - assert(extra_val.size() == extra_val.limit()); + assert_always(extra_val.size() == extra_val.limit()); } -// Simple update handler. Decode the update message, apply the update operations to the old value, and set the new value. +// Simple update handler. Decode the update message, apply the update +// operations to the old value, and set the new value. static int tokudb_update_2_fun( DB* db, - const DBT *key_dbt, - const DBT *old_val_dbt, - const DBT *extra, - void (*set_val)(const DBT *new_val_dbt, void *set_extra), - void *set_extra - ) -{ + const DBT* key_dbt, + const DBT* old_val_dbt, + const DBT* extra, + void (*set_val)(const DBT* new_val_dbt, void* set_extra), + void* set_extra) { + tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t op; extra_val.consume(&op, sizeof op); - assert(op == UPDATE_OP_UPDATE_2); + assert_always(op == UPDATE_OP_UPDATE_2); if (old_val_dbt != NULL) { - tokudb::buffer old_val(old_val_dbt->data, old_val_dbt->size, old_val_dbt->size); + tokudb::buffer old_val( + old_val_dbt->data, + old_val_dbt->size, + old_val_dbt->size); // new val = old val tokudb::buffer new_val; @@ -1664,26 +1895,28 @@ static int tokudb_update_2_fun( return 0; } -// Simple upsert handler. Decode the upsert message. If the key does not exist, then insert a new value from the extra. -// Otherwise, apply the update operations to the old value, and then set the new value. +// Simple upsert handler. Decode the upsert message. If the key does not exist, +// then insert a new value from the extra. +// Otherwise, apply the update operations to the old value, and then set the +// new value. static int tokudb_upsert_2_fun( DB* db, - const DBT *key_dbt, - const DBT *old_val_dbt, - const DBT *extra, - void (*set_val)(const DBT *new_val_dbt, void *set_extra), - void *set_extra - ) -{ + const DBT* key_dbt, + const DBT* old_val_dbt, + const DBT* extra, + void (*set_val)(const DBT* new_val_dbt, void* set_extra), + void* set_extra) { + tokudb::buffer extra_val(extra->data, 0, extra->size); uint8_t op; extra_val.consume(&op, sizeof op); - assert(op == UPDATE_OP_UPSERT_2); + assert_always(op == UPDATE_OP_UPSERT_2); uint32_t insert_length = consume_uint32(extra_val); - assert(insert_length < extra_val.limit()); - void *insert_row = extra_val.consume_ptr(insert_length); assert(insert_row); + assert_always(insert_length < extra_val.limit()); + void* insert_row = extra_val.consume_ptr(insert_length); + assert_always(insert_row); if (old_val_dbt == NULL) { // insert a new row @@ -1692,7 +1925,10 @@ static int tokudb_upsert_2_fun( new_val_dbt.data = insert_row; set_val(&new_val_dbt, set_extra); } else { - tokudb::buffer old_val(old_val_dbt->data, old_val_dbt->size, old_val_dbt->size); + tokudb::buffer old_val( + old_val_dbt->data, + old_val_dbt->size, + old_val_dbt->size); // new val = old val tokudb::buffer new_val; @@ -1713,56 +1949,107 @@ static int tokudb_upsert_2_fun( return 0; } -// This function is the update callback function that is registered with the YDB environment. -// It uses the first byte in the update message to identify the update message type and call -// the handler for that message. +// This function is the update callback function that is registered with the +// YDB environment. It uses the first byte in the update message to identify +// the update message type and call the handler for that message. int tokudb_update_fun( DB* db, - const DBT *key, - const DBT *old_val, - const DBT *extra, - void (*set_val)(const DBT *new_val, void *set_extra), - void *set_extra - ) -{ - assert(extra->size > 0); - uint8_t *extra_pos = (uchar *)extra->data; + const DBT* key, + const DBT* old_val, + const DBT* extra, + void (*set_val)(const DBT* new_val, void* set_extra), + void* set_extra) { + + assert_always(extra->size > 0); + uint8_t* extra_pos = (uchar*)extra->data; uint8_t operation = extra_pos[0]; int error; switch (operation) { case UPDATE_OP_COL_ADD_OR_DROP: - error = tokudb_hcad_update_fun(db, key, old_val, extra, set_val, set_extra); + error = tokudb_hcad_update_fun( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_EXPAND_VARIABLE_OFFSETS: - error = tokudb_expand_variable_offsets(db, key, old_val, extra, set_val, set_extra); + error = tokudb_expand_variable_offsets( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_EXPAND_INT: case UPDATE_OP_EXPAND_UINT: - error = tokudb_expand_int_field(db, key, old_val, extra, set_val, set_extra); + error = tokudb_expand_int_field( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_EXPAND_CHAR: case UPDATE_OP_EXPAND_BINARY: - error = tokudb_expand_char_field(db, key, old_val, extra, set_val, set_extra); + error = tokudb_expand_char_field( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_EXPAND_BLOB: - error = tokudb_expand_blobs(db, key, old_val, extra, set_val, set_extra); + error = tokudb_expand_blobs( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_UPDATE_1: - error = tokudb_update_1_fun(db, key, old_val, extra, set_val, set_extra); + error = tokudb_update_1_fun( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_UPSERT_1: - error = tokudb_upsert_1_fun(db, key, old_val, extra, set_val, set_extra); + error = tokudb_upsert_1_fun( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_UPDATE_2: - error = tokudb_update_2_fun(db, key, old_val, extra, set_val, set_extra); + error = tokudb_update_2_fun( + db, + key, + old_val, + extra, + set_val, + set_extra); break; case UPDATE_OP_UPSERT_2: - error = tokudb_upsert_2_fun(db, key, old_val, extra, set_val, set_extra); + error = tokudb_upsert_2_fun( + db, + key, + old_val, + extra, + set_val, + set_extra); break; default: - assert(0); - error = EINVAL; - break; + assert_unreachable(); } return error; } From ae6cc54a4ae6a0764330a6a1c42baae4ec34442f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 16 Feb 2016 19:44:10 +0100 Subject: [PATCH 002/112] 5.6.28-76.1 --- .../r/tokudb_backup_exclude.result | 31 + .../r/tokudb_backup_set_last_error.result | 20 + mysql-test/suite/tokudb.backup/t/suite.opt | 1 + .../t/tokudb_backup_exclude.test | 69 ++ .../t/tokudb_backup_set_last_error.test | 32 + .../suite/tokudb/include/cluster_key.inc | 138 ++++ mysql-test/suite/tokudb/r/cluster_key.result | 36 +- .../suite/tokudb/r/cluster_key_part.result | 652 +++++++++++++++++- mysql-test/suite/tokudb/t/cluster_key.test | 138 +--- .../suite/tokudb/t/cluster_key_part.test | 48 +- mysql-test/suite/tokudb/t/disabled.def | 1 - storage/tokudb/CMakeLists.txt | 2 +- storage/tokudb/PerconaFT/README.md | 8 +- storage/tokudb/ha_tokudb.h | 3 - 14 files changed, 997 insertions(+), 182 deletions(-) create mode 100644 mysql-test/suite/tokudb.backup/r/tokudb_backup_exclude.result create mode 100644 mysql-test/suite/tokudb.backup/r/tokudb_backup_set_last_error.result create mode 100644 mysql-test/suite/tokudb.backup/t/suite.opt create mode 100644 mysql-test/suite/tokudb.backup/t/tokudb_backup_exclude.test create mode 100644 mysql-test/suite/tokudb.backup/t/tokudb_backup_set_last_error.test create mode 100644 mysql-test/suite/tokudb/include/cluster_key.inc diff --git a/mysql-test/suite/tokudb.backup/r/tokudb_backup_exclude.result b/mysql-test/suite/tokudb.backup/r/tokudb_backup_exclude.result new file mode 100644 index 0000000000000..0bec62e54f62d --- /dev/null +++ b/mysql-test/suite/tokudb.backup/r/tokudb_backup_exclude.result @@ -0,0 +1,31 @@ +create table t1(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +create table t1a(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +create table t1b(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +create table t1c(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +select @@session.tokudb_backup_last_error; +@@session.tokudb_backup_last_error +0 +select @@session.tokudb_backup_last_error_string; +@@session.tokudb_backup_last_error_string +NULL +20 +set session tokudb_backup_exclude='(t1a|t1c)+'; +select @@session.tokudb_backup_last_error; +@@session.tokudb_backup_last_error +0 +select @@session.tokudb_backup_last_error_string; +@@session.tokudb_backup_last_error_string +NULL +10 +set session tokudb_backup_exclude='t1[abc]+'; +select @@session.tokudb_backup_last_error; +@@session.tokudb_backup_last_error +0 +select @@session.tokudb_backup_last_error_string; +@@session.tokudb_backup_last_error_string +NULL +5 +drop table t1; +drop table t1a; +drop table t1b; +drop table t1c; diff --git a/mysql-test/suite/tokudb.backup/r/tokudb_backup_set_last_error.result b/mysql-test/suite/tokudb.backup/r/tokudb_backup_set_last_error.result new file mode 100644 index 0000000000000..e1baf8418adcd --- /dev/null +++ b/mysql-test/suite/tokudb.backup/r/tokudb_backup_set_last_error.result @@ -0,0 +1,20 @@ +create table t1(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +set session tokudb_backup_dir='/aint/no/way/this/exists/here'; +ERROR 42000: Variable 'tokudb_backup_dir' can't be set to the value of '/aint/no/way/this/exists/here' +select @@session.tokudb_backup_last_error; +@@session.tokudb_backup_last_error +2 +select @@session.tokudb_backup_last_error_string; +@@session.tokudb_backup_last_error_string +Could not get real path for /aint/no/way/this/exists/here +set session tokudb_backup_last_error_string='this should not crash the server'; +select @@session.tokudb_backup_last_error_string; +@@session.tokudb_backup_last_error_string +this should not crash the server +set session tokudb_backup_dir='/aint/no/way/this/exists/here'; +ERROR 42000: Variable 'tokudb_backup_dir' can't be set to the value of '/aint/no/way/this/exists/here' +select @@session.tokudb_backup_last_error_string; +@@session.tokudb_backup_last_error_string +Could not get real path for /aint/no/way/this/exists/here +set session tokudb_backup_last_error_string = @old_backup_last_error_string; +drop table t1; diff --git a/mysql-test/suite/tokudb.backup/t/suite.opt b/mysql-test/suite/tokudb.backup/t/suite.opt new file mode 100644 index 0000000000000..e52bd6327e0bf --- /dev/null +++ b/mysql-test/suite/tokudb.backup/t/suite.opt @@ -0,0 +1 @@ +$TOKUDB_OPT $TOKUDB_LOAD_ADD $TOKUDB_BACKUP_OPT $TOKUDB_BACKUP_LOAD_ADD --loose-tokudb-check-jemalloc=0 diff --git a/mysql-test/suite/tokudb.backup/t/tokudb_backup_exclude.test b/mysql-test/suite/tokudb.backup/t/tokudb_backup_exclude.test new file mode 100644 index 0000000000000..a0ff5152f669a --- /dev/null +++ b/mysql-test/suite/tokudb.backup/t/tokudb_backup_exclude.test @@ -0,0 +1,69 @@ +# This test is to specifically test the TokuDB backup excluse functionality. +# This is _not_ an illustration of how to exclude tables from a TokuDB backup, +# if you exclude TokuDB database files in this way, you will have a useless +# backup. +source include/have_tokudb_backup.inc; + +disable_query_log; + +set @old_backup_exclude = @@session.tokudb_backup_exclude; + +enable_query_log; + +# This should create 20 files prefixed with '_test_t1' +create table t1(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +create table t1a(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +create table t1b(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; +create table t1c(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; + +# This should not filter any files +disable_query_log; +--exec mkdir $MYSQLTEST_VARDIR/tmp/backup +--eval set session tokudb_backup_dir='$MYSQLTEST_VARDIR/tmp/backup' +enable_query_log; + +select @@session.tokudb_backup_last_error; +select @@session.tokudb_backup_last_error_string; + +# 20 files should be in the backup set +--exec ls $MYSQLTEST_VARDIR/tmp/backup/mysql_data_dir | grep -c _test_t1 + +--exec rm -rf $MYSQLTEST_VARDIR/tmp/backup + + +# This should filter all files for the t1a and t1c tables +set session tokudb_backup_exclude='(t1a|t1c)+'; + +disable_query_log; +--exec mkdir $MYSQLTEST_VARDIR/tmp/backup +--eval set session tokudb_backup_dir='$MYSQLTEST_VARDIR/tmp/backup' +enable_query_log; + +select @@session.tokudb_backup_last_error; +select @@session.tokudb_backup_last_error_string; + +# 10 files should be in the backup set +--exec ls $MYSQLTEST_VARDIR/tmp/backup/mysql_data_dir | grep -c _test_t1 + +--exec rm -rf $MYSQLTEST_VARDIR/tmp/backup + +# This should filter all files for the t1a, t1b, and t1c tables +set session tokudb_backup_exclude='t1[abc]+'; + +disable_query_log; +--exec mkdir $MYSQLTEST_VARDIR/tmp/backup +--eval set session tokudb_backup_dir='$MYSQLTEST_VARDIR/tmp/backup' +enable_query_log; + +select @@session.tokudb_backup_last_error; +select @@session.tokudb_backup_last_error_string; + +# 5 files should be in the backup set +--exec ls $MYSQLTEST_VARDIR/tmp/backup/mysql_data_dir | grep -c _test_t1 + +--exec rm -rf $MYSQLTEST_VARDIR/tmp/backup + +drop table t1; +drop table t1a; +drop table t1b; +drop table t1c; diff --git a/mysql-test/suite/tokudb.backup/t/tokudb_backup_set_last_error.test b/mysql-test/suite/tokudb.backup/t/tokudb_backup_set_last_error.test new file mode 100644 index 0000000000000..18fc8cc5efb93 --- /dev/null +++ b/mysql-test/suite/tokudb.backup/t/tokudb_backup_set_last_error.test @@ -0,0 +1,32 @@ +# This test validates that the plugin will not crash if a user sets +# tokudb_backup_last_error_string after performing a backup. +source include/have_tokudb_backup.inc; + +disable_query_log; + +set @old_backup_last_error_string = @@session.tokudb_backup_last_error_string; + +enable_query_log; + +create table t1(a INT, b INT, c INT, KEY(a), KEY(b), KEY(c)) engine='tokudb'; + +# this should fail and set the error string since the dummy directory +# doesn't exist +--error ER_WRONG_VALUE_FOR_VAR +--eval set session tokudb_backup_dir='/aint/no/way/this/exists/here' + +select @@session.tokudb_backup_last_error; +select @@session.tokudb_backup_last_error_string; + +set session tokudb_backup_last_error_string='this should not crash the server'; +select @@session.tokudb_backup_last_error_string; + +# this should fail again and set the error string since the dummy directory +# doesn't exist +--error ER_WRONG_VALUE_FOR_VAR +--eval set session tokudb_backup_dir='/aint/no/way/this/exists/here' +select @@session.tokudb_backup_last_error_string; + +set session tokudb_backup_last_error_string = @old_backup_last_error_string; + +drop table t1; diff --git a/mysql-test/suite/tokudb/include/cluster_key.inc b/mysql-test/suite/tokudb/include/cluster_key.inc new file mode 100644 index 0000000000000..dff54c432fbc3 --- /dev/null +++ b/mysql-test/suite/tokudb/include/cluster_key.inc @@ -0,0 +1,138 @@ +# test for TokuDB clustering keys. +# test assumes that a table 't1' exists with the following columns: +# a int, b int, c int, d int +insert into t1 values (1,10,100,1000),(2,20,200,2000),(3,30,300,3000),(4,40,400,4000),(5,50,500,5000),(6,60,600,6000),(7,70,700,7000),(8,80,800,8000),(9,90,900,9000); + + +#normal queries + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where a > 5; +select * from t1 where a > 5; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where b > 30; +select * from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where c > 750; +select * from t1 where c > 750; + +#covering indexes + +# ignore rows column +--replace_column 9 NULL; +explain select a from t1 where a > 8; +select a from t1 where a > 8; + +# ignore rows column +--replace_column 9 NULL; +explain select a,b from t1 where b > 30; +select a,b from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select a,b from t1 where c > 750; +select a,c from t1 where c > 750; + + +alter table t1 add clustering index bdca(b,d,c,a); +insert into t1 values (10,10,10,10); +alter table t1 drop index bdca; + +alter table t1 drop primary key; +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where a > 5; +select * from t1 where a > 5; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where b > 30; +select * from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where c > 750; +select * from t1 where c > 750; + +#covering indexes + +# ignore rows column +--replace_column 9 NULL; +explain select b from t1 where b > 30; +select b from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select b from t1 where c > 750; +select c from t1 where c > 750; + +alter table t1 add e varchar(20); + +alter table t1 add primary key (a,b,c); + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where a > 5; +select * from t1 where a > 5; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where b > 30; +select * from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where c > 750; +select * from t1 where c > 750; + +#covering indexes + +# ignore rows column +--replace_column 9 NULL; +explain select a from t1 where a > 8; +select a from t1 where a > 8; + +# ignore rows column +--replace_column 9 NULL; +explain select a,b from t1 where b > 30; +select a,b from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select a,b from t1 where c > 750; +select a,c from t1 where c > 750; + + +alter table t1 drop primary key; +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where a > 5; +select * from t1 where a > 5; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where b > 30; +select * from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select * from t1 where c > 750; +select * from t1 where c > 750; + +#covering indexes +# ignore rows column +--replace_column 9 NULL; +explain select b from t1 where b > 30; +select b from t1 where b > 30; + +# ignore rows column +--replace_column 9 NULL; +explain select b from t1 where c > 750; +select c from t1 where c > 750; + + diff --git a/mysql-test/suite/tokudb/r/cluster_key.result b/mysql-test/suite/tokudb/r/cluster_key.result index b2a01b1e14d45..9e008b5eb4266 100644 --- a/mysql-test/suite/tokudb/r/cluster_key.result +++ b/mysql-test/suite/tokudb/r/cluster_key.result @@ -1,6 +1,6 @@ SET DEFAULT_STORAGE_ENGINE='tokudb'; DROP TABLE IF EXISTS t1; -create table t1(a int, b int, c int, d int, primary key(a), clustering key(b), key (c))engine=tokudb; +create table t1(a int, b int, c int, d int, primary key(a,b,c), clustering key(b), key (c))engine=tokudb; insert into t1 values (1,10,100,1000),(2,20,200,2000),(3,30,300,3000),(4,40,400,4000),(5,50,500,5000),(6,60,600,6000),(7,70,700,7000),(8,80,800,8000),(9,90,900,9000); explain select * from t1 where a > 5; id select_type table type possible_keys key key_len ref rows Extra @@ -13,7 +13,7 @@ a b c d 9 90 900 9000 explain select * from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where +1 SIMPLE t1 range b b 4 NULL NULL; Using where select * from t1 where b > 30; a b c d 4 40 400 4000 @@ -24,7 +24,7 @@ a b c d 9 90 900 9000 explain select * from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where select * from t1 where c > 750; a b c d 8 80 800 8000 @@ -37,7 +37,7 @@ a 9 explain select a,b from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where; Using index +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index select a,b from t1 where b > 30; a b 4 40 @@ -48,7 +48,7 @@ a b 9 90 explain select a,b from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where; Using index select a,c from t1 where c > 750; a c 8 800 @@ -69,7 +69,7 @@ a b c d 10 10 10 10 explain select * from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where +1 SIMPLE t1 range b b 4 NULL NULL; Using where select * from t1 where b > 30; a b c d 4 40 400 4000 @@ -80,14 +80,14 @@ a b c d 9 90 900 9000 explain select * from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where select * from t1 where c > 750; a b c d 8 80 800 8000 9 90 900 9000 explain select b from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where; Using index +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index select b from t1 where b > 30; b 40 @@ -98,13 +98,13 @@ b 90 explain select b from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where select c from t1 where c > 750; c 800 900 alter table t1 add e varchar(20); -alter table t1 add primary key (a); +alter table t1 add primary key (a,b,c); explain select * from t1 where a > 5; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where @@ -117,7 +117,7 @@ a b c d e 10 10 10 10 NULL explain select * from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where +1 SIMPLE t1 range b b 4 NULL NULL; Using where select * from t1 where b > 30; a b c d e 4 40 400 4000 NULL @@ -128,7 +128,7 @@ a b c d e 9 90 900 9000 NULL explain select * from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where select * from t1 where c > 750; a b c d e 8 80 800 8000 NULL @@ -142,7 +142,7 @@ a 10 explain select a,b from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where; Using index +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index select a,b from t1 where b > 30; a b 4 40 @@ -153,7 +153,7 @@ a b 9 90 explain select a,b from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where; Using index select a,c from t1 where c > 750; a c 8 800 @@ -171,7 +171,7 @@ a b c d e 10 10 10 10 NULL explain select * from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where +1 SIMPLE t1 range b b 4 NULL NULL; Using where select * from t1 where b > 30; a b c d e 4 40 400 4000 NULL @@ -182,14 +182,14 @@ a b c d e 9 90 900 9000 NULL explain select * from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where select * from t1 where c > 750; a b c d e 8 80 800 8000 NULL 9 90 900 9000 NULL explain select b from t1 where b > 30; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 5 NULL NULL; Using where; Using index +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index select b from t1 where b > 30; b 40 @@ -200,7 +200,7 @@ b 90 explain select b from t1 where c > 750; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL NULL; Using where +1 SIMPLE t1 range c c 4 NULL NULL; Using where select c from t1 where c > 750; c 800 diff --git a/mysql-test/suite/tokudb/r/cluster_key_part.result b/mysql-test/suite/tokudb/r/cluster_key_part.result index cd8fc34031459..6df54cac05a02 100644 --- a/mysql-test/suite/tokudb/r/cluster_key_part.result +++ b/mysql-test/suite/tokudb/r/cluster_key_part.result @@ -1,11 +1,22 @@ set default_storage_engine='tokudb'; -drop table if exists t; -create table t ( -x int not null, -y int not null, -primary key(x)) -partition by hash(x) partitions 2; -show create table t; +DROP TABLE IF EXISTS t; +CREATE TABLE t (a INT NOT NULL AUTO_INCREMENT, b INT, PRIMARY KEY(a), CLUSTERING KEY b(b)) ENGINE=TokuDB +PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (100) ENGINE = TokuDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TokuDB); +SHOW CREATE TABLE t; +Table Create Table +t CREATE TABLE `t` ( + `a` int(11) NOT NULL AUTO_INCREMENT, + `b` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + CLUSTERING KEY `b` (`b`) +) ENGINE=TokuDB DEFAULT CHARSET=latin1 +/*!50100 PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (100) ENGINE = TokuDB, + PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TokuDB) */ +DROP TABLE t; +CREATE TABLE t (x INT NOT NULL, y INT NOT NULL, PRIMARY KEY(x)) +PARTITION BY HASH(x) PARTITIONS 2; +SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `x` int(11) NOT NULL, @@ -14,8 +25,8 @@ t CREATE TABLE `t` ( ) ENGINE=TokuDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (x) PARTITIONS 2 */ -alter table t add clustering key(y); -show create table t; +ALTER TABLE t ADD CLUSTERING KEY(y); +SHOW CREATE TABLE t; Table Create Table t CREATE TABLE `t` ( `x` int(11) NOT NULL, @@ -25,4 +36,625 @@ t CREATE TABLE `t` ( ) ENGINE=TokuDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY HASH (x) PARTITIONS 2 */ -drop table t; +DROP TABLE t; +CREATE TABLE t1(a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), CLUSTERING KEY(b), KEY (c)) ENGINE=TOKUDB +PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (5) ENGINE = TOKUDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TOKUDB); +insert into t1 values (1,10,100,1000),(2,20,200,2000),(3,30,300,3000),(4,40,400,4000),(5,50,500,5000),(6,60,600,6000),(7,70,700,7000),(8,80,800,8000),(9,90,900,9000); +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where +select * from t1 where a > 5; +a b c d +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d +4 40 400 4000 +5 50 500 5000 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d +8 80 800 8000 +9 90 900 9000 +explain select a from t1 where a > 8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where; Using index +select a from t1 where a > 8; +a +9 +explain select a,b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select a,b from t1 where b > 30; +a b +4 40 +5 50 +6 60 +7 70 +8 80 +9 90 +explain select a,b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c b 4 NULL NULL; Using where; Using index +select a,c from t1 where c > 750; +a c +8 800 +9 900 +alter table t1 add clustering index bdca(b,d,c,a); +insert into t1 values (10,10,10,10); +alter table t1 drop index bdca; +alter table t1 drop primary key; +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL NULL; Using where +select * from t1 where a > 5; +a b c d +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +10 10 10 10 +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d +4 40 400 4000 +5 50 500 5000 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d +8 80 800 8000 +9 90 900 9000 +explain select b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select b from t1 where b > 30; +b +40 +50 +60 +70 +80 +90 +explain select b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select c from t1 where c > 750; +c +800 +900 +alter table t1 add e varchar(20); +alter table t1 add primary key (a,b,c); +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where +select * from t1 where a > 5; +a b c d e +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +10 10 10 10 NULL +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d e +4 40 400 4000 NULL +5 50 500 5000 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d e +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select a from t1 where a > 8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where; Using index +select a from t1 where a > 8; +a +9 +10 +explain select a,b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select a,b from t1 where b > 30; +a b +4 40 +5 50 +6 60 +7 70 +8 80 +9 90 +explain select a,b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where; Using index +select a,c from t1 where c > 750; +a c +8 800 +9 900 +alter table t1 drop primary key; +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL NULL; Using where +select * from t1 where a > 5; +a b c d e +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +10 10 10 10 NULL +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d e +4 40 400 4000 NULL +5 50 500 5000 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d e +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select b from t1 where b > 30; +b +40 +50 +60 +70 +80 +90 +explain select b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select c from t1 where c > 750; +c +800 +900 +DROP TABLE t1; +CREATE TABLE t1(a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), CLUSTERING KEY(b), KEY (c)) ENGINE=TOKUDB +PARTITION BY RANGE(b) (PARTITION p0 VALUES LESS THAN (50) ENGINE = TOKUDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TOKUDB); +insert into t1 values (1,10,100,1000),(2,20,200,2000),(3,30,300,3000),(4,40,400,4000),(5,50,500,5000),(6,60,600,6000),(7,70,700,7000),(8,80,800,8000),(9,90,900,9000); +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where +select * from t1 where a > 5; +a b c d +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d +4 40 400 4000 +5 50 500 5000 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d +8 80 800 8000 +9 90 900 9000 +explain select a from t1 where a > 8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where; Using index +select a from t1 where a > 8; +a +9 +explain select a,b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select a,b from t1 where b > 30; +a b +4 40 +5 50 +6 60 +7 70 +8 80 +9 90 +explain select a,b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c b 4 NULL NULL; Using where; Using index +select a,c from t1 where c > 750; +a c +8 800 +9 900 +alter table t1 add clustering index bdca(b,d,c,a); +insert into t1 values (10,10,10,10); +alter table t1 drop index bdca; +alter table t1 drop primary key; +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL NULL; Using where +select * from t1 where a > 5; +a b c d +10 10 10 10 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d +4 40 400 4000 +5 50 500 5000 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d +8 80 800 8000 +9 90 900 9000 +explain select b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select b from t1 where b > 30; +b +40 +50 +60 +70 +80 +90 +explain select b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select c from t1 where c > 750; +c +800 +900 +alter table t1 add e varchar(20); +alter table t1 add primary key (a,b,c); +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where +select * from t1 where a > 5; +a b c d e +10 10 10 10 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d e +4 40 400 4000 NULL +5 50 500 5000 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d e +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select a from t1 where a > 8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where; Using index +select a from t1 where a > 8; +a +10 +9 +explain select a,b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select a,b from t1 where b > 30; +a b +4 40 +5 50 +6 60 +7 70 +8 80 +9 90 +explain select a,b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c b 4 NULL NULL; Using where; Using index +select a,c from t1 where c > 750; +a c +8 800 +9 900 +alter table t1 drop primary key; +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL NULL; Using where +select * from t1 where a > 5; +a b c d e +10 10 10 10 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d e +4 40 400 4000 NULL +5 50 500 5000 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d e +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select b from t1 where b > 30; +b +40 +50 +60 +70 +80 +90 +explain select b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select c from t1 where c > 750; +c +800 +900 +DROP TABLE t1; +CREATE TABLE t1(a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), CLUSTERING KEY(b), KEY (c)) ENGINE=TOKUDB +PARTITION BY RANGE(c) (PARTITION p0 VALUES LESS THAN (500) ENGINE = TOKUDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TOKUDB); +insert into t1 values (1,10,100,1000),(2,20,200,2000),(3,30,300,3000),(4,40,400,4000),(5,50,500,5000),(6,60,600,6000),(7,70,700,7000),(8,80,800,8000),(9,90,900,9000); +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where +select * from t1 where a > 5; +a b c d +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d +4 40 400 4000 +5 50 500 5000 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d +8 80 800 8000 +9 90 900 9000 +explain select a from t1 where a > 8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where; Using index +select a from t1 where a > 8; +a +9 +explain select a,b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select a,b from t1 where b > 30; +a b +4 40 +5 50 +6 60 +7 70 +8 80 +9 90 +explain select a,b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c b 4 NULL NULL; Using where; Using index +select a,c from t1 where c > 750; +a c +8 800 +9 900 +alter table t1 add clustering index bdca(b,d,c,a); +insert into t1 values (10,10,10,10); +alter table t1 drop index bdca; +alter table t1 drop primary key; +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL NULL; Using where +select * from t1 where a > 5; +a b c d +10 10 10 10 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d +4 40 400 4000 +5 50 500 5000 +6 60 600 6000 +7 70 700 7000 +8 80 800 8000 +9 90 900 9000 +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d +8 80 800 8000 +9 90 900 9000 +explain select b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select b from t1 where b > 30; +b +40 +50 +60 +70 +80 +90 +explain select b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select c from t1 where c > 750; +c +800 +900 +alter table t1 add e varchar(20); +alter table t1 add primary key (a,b,c); +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where +select * from t1 where a > 5; +a b c d e +10 10 10 10 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d e +4 40 400 4000 NULL +5 50 500 5000 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d e +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select a from t1 where a > 8; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL NULL; Using where; Using index +select a from t1 where a > 8; +a +10 +9 +explain select a,b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select a,b from t1 where b > 30; +a b +4 40 +5 50 +6 60 +7 70 +8 80 +9 90 +explain select a,b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index c b 4 NULL NULL; Using where; Using index +select a,c from t1 where c > 750; +a c +8 800 +9 900 +alter table t1 drop primary key; +explain select * from t1 where a > 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL NULL; Using where +select * from t1 where a > 5; +a b c d e +10 10 10 10 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where +select * from t1 where b > 30; +a b c d e +4 40 400 4000 NULL +5 50 500 5000 NULL +6 60 600 6000 NULL +7 70 700 7000 NULL +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select * from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select * from t1 where c > 750; +a b c d e +8 80 800 8000 NULL +9 90 900 9000 NULL +explain select b from t1 where b > 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 4 NULL NULL; Using where; Using index +select b from t1 where b > 30; +b +40 +50 +60 +70 +80 +90 +explain select b from t1 where c > 750; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range c c 4 NULL NULL; Using where +select c from t1 where c > 750; +c +800 +900 +DROP TABLE t1; diff --git a/mysql-test/suite/tokudb/t/cluster_key.test b/mysql-test/suite/tokudb/t/cluster_key.test index 55420c8528561..9fbd33f6a9936 100644 --- a/mysql-test/suite/tokudb/t/cluster_key.test +++ b/mysql-test/suite/tokudb/t/cluster_key.test @@ -5,140 +5,8 @@ SET DEFAULT_STORAGE_ENGINE='tokudb'; DROP TABLE IF EXISTS t1; --enable_warnings -create table t1(a int, b int, c int, d int, primary key(a), clustering key(b), key (c))engine=tokudb; +create table t1(a int, b int, c int, d int, primary key(a,b,c), clustering key(b), key (c))engine=tokudb; -insert into t1 values (1,10,100,1000),(2,20,200,2000),(3,30,300,3000),(4,40,400,4000),(5,50,500,5000),(6,60,600,6000),(7,70,700,7000),(8,80,800,8000),(9,90,900,9000); +--source ../include/cluster_key.inc - -#normal queries - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where a > 5; -select * from t1 where a > 5; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where b > 30; -select * from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where c > 750; -select * from t1 where c > 750; - -#covering indexes - -# ignore rows column ---replace_column 9 NULL; -explain select a from t1 where a > 8; -select a from t1 where a > 8; - -# ignore rows column ---replace_column 9 NULL; -explain select a,b from t1 where b > 30; -select a,b from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select a,b from t1 where c > 750; -select a,c from t1 where c > 750; - - -alter table t1 add clustering index bdca(b,d,c,a); -insert into t1 values (10,10,10,10); -alter table t1 drop index bdca; - -alter table t1 drop primary key; -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where a > 5; -select * from t1 where a > 5; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where b > 30; -select * from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where c > 750; -select * from t1 where c > 750; - -#covering indexes - -# ignore rows column ---replace_column 9 NULL; -explain select b from t1 where b > 30; -select b from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select b from t1 where c > 750; -select c from t1 where c > 750; - -alter table t1 add e varchar(20); - -alter table t1 add primary key (a); - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where a > 5; -select * from t1 where a > 5; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where b > 30; -select * from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where c > 750; -select * from t1 where c > 750; - -#covering indexes - -# ignore rows column ---replace_column 9 NULL; -explain select a from t1 where a > 8; -select a from t1 where a > 8; - -# ignore rows column ---replace_column 9 NULL; -explain select a,b from t1 where b > 30; -select a,b from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select a,b from t1 where c > 750; -select a,c from t1 where c > 750; - - -alter table t1 drop primary key; -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where a > 5; -select * from t1 where a > 5; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where b > 30; -select * from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select * from t1 where c > 750; -select * from t1 where c > 750; - -#covering indexes -# ignore rows column ---replace_column 9 NULL; -explain select b from t1 where b > 30; -select b from t1 where b > 30; - -# ignore rows column ---replace_column 9 NULL; -explain select b from t1 where c > 750; -select c from t1 where c > 750; - -drop table t1; \ No newline at end of file +drop table t1; diff --git a/mysql-test/suite/tokudb/t/cluster_key_part.test b/mysql-test/suite/tokudb/t/cluster_key_part.test index ed84404616ea8..b875b71fe0092 100644 --- a/mysql-test/suite/tokudb/t/cluster_key_part.test +++ b/mysql-test/suite/tokudb/t/cluster_key_part.test @@ -5,19 +5,47 @@ source include/have_partition.inc; set default_storage_engine='tokudb'; disable_warnings; -drop table if exists t; +DROP TABLE IF EXISTS t; enable_warnings; -create table t ( - x int not null, - y int not null, - primary key(x)) -partition by hash(x) partitions 2; +CREATE TABLE t (a INT NOT NULL AUTO_INCREMENT, b INT, PRIMARY KEY(a), CLUSTERING KEY b(b)) ENGINE=TokuDB +PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (100) ENGINE = TokuDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TokuDB); -show create table t; +SHOW CREATE TABLE t; -alter table t add clustering key(y); +DROP TABLE t; -show create table t; -drop table t; + +CREATE TABLE t (x INT NOT NULL, y INT NOT NULL, PRIMARY KEY(x)) +PARTITION BY HASH(x) PARTITIONS 2; + +SHOW CREATE TABLE t; + +ALTER TABLE t ADD CLUSTERING KEY(y); + +SHOW CREATE TABLE t; + +DROP TABLE t; + + +CREATE TABLE t1(a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), CLUSTERING KEY(b), KEY (c)) ENGINE=TOKUDB +PARTITION BY RANGE(a) (PARTITION p0 VALUES LESS THAN (5) ENGINE = TOKUDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TOKUDB); + +--source ../include/cluster_key.inc + +DROP TABLE t1; + +CREATE TABLE t1(a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), CLUSTERING KEY(b), KEY (c)) ENGINE=TOKUDB +PARTITION BY RANGE(b) (PARTITION p0 VALUES LESS THAN (50) ENGINE = TOKUDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TOKUDB); + +--source ../include/cluster_key.inc + +DROP TABLE t1; + +CREATE TABLE t1(a INT, b INT, c INT, d INT, PRIMARY KEY(a,b,c), CLUSTERING KEY(b), KEY (c)) ENGINE=TOKUDB +PARTITION BY RANGE(c) (PARTITION p0 VALUES LESS THAN (500) ENGINE = TOKUDB, PARTITION p2 VALUES LESS THAN MAXVALUE ENGINE = TOKUDB); + +--source ../include/cluster_key.inc + +DROP TABLE t1; diff --git a/mysql-test/suite/tokudb/t/disabled.def b/mysql-test/suite/tokudb/t/disabled.def index f65151ecd547a..36e63bddab044 100644 --- a/mysql-test/suite/tokudb/t/disabled.def +++ b/mysql-test/suite/tokudb/t/disabled.def @@ -2,7 +2,6 @@ mvcc-19: tokutek mvcc-20: tokutek mvcc-27: tokutek storage_engine_default: tokudb is not the default storage engine -cluster_key_part : https://tokutek.atlassian.net/browse/DB-720 fast_update_blobs : https://tokutek.atlassian.net/browse/DB-871 fast_update_blobs_fixed_varchar : https://tokutek.atlassian.net/browse/DB-871 fast_update_blobs_with_varchar : https://tokutek.atlassian.net/browse/DB-871 diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 37de19c3c1985..2360c6b2c9a70 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(TOKUDB_VERSION 5.6.27-76.0) +SET(TOKUDB_VERSION 5.6.28-76.1) # PerconaFT only supports x86-64 and cmake-2.8.9+ IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT CMAKE_VERSION VERSION_LESS "2.8.9") diff --git a/storage/tokudb/PerconaFT/README.md b/storage/tokudb/PerconaFT/README.md index 7e30a558bc70b..d53caf0019012 100644 --- a/storage/tokudb/PerconaFT/README.md +++ b/storage/tokudb/PerconaFT/README.md @@ -113,11 +113,11 @@ All source code and test contributions must be provided under a [BSD 2-Clause][b License ------- -PerconaFT is available under the GPL version 2, and AGPL version 3, with slight modifications. +PerconaFT is available under the GPL version 2, and AGPL version 3. See [COPYING.AGPLv3][agpllicense], [COPYING.GPLv2][gpllicense], and [PATENTS][patents]. -[agpllicense]: http://github.com/Perona/PerconaFT/blob/master/COPYING.AGPLv3 -[gpllicense]: http://github.com/Perona/PerconaFT/blob/master/COPYING.GPLv2 -[patents]: http://github.com/Perona/PerconaFT/blob/master/PATENTS +[agpllicense]: http://github.com/Percona/PerconaFT/blob/master/COPYING.AGPLv3 +[gpllicense]: http://github.com/Percona/PerconaFT/blob/master/COPYING.GPLv2 +[patents]: http://github.com/Percona/PerconaFT/blob/master/PATENTS diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h index 8783836fbf054..93658643c9a97 100644 --- a/storage/tokudb/ha_tokudb.h +++ b/storage/tokudb/ha_tokudb.h @@ -837,9 +837,6 @@ class ha_tokudb : public handler { bool primary_key_is_clustered() { return true; } - bool supports_clustered_keys() { - return true; - } int cmp_ref(const uchar * ref1, const uchar * ref2); bool check_if_incompatible_data(HA_CREATE_INFO * info, uint table_changes); From 96f680aa6589138058a820987e5cf8600f024e81 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 29 Feb 2016 13:58:41 +0100 Subject: [PATCH 003/112] Raise version number after cloning 5.5.49 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ba54e70bc3ede..58a6b369de910 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=49 +MYSQL_VERSION_PATCH=50 MYSQL_VERSION_EXTRA= From c7e68606c02b7f87a48c27eb358d4d07480f40f4 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Tue, 1 Mar 2016 10:17:25 +0530 Subject: [PATCH 004/112] Bug#21920657: SSL-CA FAILS SILENTLY IF THE PATH CANNOT BE FOUND Description:- Failure during the validation of CA certificate path which is provided as an option for 'ssl-ca' returns two different errors for YaSSL and OPENSSL. Analysis:- 'ssl-ca', option used for specifying the ssl ca certificate path. Failing to validate this certificate with OPENSSL returns an error, "ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed". While YASSL returns "ERROR 2026 (HY000): SSL connection error: ASN: bad other signature confirmation". Error returned by the OPENSSL is correct since "SSL_CTX_load_verify_locations()" returns 0 (in case of OPENSSL) for the failure and sets error as "SSL_INITERR_BAD_PATHS". In case of YASSL, "SSL_CTX_load_verify_locations()" returns an error number which is less than or equal to 0 in case of error. Error numbers for YASSL is mentioned in the file, 'extra/yassl/include/openssl/ssl.h'(line no : 292). Also 'ssl-ca' does not accept tilde home directory path substitution. Fix:- The condition which checks for the error in the "SSL_CTX_load_verify_locations()" is changed in order to accommodate YASSL as well. A logic is written in "mysql_ssl_set()" in order accept the tilde home directory path substitution for all ssl options. --- mysql-test/r/ssl_ca.result | 24 ++++++++++++++++++++++++ mysql-test/t/ssl_ca.test | 35 +++++++++++++++++++++++++++++++++++ sql-common/client.c | 23 +++++++++++++++++++---- vio/viosslfactories.c | 4 ++-- 4 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 mysql-test/r/ssl_ca.result create mode 100644 mysql-test/t/ssl_ca.test diff --git a/mysql-test/r/ssl_ca.result b/mysql-test/r/ssl_ca.result new file mode 100644 index 0000000000000..ffc5671f85f8b --- /dev/null +++ b/mysql-test/r/ssl_ca.result @@ -0,0 +1,24 @@ +# +# Bug#21920657: SSL-CA FAILS SILENTLY IF THE PATH CANNOT BE FOUND +# +# try to connect with wrong '--ssl-ca' path : should fail +ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed +# try to connect with correct '--ssl-ca' path : should connect +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA +# +# Bug#21920678: SSL-CA DOES NOT ACCEPT ~USER TILDE HOME DIRECTORY +# PATH SUBSTITUTION +# +# try to connect with '--ssl-ca' option using tilde home directoy +# path substitution : should connect +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA +# try to connect with '--ssl-key' option using tilde home directoy +# path substitution : should connect +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA +# try to connect with '--ssl-cert' option using tilde home directoy +# path substitution : should connect +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA diff --git a/mysql-test/t/ssl_ca.test b/mysql-test/t/ssl_ca.test new file mode 100644 index 0000000000000..92695de4b0d92 --- /dev/null +++ b/mysql-test/t/ssl_ca.test @@ -0,0 +1,35 @@ +--source include/have_ssl.inc +--source include/not_embedded.inc + +--echo # +--echo # Bug#21920657: SSL-CA FAILS SILENTLY IF THE PATH CANNOT BE FOUND +--echo # + +--echo # try to connect with wrong '--ssl-ca' path : should fail +--error 1 +--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/wrong-cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" 2>&1 + +--echo # try to connect with correct '--ssl-ca' path : should connect +--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" + +--echo # +--echo # Bug#21920678: SSL-CA DOES NOT ACCEPT ~USER TILDE HOME DIRECTORY +--echo # PATH SUBSTITUTION +--echo # + +--let $mysql_test_dir_path= `SELECT REPLACE('$MYSQL_TEST_DIR', '$HOME', '~')` + +--echo # try to connect with '--ssl-ca' option using tilde home directoy +--echo # path substitution : should connect +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +--exec $MYSQL --ssl-ca=$mysql_test_dir_path/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" + +--echo # try to connect with '--ssl-key' option using tilde home directoy +--echo # path substitution : should connect +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$mysql_test_dir_path/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" + +--echo # try to connect with '--ssl-cert' option using tilde home directoy +--echo # path substitution : should connect +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$mysql_test_dir_path/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" diff --git a/sql-common/client.c b/sql-common/client.c index 0ef70eb7f56de..cd9b6a71c53f8 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1204,6 +1204,21 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd) my_strdup((STR), MYF(MY_WME)) : NULL; \ } while (0) +#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) +static char *set_ssl_option_unpack_path(const char *arg) +{ + char *opt_var= NULL; + if (arg) + { + char *buff= (char *)my_malloc(FN_REFLEN + 1, MYF(MY_WME)); + unpack_filename(buff, (char *)arg); + opt_var= my_strdup(buff, MYF(MY_WME)); + my_free(buff); + } + return opt_var; +} +#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ + void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group) { @@ -1798,10 +1813,10 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , { DBUG_ENTER("mysql_ssl_set"); #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) - mysql->options.ssl_key= strdup_if_not_null(key); - mysql->options.ssl_cert= strdup_if_not_null(cert); - mysql->options.ssl_ca= strdup_if_not_null(ca); - mysql->options.ssl_capath= strdup_if_not_null(capath); + mysql->options.ssl_key= set_ssl_option_unpack_path(key); + mysql->options.ssl_cert= set_ssl_option_unpack_path(cert); + mysql->options.ssl_ca= set_ssl_option_unpack_path(ca); + mysql->options.ssl_capath= set_ssl_option_unpack_path(capath); mysql->options.ssl_cipher= strdup_if_not_null(cipher); #endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */ DBUG_RETURN(0); diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index ea46d9c030285..3aa1c8731635d 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -250,7 +250,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, } /* Load certs from the trusted ca */ - if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) == 0) + if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) <= 0) { DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); if (ca_file || ca_path) From bb32ac1d9b6c1333316a8da32ea46105eceefa29 Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Tue, 1 Mar 2016 11:58:45 +0530 Subject: [PATCH 005/112] BUG#17018343 SLAVE CRASHES WHEN APPLYING ROW-BASED BINLOG ENTRIES IN CASCADING REPLICATION Problem: In RBR mode, merge table updates are not successfully applied on a cascading replication. Analysis & Fix: Every type of row event is preceded by one or more table_map_log_events that gives the information about all the tables that are involved in the row event. Server maintains the list in RPL_TABLE_LIST and it goes through all the tables and checks for the compatibility between master and slave. Before checking for the compatibility, it calls 'open_tables()' which takes the list of all tables that needs to be locked and opened. In RBR, because of the Table_map_log_event , we already have all the tables including base tables in the list. But the open_tables() which is generic call takes care of appending base tables if the list contains merge tables. There is an assumption in the current replication layer logic that these tables (TABLE_LIST type objects) are always added in the end of the list. Replication layer maintains the count of tables(tables_to_lock_count) that needs to be verified for compatibility check and runs through only those many tables from the list and rest of the objects in linked list can be skipped. But this assumption is wrong. open_tables()->..->add_children_to_list() adds base tables to the list immediately after seeing the merge table in the list. For eg: If the list passed to open_tables() is t1->t2->t3 where t3 is merge table (and t1 and t2 are base tables), it adds t1'->t2' to the list after t3. New table list looks like t1->t2->t3->t1'->t2'. It looks like it added at the end of the list but that is not correct. If the list passed to open_tables() is t3->t1->t2 where t3 is merge table (and t1 and t2 are base tables), the new prepared list will be t3->t1'->t2'->t1->t2. Where t1' and t2' are of TABLE_LIST objects which were added by add_children_to_list() call and replication layer should not look into them. Here tables_to_lock_count will not help as the objects are added in between the list. Fix: After investigating add_children_list() logic (which is called from open_tables()), there is no flag/logic in it to skip adding the children to the list even if the children are already included in the table list. Hence to fix the issue, a logic should be added in the replication layer to skip children in the list by checking whether 'parent_l' is non-null or not. If it is children, we will skip 'compatibility' check for that table. Also this patch is not removing 'tables_to_lock_count' logic for the performance issues if there are any children at the end of the list, those can be easily skipped directly by stopping the loop with tables_to_lock_count check. --- sql/log_event.cc | 46 +++++++++++++++++++++++++++++++++------ sql/log_event_old.cc | 52 +++++++++++++++++++++++++++++++++----------- 2 files changed, 78 insertions(+), 20 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index accb6a28dbd63..702cf1d575a3f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -7930,9 +7930,6 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. - - We can use a down cast here since we know that every table added - to the tables_to_lock is a RPL_TABLE_LIST. */ { @@ -7951,10 +7948,37 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) NOTE: The base tables are added here are removed when close_thread_tables is called. */ - RPL_TABLE_LIST *ptr= rli->tables_to_lock; - for (uint i= 0 ; ptr && (i < rli->tables_to_lock_count); - ptr= static_cast(ptr->next_global), i++) + TABLE_LIST *table_list_ptr= rli->tables_to_lock; + for (uint i=0 ; table_list_ptr && (i < rli->tables_to_lock_count); + table_list_ptr= table_list_ptr->next_global, i++) { + /* + Below if condition takes care of skipping base tables that + make up the MERGE table (which are added by open_tables() + call). They are added next to the merge table in the list. + For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2 + are base tables for merge table 't3'), open_tables will modify + the list by adding t1 and t2 again immediately after t3 in the + list (*not at the end of the list*). New table_to_lock list will + look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST + objects added by open_tables() call). There is no flag(or logic) in + open_tables() that can skip adding these base tables to the list. + So the logic here should take care of skipping them. + + tables_to_lock_count logic will take care of skipping base tables + that are added at the end of the list. + For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify + the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped + because tables_to_lock_count logic in this for loop. + */ + if (table_list_ptr->parent_l) + continue; + /* + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST (or child table which is + skipped above). + */ + RPL_TABLE_LIST *ptr= static_cast(table_list_ptr); DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; if (!ptr->m_tabledef.compatible_with(thd, const_cast(rli), @@ -7995,7 +8019,15 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) */ TABLE_LIST *ptr= rli->tables_to_lock; for (uint i=0 ; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++) + { + /* + Please see comment in above 'for' loop to know the reason + for this if condition + */ + if (ptr->parent_l) + continue; const_cast(rli)->m_table_map.set_table(ptr->table_id, ptr->table); + } #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(rli->tables_to_lock); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index ed53aec6006c4..eb9678ddaa530 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -119,16 +119,25 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. - - We can use a down cast here since we know that every table added - to the tables_to_lock is a RPL_TABLE_LIST. */ { - RPL_TABLE_LIST *ptr= rli->tables_to_lock; - for (uint i= 0 ; ptr&& (i< rli->tables_to_lock_count); - ptr= static_cast(ptr->next_global), i++) + TABLE_LIST *table_list_ptr= rli->tables_to_lock; + for (uint i=0 ; table_list_ptr&& (i< rli->tables_to_lock_count); + table_list_ptr= table_list_ptr->next_global, i++) { + /* + Please see comment in log_event.cc-Rows_log_event::do_apply_event() + function for the explanation of the below if condition + */ + if (table_list_ptr->parent_l) + continue; + /* + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST(or child table which is + skipped above). + */ + RPL_TABLE_LIST *ptr=static_cast(table_list_ptr); DBUG_ASSERT(ptr->m_tabledef_valid); TABLE *conv_table; if (!ptr->m_tabledef.compatible_with(thd, const_cast(rli), @@ -162,7 +171,15 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info */ TABLE_LIST *ptr= rli->tables_to_lock; for (uint i=0; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++) + { + /* + Please see comment in log_event.cc-Rows_log_event::do_apply_event() + function for the explanation of the below if condition + */ + if (ptr->parent_l) + continue; const_cast(rli)->m_table_map.set_table(ptr->table_id, ptr->table); + } #ifdef HAVE_QUERY_CACHE query_cache.invalidate_locked_for_write(rli->tables_to_lock); #endif @@ -1545,16 +1562,25 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) /* When the open and locking succeeded, we check all tables to ensure that they still have the correct type. - - We can use a down cast here since we know that every table added - to the tables_to_lock is a RPL_TABLE_LIST. */ { - RPL_TABLE_LIST *ptr= rli->tables_to_lock; - for (uint i= 0 ; ptr&& (i< rli->tables_to_lock_count); - ptr= static_cast(ptr->next_global), i++) + TABLE_LIST *table_list_ptr= rli->tables_to_lock; + for (uint i=0; table_list_ptr&& (i< rli->tables_to_lock_count); + table_list_ptr= static_cast(table_list_ptr->next_global), i++) { + /* + Please see comment in log_event.cc-Rows_log_event::do_apply_event() + function for the explanation of the below if condition + */ + if (table_list_ptr->parent_l) + continue; + /* + We can use a down cast here since we know that every table added + to the tables_to_lock is a RPL_TABLE_LIST (or child table which is + skipped above). + */ + RPL_TABLE_LIST *ptr=static_cast(table_list_ptr); TABLE *conv_table; if (ptr->m_tabledef.compatible_with(thd, const_cast(rli), ptr->table, &conv_table)) From 8361151765cc5efd72ad18c5553f80aa440a1d83 Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Tue, 1 Mar 2016 12:29:51 +0530 Subject: [PATCH 006/112] Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR DISK SPACE Problem: ======== Currently SHOW SLAVE STATUS blocks if IO thread waits for disk space. This makes automation tools verifying server health block on taking relevant action. Finally this will create SHOW SLAVE STATUS piles. Analysis: ========= SHOW SLAVE STATUS hangs on mi->data_lock if relay log write is waiting for free disk space while holding mi->data_lock. mi->data_lock is needed to protect the format description event (mi->format_description_event) which is accessed by the clients running FLUSH LOGS and slave IO thread. Note relay log writes don't need to be protected by mi->data_lock, LOCK_log is used to protect relay log between IO and SQL thread (see MYSQL_BIN_LOG::append_event). The code takes mi->data_lock to protect mi->format_description_event during relay log rotate which might get triggered right after relay log write. Fix: ==== Release the data_lock just for the duration of writing into relay log. Made change to ensure the following lock order is maintained to avoid deadlocks. data_lock, LOCK_log data_lock is held during relay log rotations to protect the description event. --- mysql-test/include/assert_grep.inc | 154 ++++++++++++++++++ mysql-test/include/rpl_init.inc | 31 +++- mysql-test/include/rpl_reconnect.inc | 33 +++- mysql-test/include/start_slave_sql.inc | 39 +++++ .../r/rpl_io_thd_wait_for_disk_space.result | 15 ++ .../rpl/t/rpl_io_thd_wait_for_disk_space.test | 71 ++++++++ mysys/errors.c | 13 +- mysys/my_write.c | 10 +- sql/log.cc | 69 +++++++- sql/log.h | 7 +- sql/slave.cc | 40 +++-- sql/slave.h | 4 +- sql/sql_reload.cc | 4 +- 13 files changed, 443 insertions(+), 47 deletions(-) create mode 100644 mysql-test/include/assert_grep.inc create mode 100644 mysql-test/include/start_slave_sql.inc create mode 100644 mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result create mode 100644 mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test diff --git a/mysql-test/include/assert_grep.inc b/mysql-test/include/assert_grep.inc new file mode 100644 index 0000000000000..a980a6d73b184 --- /dev/null +++ b/mysql-test/include/assert_grep.inc @@ -0,0 +1,154 @@ +# ==== Purpose ==== +# +# Grep a file for a pattern, produce a single string out of the +# matching lines, and assert that the string matches a given regular +# expression. +# +# ==== Usage ==== +# +# --let $assert_text= TEXT +# --let $assert_file= FILE +# --let $assert_select= REGEX +# [--let $assert_match= REGEX | --let $assert_count= NUMBER] +# [--let $assert_only_after= REGEX] +# --source include/assert_grep.inc +# +# Parameters: +# +# $assert_text +# Text that describes what is being checked. This text is written to +# the query log so it should not contain non-deterministic elements. +# +# $assert_file +# File to search. +# +# $assert_select +# All lines matching this text will be checked. +# +# $assert_match +# The script will find all lines that match $assert_select, +# concatenate them to a long string, and assert that it matches +# $assert_match. +# +# $assert_count +# Instead of asserting that the selected lines match +# $assert_match, assert that there were exactly $assert_count +# matching lines. +# +# $assert_only_after +# Reset all the lines matched and the counter when finding this pattern. +# It is useful for searching things in the mysqld.err log file just +# after the last server restart for example (discarding the log content +# of previous server executions). + + +if (!$assert_text) +{ + --die !!!ERROR IN TEST: you must set $assert_text +} +if (!$assert_file) +{ + --die !!!ERROR IN TEST: you must set $assert_file +} +if (!$assert_select) +{ + --die !!!ERROR IN TEST: you must set $assert_select +} +if ($assert_match == '') +{ + if ($assert_count == '') + { + --die !!!ERROR IN TEST: you must set either $assert_match or $assert_count + } +} +if ($assert_match != '') +{ + if ($assert_count != '') + { + --echo assert_text='$assert_text' assert_count='$assert_count' + --die !!!ERROR IN TEST: you must set only one of $assert_match or $assert_count + } +} + + +--let $include_filename= assert_grep.inc [$assert_text] +--source include/begin_include_file.inc + + +--let _AG_ASSERT_TEXT= $assert_text +--let _AG_ASSERT_FILE= $assert_file +--let _AG_ASSERT_SELECT= $assert_select +--let _AG_ASSERT_MATCH= $assert_match +--let _AG_ASSERT_COUNT= $assert_count +--let _AG_OUT= `SELECT CONCAT('$MYSQLTEST_VARDIR/tmp/_ag_', UUID())` +--let _AG_ASSERT_ONLY_AFTER= $assert_only_after + + +--perl + use strict; + use warnings; + my $file= $ENV{'_AG_ASSERT_FILE'}; + my $assert_select= $ENV{'_AG_ASSERT_SELECT'}; + my $assert_match= $ENV{'_AG_ASSERT_MATCH'}; + my $assert_count= $ENV{'_AG_ASSERT_COUNT'}; + my $assert_only_after= $ENV{'_AG_ASSERT_ONLY_AFTER'}; + my $out= $ENV{'_AG_OUT'}; + + my $result= ''; + my $count= 0; + open(FILE, "$file") or die("Error $? opening $file: $!\n"); + while () { + my $line = $_; + if ($assert_only_after && $line =~ /$assert_only_after/) { + $result = ""; + $count = 0; + } + if ($line =~ /$assert_select/) { + if ($assert_count ne '') { + $count++; + } + else { + $result .= $line; + } + } + } + close(FILE) or die("Error $? closing $file: $!"); + open OUT, "> $out" or die("Error $? opening $out: $!"); + if ($assert_count ne '' && ($count != $assert_count)) { + print OUT ($count) or die("Error $? writing $out: $!"); + } + elsif ($assert_count eq '' && $result !~ /$assert_match/) { + print OUT ($result) or die("Error $? writing $out: $!"); + } + else { + print OUT ("assert_grep.inc ok"); + } + close OUT or die("Error $? closing $out: $!"); +EOF + + +--let $_ag_outcome= `SELECT LOAD_FILE('$_AG_OUT')` +if ($_ag_outcome != 'assert_grep.inc ok') +{ + --source include/show_rpl_debug_info.inc + --echo include/assert_grep.inc failed! + --echo assert_text: '$assert_text' + --echo assert_file: '$assert_file' + --echo assert_select: '$assert_select' + --echo assert_match: '$assert_match' + --echo assert_count: '$assert_count' + --echo assert_only_after: '$assert_only_after' + if ($assert_match != '') + { + --echo matching lines: '$_ag_outcome' + } + if ($assert_count != '') + { + --echo number of matching lines: $_ag_outcome + } + --die assert_grep.inc failed. +} + + +--let $include_filename= include/assert_grep.inc [$assert_text] +--source include/end_include_file.inc diff --git a/mysql-test/include/rpl_init.inc b/mysql-test/include/rpl_init.inc index 2abfd901b037e..820bc8e90160a 100644 --- a/mysql-test/include/rpl_init.inc +++ b/mysql-test/include/rpl_init.inc @@ -43,6 +43,7 @@ # # [--let $rpl_server_count= 7] # --let $rpl_topology= 1->2->3->1->4, 2->5, 6->7 +# [--let $rpl_extra_connections_per_server= 1] # [--let $rpl_check_server_ids= 1] # [--let $rpl_skip_change_master= 1] # [--let $rpl_skip_start_slave= 1] @@ -65,6 +66,12 @@ # want to specify the empty topology (no server replicates at # all), you have to set $rpl_topology=none. # +# $rpl_extra_connections_per_server +# By default, this script creates connections server_N and +# server_N_1. If you can set this variable to a number, the +# script creates: +# server_N, server_N_1, ..., server_N_$rpl_extra_connections_per_server +# # $rpl_check_server_ids # If $rpl_check_server_ids is set, this script checks that the # @@server_id of all servers are different. This is normally @@ -139,8 +146,17 @@ if (!$SERVER_MYPORT_4) # Check that $rpl_server_count is set if (!$rpl_server_count) { - --let $_compute_rpl_server_count= `SELECT REPLACE('$rpl_topology', '->', ',')` - --let $rpl_server_count= `SELECT GREATEST($_compute_rpl_server_count)` + --let $rpl_server_count= `SELECT REPLACE('$rpl_topology', '->', ',')` + if (`SELECT LOCATE(',', '$rpl_server_count')`) + { + --let $rpl_server_count= `SELECT GREATEST($rpl_server_count)` + } +} + +--let $_rpl_extra_connections_per_server= $rpl_extra_connections_per_server +if ($_rpl_extra_connections_per_server == '') +{ + --let $_rpl_extra_connections_per_server= 1 } @@ -159,15 +175,20 @@ if (!$rpl_debug) # Create two connections to each server; reset master/slave, select # database, set autoinc variables. --let $_rpl_server= $rpl_server_count ---let $_rpl_one= _1 +--let $underscore= _ while ($_rpl_server) { # Connect. --let $rpl_server_number= $_rpl_server --let $rpl_connection_name= server_$_rpl_server --source include/rpl_connect.inc - --let $rpl_connection_name= server_$_rpl_server$_rpl_one - --source include/rpl_connect.inc + --let $_rpl_connection_number= 1 + while ($_rpl_connection_number <= $_rpl_extra_connections_per_server) + { + --let $rpl_connection_name= server_$_rpl_server$underscore$_rpl_connection_number + --source include/rpl_connect.inc + --inc $_rpl_connection_number + } # Configure server. --let $rpl_connection_name= server_$_rpl_server diff --git a/mysql-test/include/rpl_reconnect.inc b/mysql-test/include/rpl_reconnect.inc index cdbbd0a1bf112..673f382bac023 100644 --- a/mysql-test/include/rpl_reconnect.inc +++ b/mysql-test/include/rpl_reconnect.inc @@ -12,6 +12,7 @@ # ==== Usage ==== # # --let $rpl_server_number= N +# [--let $rpl_extra_connections_per_server= 1] # [--let $rpl_debug= 1] # --source include/rpl_reconnect.inc # @@ -21,7 +22,7 @@ # master server, 2 the slave server, 3 the 3rd server, and so on. # Cf. include/rpl_init.inc # -# $rpl_debug +# $rpl_extra_connections_per_server, $rpl_debug # See include/rpl_init.inc --let $include_filename= rpl_reconnect.inc @@ -32,6 +33,11 @@ if (!$rpl_server_number) --die ERROR IN TEST: you must set $rpl_server_number before you source rpl_connect.inc } +if ($_rpl_extra_connections_per_server == '') +{ + --let $_rpl_extra_connections_per_server= 1 +} + if ($rpl_debug) { @@ -72,10 +78,14 @@ if (!$_rpl_server_number) --source include/rpl_connection.inc --enable_reconnect ---let $_rpl_one= _1 ---let $rpl_connection_name= server_$rpl_server_number$_rpl_one ---source include/rpl_connection.inc ---enable_reconnect +--let $_rpl_connection_number= 1 +while ($_rpl_connection_number <= $_rpl_extra_connections_per_server) +{ + --let $rpl_connection_name= server_$rpl_server_number$underscore$_rpl_connection_number + --source include/rpl_connection.inc + --enable_reconnect + --inc $_rpl_connection_number +} if ($rpl_debug) { @@ -122,10 +132,15 @@ if (!$_rpl_server_number) --source include/wait_until_connected_again.inc --disable_reconnect ---let $rpl_connection_name= server_$rpl_server_number$_rpl_one ---source include/rpl_connection.inc ---source include/wait_until_connected_again.inc ---disable_reconnect +--let $_rpl_connection_number= 1 +while ($_rpl_connection_number <= $_rpl_extra_connections_per_server) +{ + --let $rpl_connection_name= server_$rpl_server_number$underscore$_rpl_connection_number + --source include/rpl_connection.inc + --source include/wait_until_connected_again.inc + --disable_reconnect + --inc $_rpl_connection_number +} --let $include_filename= rpl_reconnect.inc diff --git a/mysql-test/include/start_slave_sql.inc b/mysql-test/include/start_slave_sql.inc new file mode 100644 index 0000000000000..9cb66a2eb402c --- /dev/null +++ b/mysql-test/include/start_slave_sql.inc @@ -0,0 +1,39 @@ +# ==== Purpose ==== +# +# Issues START SLAVE SQL_THREAD on the current connection. Then waits +# until the SQL thread has started, or until a timeout is reached. +# +# Please use this instead of 'START SLAVE SQL_THREAD', to reduce the +# risk of races in test cases. +# +# +# ==== Usage ==== +# +# [--let $slave_timeout= NUMBER] +# [--let $rpl_debug= 1] +# --source include/start_slave_sql.inc +# +# Parameters: +# $slave_timeout +# See include/wait_for_slave_param.inc +# +# $rpl_debug +# See include/rpl_init.inc + + +--let $include_filename= start_slave_sql.inc +--source include/begin_include_file.inc + + +if (!$rpl_debug) +{ + --disable_query_log +} + + +START SLAVE SQL_THREAD; +--source include/wait_for_slave_sql_to_start.inc + + +--let $include_filename= start_slave_sql.inc +--source include/end_include_file.inc diff --git a/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result b/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result new file mode 100644 index 0000000000000..c601c9a416913 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result @@ -0,0 +1,15 @@ +include/master-slave.inc +[connection master] +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1); +CALL mtr.add_suppression("Disk is full writing"); +CALL mtr.add_suppression("Retry in 60 secs"); +include/stop_slave_sql.inc +SET @@GLOBAL.DEBUG= 'd,simulate_io_thd_wait_for_disk_space'; +INSERT INTO t1 VALUES(2); +include/wait_for_slave_param.inc [Slave_IO_State] +SET @@GLOBAL.DEBUG= '$debug_saved'; +include/assert_grep.inc [Found the disk full error message on the slave] +include/start_slave_sql.inc +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test new file mode 100644 index 0000000000000..d0c74b94cd12b --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test @@ -0,0 +1,71 @@ +# ==== Purpose ==== +# +# Check that the execution of SHOW SLAVE STATUS command is not blocked when IO +# thread is blocked waiting for disk space. +# +# ==== Implementation ==== +# +# Simulate a scenario where IO thread is waiting for disk space while writing +# into the relay log. Execute SHOW SLAVE STATUS command after IO thread is +# blocked waiting for space. The command should not be blocked. +# +# ==== References ==== +# +# Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR +# DISK SPACE +# Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL +# +############################################################################### +--source include/have_debug.inc +--source include/master-slave.inc + +# Generate events to be replicated to the slave +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1); +--sync_slave_with_master + +# Those errors will only happen in the slave +CALL mtr.add_suppression("Disk is full writing"); +CALL mtr.add_suppression("Retry in 60 secs"); + +# Stop the SQL thread to avoid writing on disk +--source include/stop_slave_sql.inc + +# Set the debug option that will simulate disk full +--let $debug_saved= `SELECT @@GLOBAL.DEBUG` +SET @@GLOBAL.DEBUG= 'd,simulate_io_thd_wait_for_disk_space'; + +# Generate events to be replicated to the slave +--connection master +INSERT INTO t1 VALUES(2); + +--connection slave +# Wait until IO thread is queuing events from master +# Notice that this is performed by querying SHOW SLAVE STATUS +--let $slave_param= Slave_IO_State +--let $slave_param_value= Queueing master event to the relay log +--source include/wait_for_slave_param.inc + +# Get the relay log file name, also using SHOW SLAVE STATUS +--let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) + +# Restore the debug options to "simulate" freed space on disk +SET @@GLOBAL.DEBUG= '$debug_saved'; + +# There should be a message in the error log of the slave stating +# that it was waiting for space to write on the relay log. +--let $assert_file=$MYSQLTEST_VARDIR/log/mysqld.2.err +# Grep only after the message that the I/O thread has started +--let $assert_only_after= Slave I/O .* connected to master .*replication started in log .* at position +--let $assert_count= 1 +--let $assert_select=Disk is full writing .*$relay_log_file.* +--let $assert_text= Found the disk full error message on the slave +--source include/assert_grep.inc + +# Start the SQL thread to let the slave to sync and finish gracefully +--source include/start_slave_sql.inc + +# Cleanup +--connection master +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/mysys/errors.c b/mysys/errors.c index ddd65836b30df..942fd3230c032 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -109,6 +109,7 @@ void init_glob_errs() */ void wait_for_free_space(const char *filename, int errors) { + size_t time_to_sleep= MY_WAIT_FOR_USER_TO_FIX_PANIC; if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE)) { my_printf_warning(EE(EE_DISK_FULL), @@ -119,10 +120,14 @@ void wait_for_free_space(const char *filename, int errors) } DBUG_EXECUTE_IF("simulate_no_free_space_error", { - (void) sleep(1); - return; + time_to_sleep= 1; }); - (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC); + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", + { + time_to_sleep= 1; + }); + + (void) sleep(time_to_sleep); } const char **get_global_errmsgs() diff --git a/mysys/my_write.c b/mysys/my_write.c index ef15e9a55b659..2e68a4dcff3a6 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -24,6 +24,7 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes, written; uint errors; + size_t ToWriteCount; DBUG_ENTER("my_write"); DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", Filedes, Buffer, (ulong) Count, MyFlags)); @@ -37,11 +38,14 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { DBUG_SET("+d,simulate_file_write_error");}); for (;;) { + ToWriteCount= Count; + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { ToWriteCount= 1; }); #ifdef _WIN32 - writtenbytes= my_win_write(Filedes, Buffer, Count); + writtenbytes= my_win_write(Filedes, Buffer, ToWriteCount); #else - writtenbytes= write(Filedes, Buffer, Count); + writtenbytes= write(Filedes, Buffer, ToWriteCount); #endif + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { errno= ENOSPC; }); DBUG_EXECUTE_IF("simulate_file_write_error", { errno= ENOSPC; diff --git a/sql/log.cc b/sql/log.cc index 9e34532f1ac47..eab9a1181478d 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -37,6 +37,7 @@ #include "log_event.h" // Query_log_event #include "rpl_filter.h" #include "rpl_rli.h" +#include "rpl_mi.h" #include "sql_audit.h" #include "sql_show.h" @@ -4377,13 +4378,22 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) } -bool MYSQL_BIN_LOG::append(Log_event* ev) +#ifdef HAVE_REPLICATION +bool MYSQL_BIN_LOG::append(Log_event* ev, Master_info *mi) { bool error = 0; + mysql_mutex_assert_owner(&mi->data_lock); mysql_mutex_lock(&LOCK_log); DBUG_ENTER("MYSQL_BIN_LOG::append"); DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); + /* + Release data_lock by holding LOCK_log, while writing into the relay log. + If slave IO thread waits here for free space, we don't want + SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is + sufficient to block SQL thread when IO thread is updating relay log here. + */ + mysql_mutex_unlock(&mi->data_lock); /* Log_event::write() is smart enough to use my_b_write() or my_b_append() depending on the kind of cache we have. @@ -4398,24 +4408,50 @@ bool MYSQL_BIN_LOG::append(Log_event* ev) if (flush_and_sync(0)) goto err; if ((uint) my_b_append_tell(&log_file) > max_size) + { + /* + If rotation is required we must acquire data_lock to protect + description_event from clients executing FLUSH LOGS in parallel. + In order do that we must release the existing LOCK_log so that we + get it once again in proper locking order to avoid dead locks. + i.e data_lock , LOCK_log. + */ + mysql_mutex_unlock(&LOCK_log); + mysql_mutex_lock(&mi->data_lock); + mysql_mutex_lock(&LOCK_log); error= new_file_without_locking(); + /* + After rotation release data_lock, we need the LOCK_log till we signal + the updation. + */ + mysql_mutex_unlock(&mi->data_lock); + } err: - mysql_mutex_unlock(&LOCK_log); signal_update(); // Safe as we don't call close + mysql_mutex_unlock(&LOCK_log); + mysql_mutex_lock(&mi->data_lock); DBUG_RETURN(error); } -bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...) +bool MYSQL_BIN_LOG::appendv(Master_info* mi, const char* buf, uint len,...) { bool error= 0; DBUG_ENTER("MYSQL_BIN_LOG::appendv"); va_list(args); va_start(args,len); + mysql_mutex_assert_owner(&mi->data_lock); + mysql_mutex_lock(&LOCK_log); DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); - mysql_mutex_assert_owner(&LOCK_log); + /* + Release data_lock by holding LOCK_log, while writing into the relay log. + If slave IO thread waits here for free space, we don't want + SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is + sufficient to block SQL thread when IO thread is updating relay log here. + */ + mysql_mutex_unlock(&mi->data_lock); do { if (my_b_append(&log_file,(uchar*) buf,len)) @@ -4428,13 +4464,34 @@ bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...) DBUG_PRINT("info",("max_size: %lu",max_size)); if (flush_and_sync(0)) goto err; - if ((uint) my_b_append_tell(&log_file) > max_size) + if ((uint) my_b_append_tell(&log_file) > + DBUG_EVALUATE_IF("rotate_slave_debug_group", 500, max_size)) + { + /* + If rotation is required we must acquire data_lock to protect + description_event from clients executing FLUSH LOGS in parallel. + In order do that we must release the existing LOCK_log so that we + get it once again in proper locking order to avoid dead locks. + i.e data_lock , LOCK_log. + */ + mysql_mutex_unlock(&LOCK_log); + mysql_mutex_lock(&mi->data_lock); + mysql_mutex_lock(&LOCK_log); error= new_file_without_locking(); + /* + After rotation release data_lock, we need the LOCK_log till we signal + the updation. + */ + mysql_mutex_unlock(&mi->data_lock); + } err: if (!error) signal_update(); + mysql_mutex_unlock(&LOCK_log); + mysql_mutex_lock(&mi->data_lock); DBUG_RETURN(error); } +#endif bool MYSQL_BIN_LOG::flush_and_sync(bool *synced) { diff --git a/sql/log.h b/sql/log.h index 1fc13afe7d186..7d1c3161ac200 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -20,6 +20,7 @@ #include "handler.h" /* my_xid */ class Relay_log_info; +class Master_info; class Format_description_log_event; @@ -454,8 +455,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG v stands for vector invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0) */ - bool appendv(const char* buf,uint len,...); - bool append(Log_event* ev); + bool appendv(Master_info* mi, const char* buf,uint len,...); + bool append(Log_event* ev, Master_info* mi); void make_log_name(char* buf, const char* log_ident); bool is_active(const char* log_file_name); diff --git a/sql/slave.cc b/sql/slave.cc index d97a9cdf6e9a8..31037c453d317 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -1660,7 +1660,7 @@ Waiting for the slave SQL thread to free enough relay log space"); #endif if (rli->sql_force_rotate_relay) { - rotate_relay_log(rli->mi); + rotate_relay_log(rli->mi, true/*need_data_lock=true*/); rli->sql_force_rotate_relay= false; } @@ -1705,7 +1705,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) if (likely((bool)ev)) { ev->server_id= 0; // don't be ignored by slave SQL thread - if (unlikely(rli->relay_log.append(ev))) + if (unlikely(rli->relay_log.append(ev, mi))) mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "failed to write a Rotate event" @@ -3605,7 +3605,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) break; Execute_load_log_event xev(thd,0,0); xev.log_pos = cev->log_pos; - if (unlikely(mi->rli.relay_log.append(&xev))) + if (unlikely(mi->rli.relay_log.append(&xev, mi))) { mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), @@ -3619,7 +3619,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) { cev->block = net->read_pos; cev->block_len = num_bytes; - if (unlikely(mi->rli.relay_log.append(cev))) + if (unlikely(mi->rli.relay_log.append(cev, mi))) { mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), @@ -3634,7 +3634,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) aev.block = net->read_pos; aev.block_len = num_bytes; aev.log_pos = cev->log_pos; - if (unlikely(mi->rli.relay_log.append(&aev))) + if (unlikely(mi->rli.relay_log.append(&aev, mi))) { mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), @@ -3713,7 +3713,7 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev) Rotate the relay log makes binlog format detection easier (at next slave start or mysqlbinlog) */ - DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */); + DBUG_RETURN(rotate_relay_log(mi, false/*need_data_lock=false*/)); } /* @@ -3819,7 +3819,7 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf, Log_event::Log_event(const char* buf...) in log_event.cc). */ ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */ - if (unlikely(rli->relay_log.append(ev))) + if (unlikely(rli->relay_log.append(ev, mi))) { delete ev; mysql_mutex_unlock(&mi->data_lock); @@ -3875,7 +3875,7 @@ static int queue_binlog_ver_3_event(Master_info *mi, const char *buf, inc_pos= event_len; break; } - if (unlikely(rli->relay_log.append(ev))) + if (unlikely(rli->relay_log.append(ev, mi))) { delete ev; mysql_mutex_unlock(&mi->data_lock); @@ -4083,7 +4083,6 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) direct master (an unsupported, useless setup!). */ - mysql_mutex_lock(log_lock); s_id= uint4korr(buf + SERVER_ID_OFFSET); if ((s_id == ::server_id && !mi->rli.replicate_same_server_id) || /* @@ -4116,6 +4115,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) IGNORE_SERVER_IDS it increments mi->master_log_pos as well as rli->group_relay_log_pos. */ + mysql_mutex_lock(log_lock); if (!(s_id == ::server_id && !mi->rli.replicate_same_server_id) || (buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT && buf[EVENT_TYPE_OFFSET] != ROTATE_EVENT && @@ -4127,13 +4127,14 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) rli->ign_master_log_pos_end= mi->master_log_pos; } rli->relay_log.signal_update(); // the slave SQL thread needs to re-check + mysql_mutex_unlock(log_lock); DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored", (ulong) mi->master_log_pos, uint4korr(buf + SERVER_ID_OFFSET))); } else { /* write the event to the relay log */ - if (likely(!(rli->relay_log.appendv(buf,event_len,0)))) + if (likely(!(rli->relay_log.appendv(mi, buf,event_len,0)))) { mi->master_log_pos+= inc_pos; DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos)); @@ -4143,9 +4144,10 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) { error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; } + mysql_mutex_lock(log_lock); rli->ign_master_log_name_end[0]= 0; // last event is not ignored + mysql_mutex_unlock(log_lock); } - mysql_mutex_unlock(log_lock); skip_relay_logging: @@ -5005,11 +5007,21 @@ event(errno: %d cur_log->error: %d)", locks; here we don't, so this function is mainly taking locks). Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file() is void). + + @param mi Master_info for the IO thread. + @param need_data_lock If true, mi->data_lock will be acquired otherwise, + mi->data_lock must be held by the caller. */ -int rotate_relay_log(Master_info* mi) +int rotate_relay_log(Master_info* mi, bool need_data_lock) { DBUG_ENTER("rotate_relay_log"); + if (need_data_lock) + mysql_mutex_lock(&mi->data_lock); + else + { + mysql_mutex_assert_owner(&mi->data_lock); + } Relay_log_info* rli= &mi->rli; int error= 0; @@ -5044,6 +5056,8 @@ int rotate_relay_log(Master_info* mi) */ rli->relay_log.harvest_bytes_written(&rli->log_space_total); end: + if (need_data_lock) + mysql_mutex_unlock(&mi->data_lock); DBUG_RETURN(error); } diff --git a/sql/slave.h b/sql/slave.h index 0374a5d27ae64..0cf8adb0315e7 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -205,7 +205,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, const char** errmsg); void set_slave_thread_options(THD* thd); void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli); -int rotate_relay_log(Master_info* mi); +int rotate_relay_log(Master_info* mi, bool need_data_lock); int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli); pthread_handler_t handle_slave_io(void *arg); diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 40e350c4ddd6c..f24f31b6399c8 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -157,7 +157,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, { #ifdef HAVE_REPLICATION mysql_mutex_lock(&LOCK_active_mi); - if (rotate_relay_log(active_mi)) + if (rotate_relay_log(active_mi, true/*need_data_lock=true*/)) *write_to_binlog= -1; mysql_mutex_unlock(&LOCK_active_mi); #endif From 32d6db3bfa00e437fbd232b80b73b82a0d30c4ae Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Tue, 1 Mar 2016 13:05:14 +0530 Subject: [PATCH 007/112] Bug#19920049 - MYSQLD_MULTI MISLEADING WHEN MY_PRINT_DEFAULTS IS NOT FOUND DESCRIPTION =========== If script mysqld_multi and utility my_print_defaults are in the same folder (not included in $PATH) and the former is made to run, it complaints that the mysqld binary is absent eventhough the binary exists. ANALYSIS ======== We've a subroutine my_which() mimicking the behaviour of POSIX "which" command. Its current behaviour is to check for a given argument as follows: - Step 1: Assume the argument to be a command having full fledged absolute path. If it exists "as-is", return the argument (which will be pathname), else proceed to Step 2. - Step 2: Assume the argument to be a plain command with no aboslute path. Try locating it in all of the paths (mentioned in $PATH) one by one. If found return the pathname. If found nowhere, return NULL. Currently when my_which(my_print_defaults) is called, it returns from Step 1 (since utlity exists in current folder) and doesn't proceed to Step 2. This is wrong since the returned value is same as the argument i.e. 'my_print_default' which defies the purpose of this subroutine whose job is to return a pathname either in Step 1 or Step 2. Later when the utility is executed in subroutine defaults_for_group(), it evaluates to NULL and returns the same. This is because the plain command 'my_print_defaults {options} ...' would execute properly only if my_print_defaults exists in one of the paths (in $PATH). In such a case, in the course of the flow it looks onto the variable $mysqld_found which comes out to be NULL and hence ethe error. In this case, call to my_which should fail resulting in script being aborted and thus avoiding this mess. FIX === This utility my_print_defaults should be tested only in Step 2 since it does not have an absolute path. Thus added a condition in Step 1 so that is gets executed iff not called for my_print_defaults thus bypassing it to proceed to Step 2 where the check is made for various paths (in $PATH) --- scripts/mysqld_multi.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index bb218a9980bfd..d9ea6a117d27c 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -1,6 +1,6 @@ #!/usr/bin/perl -# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -596,7 +596,11 @@ sub my_which my ($command) = @_; my (@paths, $path); - return $command if (-f $command && -x $command); + # If the argument is not 'my_print_defaults' then it would be of the format + # / + return $command if ($command ne 'my_print_defaults' && -f $command && + -x $command); + @paths = split(':', $ENV{'PATH'}); foreach $path (@paths) { From 767bab4abe7666ee861984bc74ce87200ba23b5d Mon Sep 17 00:00:00 2001 From: Sreeharsha Ramanavarapu Date: Thu, 3 Mar 2016 06:42:12 +0530 Subject: [PATCH 008/112] Bug #18740222: CRASH IN GET_INTERVAL_INFO WITH WEIRDO INTERVALS ISSUE: ------ Some string functions return one or a combination of the parameters as their result. Here the resultant string's charset could be incorrectly set to that of the chosen parameter. This results in incorrect behavior when an ascii string is expected. SOLUTION: --------- Since an ascii string is expected, val_str_ascii should explicitly convert the string. Part of the fix is a backport of Bug#22340858 for mysql-5.5 and mysql-5.6. --- sql/item.cc | 17 +++++++++-------- sql/item_geofunc.cc | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index c482f0e1a04fc..f4917448dda8c 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -227,9 +227,6 @@ bool Item::val_bool() */ String *Item::val_str_ascii(String *str) { - if (!(collation.collation->state & MY_CS_NONASCII)) - return val_str(str); - DBUG_ASSERT(str != &str_value); uint errors; @@ -237,11 +234,15 @@ String *Item::val_str_ascii(String *str) if (!res) return 0; - if ((null_value= str->copy(res->ptr(), res->length(), - collation.collation, &my_charset_latin1, - &errors))) - return 0; - + if (!(res->charset()->state & MY_CS_NONASCII)) + str= res; + else + { + if ((null_value= str->copy(res->ptr(), res->length(), collation.collation, + &my_charset_latin1, &errors))) + return 0; + } + return str; } diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index 621ddcb1a3003..983491211c373 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -179,7 +179,7 @@ String *Item_func_geometry_type::val_str_ascii(String *str) /* String will not move */ str->copy(geom->get_class_info()->m_name.str, geom->get_class_info()->m_name.length, - default_charset()); + &my_charset_latin1); return str; } From 5102a7f278460027fc0ff8d47f2d3f4d72deeacd Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Mon, 7 Mar 2016 18:19:26 +0530 Subject: [PATCH 009/112] Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR DISK SPACE Fixing a post push test issue. --- mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test index d0c74b94cd12b..9eed1089e6d3b 100644 --- a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test +++ b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test @@ -17,6 +17,9 @@ # ############################################################################### --source include/have_debug.inc +# Inorder to grep a specific error pattern in error log a fresh error log +# needs to be generated. +--source include/force_restart.inc --source include/master-slave.inc # Generate events to be replicated to the slave From 6608f84158d3561ef2c2f12a7136aa05cc39d7b4 Mon Sep 17 00:00:00 2001 From: Nisha Gopalakrishnan Date: Mon, 14 Mar 2016 15:20:21 +0530 Subject: [PATCH 010/112] BUG#22594514: HANDLE_FATAL_SIGNAL (SIG=11) IN UNIQUE::~UNIQUE | SQL/UNIQUES.CC:355 Analysis ======== Enabling the sort_buffer_size with a large value can cause operations utilizing the sort buffer like DELETE as mentioned in the bug report to fail. 5.5 and 5.6 versions reports OOM error while in 5.7+, the server crashes. While initializing the mem_root for the sort buffer tree, the block size for the mem_root is determined from the 'sort_buffer_size' value. This unsigned long value is typecasted to unsigned int, hence it becomes zero. Further block_size computation while initializing the mem_root results in a very large block_size value. Hence while trying to allocate a block during the DELETE operation, an OOM error is reported. In case of 5.7+, the PFS instrumentation for memory allocation, overshoots the unsigned value and allocates a block of just one byte. While trying to free the block of the mem_root, the original block_size is used. This triggers the crash since the server tries to free unallocated memory. Fix: ==== In order to restrict usage of such unreasonable sort_buffer_size, the typecast of block size to 'unsigned int' is removed and hence reports OOM error across all versions for sizes exceeding unsigned int range. --- include/my_tree.h | 4 ++-- mysys/tree.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/my_tree.h b/include/my_tree.h index 451e2b72b3c76..4457bb1bc856f 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -62,7 +62,7 @@ typedef struct st_tree { } TREE; /* Functions on whole tree */ -void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, +void init_tree(TREE *tree, size_t default_alloc_size, ulong memory_limit, int size, qsort_cmp2 compare, my_bool with_delete, tree_element_free free_element, void *custom_arg); void delete_tree(TREE*); diff --git a/mysys/tree.c b/mysys/tree.c index c5bf3681a350b..3f7360de40a1a 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -83,7 +83,7 @@ static void rb_delete_fixup(TREE *tree,TREE_ELEMENT ***parent); static int test_rb_tree(TREE_ELEMENT *element); #endif -void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, +void init_tree(TREE *tree, size_t default_alloc_size, ulong memory_limit, int size, qsort_cmp2 compare, my_bool with_delete, tree_element_free free_element, void *custom_arg) { @@ -127,7 +127,7 @@ void init_tree(TREE *tree, ulong default_alloc_size, ulong memory_limit, } if (!(tree->with_delete=with_delete)) { - init_alloc_root(&tree->mem_root, (uint) default_alloc_size, 0); + init_alloc_root(&tree->mem_root, default_alloc_size, 0); tree->mem_root.min_malloc=(sizeof(TREE_ELEMENT)+tree->size_of_element); } DBUG_VOID_RETURN; From 9e5222ce714ef9597d6b386346aec4f4b5ff6047 Mon Sep 17 00:00:00 2001 From: "mysql-builder@oracle.com" <> Date: Thu, 17 Mar 2016 14:32:08 +0100 Subject: [PATCH 011/112] From 17d32a1d45c5ab38193281c0f5d5202cc2c0ac65 Mon Sep 17 00:00:00 2001 From: "mysql-builder@oracle.com" <> Date: Wed, 23 Mar 2016 12:59:22 +0530 Subject: [PATCH 012/112] From b4afc6a7a94a60980eac15dad385cd29ad1dd816 Mon Sep 17 00:00:00 2001 From: "Sreedhar.S" Date: Thu, 14 Apr 2016 14:18:23 +0530 Subject: [PATCH 013/112] Fix for Bugs#14583183 and 19949163 --- packaging/WiX/mysql_server.wxs.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packaging/WiX/mysql_server.wxs.in b/packaging/WiX/mysql_server.wxs.in index 1802baedf3bfa..10b6f892a2eac 100644 --- a/packaging/WiX/mysql_server.wxs.in +++ b/packaging/WiX/mysql_server.wxs.in @@ -2,7 +2,7 @@ xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"> - + + + + Installed + Date: Mon, 11 Apr 2016 11:41:47 +0530 Subject: [PATCH 014/112] Bug#22897202: RPL_IO_THD_WAIT_FOR_DISK_SPACE HAS OCCASIONAL FAILURES Analysis: ========= Test script is not ensuring that "assert_grep.inc" should be called only after 'Disk is full' error is written to the error log. Test checks for "Queueing master event to the relay log" state. But this state is set before invoking 'queue_event'. Actual 'Disk is full' error happens at a very lower level. It can happen that we might even reset the debug point before even the actual disk full simulation occurs and the "Disk is full" message will never appear in the error log. In order to guarentee that we must have some mechanism where in after we write "Disk is full" error messge into the error log we must signal the test to execute SSS and then reset the debug point. So that test is deterministic. Fix: === Added debug sync point to make script deterministic. --- .../suite/rpl/r/rpl_io_thd_wait_for_disk_space.result | 2 +- .../suite/rpl/t/rpl_io_thd_wait_for_disk_space.test | 11 ++++------- mysys/errors.c | 3 ++- sql/log.cc | 8 ++++++++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result b/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result index c601c9a416913..b11ad4f53bd7e 100644 --- a/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result +++ b/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result @@ -7,7 +7,7 @@ CALL mtr.add_suppression("Retry in 60 secs"); include/stop_slave_sql.inc SET @@GLOBAL.DEBUG= 'd,simulate_io_thd_wait_for_disk_space'; INSERT INTO t1 VALUES(2); -include/wait_for_slave_param.inc [Slave_IO_State] +SET DEBUG_SYNC='now WAIT_FOR parked'; SET @@GLOBAL.DEBUG= '$debug_saved'; include/assert_grep.inc [Found the disk full error message on the slave] include/start_slave_sql.inc diff --git a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test index 9eed1089e6d3b..6076be60ebc4b 100644 --- a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test +++ b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test @@ -42,16 +42,13 @@ SET @@GLOBAL.DEBUG= 'd,simulate_io_thd_wait_for_disk_space'; --connection master INSERT INTO t1 VALUES(2); ---connection slave -# Wait until IO thread is queuing events from master -# Notice that this is performed by querying SHOW SLAVE STATUS ---let $slave_param= Slave_IO_State ---let $slave_param_value= Queueing master event to the relay log ---source include/wait_for_slave_param.inc +--connection slave1 +SET DEBUG_SYNC='now WAIT_FOR parked'; -# Get the relay log file name, also using SHOW SLAVE STATUS +# Get the relay log file name using SHOW SLAVE STATUS --let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) +--connection slave # Restore the debug options to "simulate" freed space on disk SET @@GLOBAL.DEBUG= '$debug_saved'; diff --git a/mysys/errors.c b/mysys/errors.c index 942fd3230c032..b606446053570 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -15,7 +15,7 @@ #include "mysys_priv.h" #include "mysys_err.h" - +#include "m_string.h" #ifndef SHARED_LIBRARY const char *globerrs[GLOBERRS]= @@ -128,6 +128,7 @@ void wait_for_free_space(const char *filename, int errors) }); (void) sleep(time_to_sleep); + DEBUG_SYNC_C("disk_full_reached"); } const char **get_global_errmsgs() diff --git a/sql/log.cc b/sql/log.cc index eab9a1181478d..a7f05905514f7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4452,6 +4452,14 @@ bool MYSQL_BIN_LOG::appendv(Master_info* mi, const char* buf, uint len,...) sufficient to block SQL thread when IO thread is updating relay log here. */ mysql_mutex_unlock(&mi->data_lock); + DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", + { + const char act[]= "disk_full_reached SIGNAL parked"; + DBUG_ASSERT(opt_debug_sync_timeout > 0); + DBUG_ASSERT(!debug_sync_set_action(current_thd, + STRING_WITH_LEN(act))); + };); + do { if (my_b_append(&log_file,(uchar*) buf,len)) From fbf44eed3c69dc15047ac2d40c09dd0d16993fb0 Mon Sep 17 00:00:00 2001 From: Karthik Kamath Date: Tue, 19 Apr 2016 14:49:27 +0530 Subject: [PATCH 015/112] BUG#22286421: NULL POINTER DEREFERENCE ANALYSIS: ========= A LEX_STRING structure pointer is processed during the validation of a stored program name. During this processing, there is a possibility of null pointer dereference. FIX: ==== check_routine_name() is invoked by the parser by supplying a non-empty string as the SP name. To avoid any potential calls to check_routine_name() with NULL value, a debug assert has been added to catch such cases. --- sql/sp_head.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 13d1b310599c5..992e7415f45cb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -490,8 +490,9 @@ sp_name::init_qname(THD *thd) bool check_routine_name(LEX_STRING *ident) { - if (!ident || !ident->str || !ident->str[0] || - ident->str[ident->length-1] == ' ') + DBUG_ASSERT(ident != NULL && ident->str != NULL); + + if (!ident->str[0] || ident->str[ident->length-1] == ' ') { my_error(ER_SP_WRONG_NAME, MYF(0), ident->str); return TRUE; From 3b6f9aac02b126db57fa3e3f1873713438d0a950 Mon Sep 17 00:00:00 2001 From: Nisha Gopalakrishnan Date: Fri, 22 Apr 2016 10:25:16 +0530 Subject: [PATCH 016/112] BUG#23135731: INSERT WITH DUPLICATE KEY UPDATE REPORTS INCORRECT ERROR. Analysis ======== INSERT with DUPLICATE KEY UPDATE and REPLACE on a table where foreign key constraint is defined fails with an incorrect 'duplicate entry' error rather than foreign key constraint violation error. As part of the bug fix for BUG#22037930, a new flag 'HA_CHECK_FK_ERROR' was added while checking for non fatal errors to manage FK errors based on the 'IGNORE' flag. For INSERT with DUPLICATE KEY UPDATE and REPLACE queries, the foreign key constraint violation error was marked as non-fatal, even though IGNORE was not set. Hence it continued with the duplicate key processing resulting in an incorrect error. Fix: === Foreign key violation errors are treated as non fatal only when the IGNORE is not set in the above mentioned queries. Hence reports the appropriate foreign key violation error. --- mysql-test/r/insert.result | 15 +++++++++++++++ mysql-test/t/insert.test | 22 ++++++++++++++++++++++ sql/sql_insert.cc | 23 ++++++++++++++++------- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 1aa223495931a..e840b95f1ba48 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -724,3 +724,18 @@ ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (` UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) DROP TABLE t2, t1; +# +# BUG#22037930: INSERT IGNORE FAILS TO IGNORE FOREIGN +# KEY CONSTRAINT +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= INNODB; +CREATE TABLE t2 (fld1 VARCHAR(10), fld2 INT NOT NULL, +CONSTRAINT fk FOREIGN KEY (fld2) REFERENCES t1(fld1)) ENGINE= INNODB; +# Without patch, reports incorrect error. +INSERT INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +REPLACE INTO t2 VALUES('abc', 2); +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +INSERT IGNORE INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +Warnings: +Warning 1452 `test`.`t2`, CONSTRAINT `fk` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`) +DROP TABLE t2, t1; diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index ea89872200ccc..94cf5d3b475ee 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -591,3 +591,25 @@ UPDATE t1, t2 SET t2.fld2= t2.fld2 + 3; UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; DROP TABLE t2, t1; + + +--echo # +--echo # BUG#22037930: INSERT IGNORE FAILS TO IGNORE FOREIGN +--echo # KEY CONSTRAINT + +CREATE TABLE t1 (fld1 INT PRIMARY KEY) ENGINE= INNODB; + +CREATE TABLE t2 (fld1 VARCHAR(10), fld2 INT NOT NULL, +CONSTRAINT fk FOREIGN KEY (fld2) REFERENCES t1(fld1)) ENGINE= INNODB; + +--echo # Without patch, reports incorrect error. +--error ER_NO_REFERENCED_ROW_2 +INSERT INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +--error ER_NO_REFERENCED_ROW_2 +REPLACE INTO t2 VALUES('abc', 2); + +--enable_warnings +INSERT IGNORE INTO t2 VALUES('abc', 2) ON DUPLICATE KEY UPDATE fld1= 'def'; +--disable_warnings + +DROP TABLE t2, t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a267108c84776..dc7cb69847615 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1521,16 +1521,25 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) insert_id_for_cur_row= table->file->insert_id_for_cur_row; else table->file->insert_id_for_cur_row= insert_id_for_cur_row; - bool is_duplicate_key_error; - if (table->file->is_fatal_error(error, HA_CHECK_DUP | HA_CHECK_FK_ERROR)) + + /* + If it is a FK constraint violation and 'ignore' flag is set, + report a warning instead of error. + */ + if (info->ignore && !table->file->is_fatal_error(error, + HA_CHECK_FK_ERROR)) + goto ok_or_after_trg_err; + + if (table->file->is_fatal_error(error, HA_CHECK_DUP)) goto err; - is_duplicate_key_error= table->file->is_fatal_error(error, 0); - if (!is_duplicate_key_error) + + if (!table->file->is_fatal_error(error, 0)) { /* - We come here when we had an ignorable error which is not a duplicate - key error. In this we ignore error if ignore flag is set, otherwise - report error as usual. We will not do any duplicate key processing. + We come here when we have an ignorable error which is not a duplicate + key error or FK error(Ex: Partition related errors). In this case we + ignore the error if ignore flag is set, otherwise report error as usual. + We will not do any duplicate key processing. */ if (info->ignore) goto ok_or_after_trg_err; /* Ignoring a not fatal error, return 0 */ From 72d23896d6590de7af3566e1f74f8dd1134f11f3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Apr 2016 19:06:20 +0200 Subject: [PATCH 017/112] 5.6.30 --- .../suite/perfschema/r/sizing_low.result | 1 + .../suite/perfschema/r/table_name.result | 156 +++++++++++++++++ mysql-test/suite/perfschema/t/sizing_low.test | 1 + mysql-test/suite/perfschema/t/table_name.test | 164 ++++++++++++++++++ 4 files changed, 322 insertions(+) create mode 100644 mysql-test/suite/perfschema/r/table_name.result create mode 100644 mysql-test/suite/perfschema/t/table_name.test diff --git a/mysql-test/suite/perfschema/r/sizing_low.result b/mysql-test/suite/perfschema/r/sizing_low.result index dce5a994099de..a698f55aa0787 100644 --- a/mysql-test/suite/perfschema/r/sizing_low.result +++ b/mysql-test/suite/perfschema/r/sizing_low.result @@ -67,3 +67,4 @@ Performance_schema_table_instances_lost 0 Performance_schema_thread_classes_lost 0 Performance_schema_thread_instances_lost 0 Performance_schema_users_lost 0 +CALL mtr.add_suppression("innodb_open_files should not be greater than the open_files_limit."); diff --git a/mysql-test/suite/perfschema/r/table_name.result b/mysql-test/suite/perfschema/r/table_name.result new file mode 100644 index 0000000000000..d6369ffc79e04 --- /dev/null +++ b/mysql-test/suite/perfschema/r/table_name.result @@ -0,0 +1,156 @@ + +# +# TEST 1: Normal tables prefixed with "#sql" and "sql". +# +USE test; +CREATE TABLE `#sql_1` (a int, b text); +INSERT INTO `#sql_1` VALUES(1,'one'); + +CREATE TABLE `sql_1` (a int, b text); +INSERT INTO `sql_1` VALUES(1,'one'); + +# Verify that the tables are treated as normal tables . + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name +TABLE test #sql_1 +TABLE test sql_1 + +# Drop the tables, verify that the table objects are removed. + +DROP TABLE `#sql_1`; +DROP TABLE `sql_1`; + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# +# TEST 2: Temporary tables, no special prefix. +# +CREATE TEMPORARY TABLE sql_temp2_myisam (a int, b text) ENGINE=MYISAM; +INSERT INTO sql_temp2_myisam VALUES(1,'one'); + +CREATE TEMPORARY TABLE sql_temp2_innodb (a int, b text) ENGINE=INNODB; +INSERT INTO sql_temp2_innodb VALUES(1,'one'); + +# Confirm that the temporary tables are ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# Drop the tables, verify that the table objects are not created. + +DROP TABLE sql_temp2_myisam; +DROP TABLE sql_temp2_innodb; + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# +# TEST 3: Temporary tables with the "#sql" prefix. +# +CREATE TEMPORARY TABLE `#sql_temp3_myisam` (a int, b text) ENGINE=MYISAM; +CHECK TABLE `#sql_temp3_myisam`; +Table Op Msg_type Msg_text +test.#sql_temp3_myisam check status OK +INSERT INTO `#sql_temp3_myisam` VALUES(1,'one'); + +CREATE TEMPORARY TABLE `#sql_temp3_innodb` (a int, b text) ENGINE=INNODB; +CHECK TABLE `#sql_temp3_innodb`; +Table Op Msg_type Msg_text +test.#sql_temp3_innodb check status OK +INSERT INTO `#sql_temp3_innodb` VALUES(1,'one'); + +# Confirm that the temporary tables are ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# Drop the temporary tables. + +DROP TABLE `#sql_temp3_myisam`; +DROP TABLE `#sql_temp3_innodb`; + +# Confirm that the temporary tables are still ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# +# TEST 4: Special case: MyISAM temporary tables are recreated as non-temporary +# when they are truncated. +# +CREATE TEMPORARY TABLE `sql_temp4_myisam` (a int, b text) ENGINE=MYISAM; +INSERT INTO `sql_temp4_myisam` VALUES(1,'one'); + +CREATE TEMPORARY TABLE `#sql_temp4_myisam` (a int, b text) ENGINE=MYISAM; +INSERT INTO `#sql_temp4_myisam` VALUES(1,'one'); + +# Confirm that the MyISAM temporary tables are ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# Truncate the MyISAM temporary tables, forcing them to be recreated as non-temporary. + +TRUNCATE TABLE `sql_temp4_myisam`; +TRUNCATE TABLE `#sql_temp4_myisam`; + +# Confirm that the recreated MyISAM tables are still regarded as temporary and ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# Drop the recreated MyISAM tables; + +DROP TABLE `sql_temp4_myisam`; +DROP TABLE `#sql_temp4_myisam`; + +# Confirm that the recreated temporary tables are still ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# +# TEST 5: Generate temporary tables with ALTER MyISAM table. +# +USE test; +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (1), (2), (3); +ALTER TABLE t1 ADD COLUMN (b int); + +# Confirm that the recreated temporary tables are still ignored. + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name + +# Drop the MyISAM table + +DROP TABLE t1; + +# Confirm that no tables remain; + +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +object_type object_schema object_name diff --git a/mysql-test/suite/perfschema/t/sizing_low.test b/mysql-test/suite/perfschema/t/sizing_low.test index 4d02d41aecdb7..56446fd6973ca 100644 --- a/mysql-test/suite/perfschema/t/sizing_low.test +++ b/mysql-test/suite/perfschema/t/sizing_low.test @@ -7,3 +7,4 @@ --source ../include/sizing_auto.inc +CALL mtr.add_suppression("innodb_open_files should not be greater than the open_files_limit."); diff --git a/mysql-test/suite/perfschema/t/table_name.test b/mysql-test/suite/perfschema/t/table_name.test new file mode 100644 index 0000000000000..00df678a3926d --- /dev/null +++ b/mysql-test/suite/perfschema/t/table_name.test @@ -0,0 +1,164 @@ +# +# Performance Schema +# +# Verify that the Performance Schema correctly identifies normal and temporary +# tables with non-standard names. + +# The server uses the table name prefix "#sql" for temporary and intermediate +# tables, however user-defined tables having the "#sql" prefix are also permitted. +# Independent of the table name, temporary or intermediate tables always have the +# "#sql" prefix in the filename. (For non-temporary tables starting with "#", +# the "#" is encoded to @0023 in the filename.) +# +# Given the ambiguity with temporary table names, the Performance Schema identifies +# temporary tables tables either by the table category or by the filename. +# +--source include/have_perfschema.inc +--source include/not_embedded.inc + +--echo +--echo # +--echo # TEST 1: Normal tables prefixed with "#sql" and "sql". +--echo # +USE test; +CREATE TABLE `#sql_1` (a int, b text); +# INSERT forces path through get_table_share() +INSERT INTO `#sql_1` VALUES(1,'one'); +--echo +CREATE TABLE `sql_1` (a int, b text); +INSERT INTO `sql_1` VALUES(1,'one'); +--echo +--echo # Verify that the tables are treated as normal tables . +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +--echo +--echo # Drop the tables, verify that the table objects are removed. +--echo +DROP TABLE `#sql_1`; +DROP TABLE `sql_1`; +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; + +--echo +--echo # +--echo # TEST 2: Temporary tables, no special prefix. +--echo # +CREATE TEMPORARY TABLE sql_temp2_myisam (a int, b text) ENGINE=MYISAM; +INSERT INTO sql_temp2_myisam VALUES(1,'one'); +--echo +CREATE TEMPORARY TABLE sql_temp2_innodb (a int, b text) ENGINE=INNODB; +INSERT INTO sql_temp2_innodb VALUES(1,'one'); +--echo +--echo # Confirm that the temporary tables are ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +--echo +--echo # Drop the tables, verify that the table objects are not created. +--echo +DROP TABLE sql_temp2_myisam; +DROP TABLE sql_temp2_innodb; +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; + +--echo +--echo # +--echo # TEST 3: Temporary tables with the "#sql" prefix. +--echo # +CREATE TEMPORARY TABLE `#sql_temp3_myisam` (a int, b text) ENGINE=MYISAM; +CHECK TABLE `#sql_temp3_myisam`; +INSERT INTO `#sql_temp3_myisam` VALUES(1,'one'); +--echo +CREATE TEMPORARY TABLE `#sql_temp3_innodb` (a int, b text) ENGINE=INNODB; +CHECK TABLE `#sql_temp3_innodb`; +INSERT INTO `#sql_temp3_innodb` VALUES(1,'one'); +--echo +--echo # Confirm that the temporary tables are ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +--echo +--echo # Drop the temporary tables. +--echo +DROP TABLE `#sql_temp3_myisam`; +DROP TABLE `#sql_temp3_innodb`; +--echo +--echo # Confirm that the temporary tables are still ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; + +--echo +--echo # +--echo # TEST 4: Special case: MyISAM temporary tables are recreated as non-temporary +--echo # when they are truncated. +--echo # +CREATE TEMPORARY TABLE `sql_temp4_myisam` (a int, b text) ENGINE=MYISAM; +INSERT INTO `sql_temp4_myisam` VALUES(1,'one'); +--echo +CREATE TEMPORARY TABLE `#sql_temp4_myisam` (a int, b text) ENGINE=MYISAM; +INSERT INTO `#sql_temp4_myisam` VALUES(1,'one'); +--echo +--echo # Confirm that the MyISAM temporary tables are ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +--echo +--echo # Truncate the MyISAM temporary tables, forcing them to be recreated as non-temporary. +--echo +TRUNCATE TABLE `sql_temp4_myisam`; +TRUNCATE TABLE `#sql_temp4_myisam`; +--echo +--echo # Confirm that the recreated MyISAM tables are still regarded as temporary and ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +--echo +--echo # Drop the recreated MyISAM tables; +--echo +DROP TABLE `sql_temp4_myisam`; +DROP TABLE `#sql_temp4_myisam`; +--echo +--echo # Confirm that the recreated temporary tables are still ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; + +--echo +--echo # +--echo # TEST 5: Generate temporary tables with ALTER MyISAM table. +--echo # +USE test; +CREATE TABLE t1 (a int) ENGINE=MYISAM; +INSERT INTO t1 VALUES (1), (2), (3); +# Force a path throug mysql_alter_table() and ha_create_table(). +ALTER TABLE t1 ADD COLUMN (b int); +--echo +--echo # Confirm that the recreated temporary tables are still ignored. +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; +--echo +--echo # Drop the MyISAM table +--echo +DROP TABLE t1; + +--echo +--echo # Confirm that no tables remain; +--echo +SELECT object_type, object_schema, object_name +FROM performance_schema.objects_summary_global_by_type +WHERE object_schema="test"; From 9a957a5b56005f1387aedb77509e1a0c31b7da9a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Apr 2016 20:56:25 +0200 Subject: [PATCH 018/112] move mysql-test into storage/tokudb, rename suites --- .../tokudb/mysql-test}/tokudb/bulk-fetch-gen.py | 0 .../mysql-test}/tokudb/include/cluster_key.inc | 0 .../tokudb/locks-blocking-row-locks-testgen.py | 0 .../mysql-test}/tokudb/r/auto_increment.result | 0 .../tokudb/r/auto_increment_boundary.result | 0 .../r/auto_increment_boundary_traditional.result | 0 .../tokudb/r/background_job_manager.result | Bin .../mysql-test}/tokudb/r/bf_create_select.result | 0 .../tokudb/r/bf_create_select_hash_part.result | 0 .../tokudb/r/bf_create_select_range_part.result | 0 .../tokudb/r/bf_create_temp_select.result | 0 .../tokudb/mysql-test}/tokudb/r/bf_delete.result | 0 .../mysql-test}/tokudb/r/bf_delete_trigger.result | 0 .../mysql-test}/tokudb/r/bf_insert_select.result | 0 .../tokudb/r/bf_insert_select_dup_key.result | 0 .../tokudb/r/bf_insert_select_trigger.result | 0 .../tokudb/r/bf_insert_select_update_trigger.result | 0 .../mysql-test}/tokudb/r/bf_replace_select.result | 0 .../tokudb/r/bf_replace_select_trigger.result | 0 .../mysql-test}/tokudb/r/bf_select_hash_part.result | 0 .../tokudb/r/bf_select_range_part.result | 0 .../tokudb/mysql-test}/tokudb/r/bulk-fetch.result | 0 .../tokudb/mysql-test}/tokudb/r/bulk-fetch2.result | 0 .../mysql-test}/tokudb/r/card_add_drop.result | 0 .../mysql-test}/tokudb/r/card_add_index.result | 0 .../tokudb/r/card_auto_analyze_lots.result | 0 .../mysql-test}/tokudb/r/card_drop_index.result | 0 .../mysql-test}/tokudb/r/card_drop_index_2.result | 0 .../tokudb/mysql-test}/tokudb/r/card_drop_pk.result | 0 .../tokudb/mysql-test}/tokudb/r/card_no_keys.result | 0 .../tokudb/mysql-test}/tokudb/r/card_pk.result | 0 .../tokudb/mysql-test}/tokudb/r/card_pk_2.result | 0 .../tokudb/mysql-test}/tokudb/r/card_pk_sk.result | 0 .../mysql-test}/tokudb/r/card_scale_percent.result | 0 .../tokudb/mysql-test}/tokudb/r/card_sk.result | 0 .../tokudb/mysql-test}/tokudb/r/card_sk_2.result | 0 .../mysql-test}/tokudb/r/card_unique_sk.result | 0 .../tokudb/r/change_column_all_1000_1.result | 0 .../tokudb/r/change_column_all_1000_10.result | 0 .../tokudb/r/change_column_auto_inc.result | 0 .../mysql-test}/tokudb/r/change_column_bin.result | 0 .../tokudb/r/change_column_bin_descriptor.result | 0 .../tokudb/r/change_column_bin_key.result | 0 .../tokudb/r/change_column_bin_pad.result | 0 .../tokudb/r/change_column_bin_rename.result | 0 .../mysql-test}/tokudb/r/change_column_blob.result | 0 .../tokudb/r/change_column_blob_data.result | 0 .../r/change_column_carchar_sum_cross256.result | 0 .../mysql-test}/tokudb/r/change_column_char.result | 0 .../tokudb/r/change_column_char_binary.result | 0 .../tokudb/r/change_column_char_charbinary.result | 0 .../tokudb/r/change_column_char_charset.result | 0 .../tokudb/r/change_column_char_default.result | 0 .../tokudb/r/change_column_char_descriptor.result | 0 .../tokudb/r/change_column_char_key.result | 0 .../tokudb/r/change_column_char_null.result | 0 .../tokudb/r/change_column_char_rename.result | 0 .../r/change_column_delete_change_char_5674.result | 0 .../r/change_column_delete_change_int_5674.result | 0 .../change_column_delete_change_varchar_5674.result | 0 .../mysql-test}/tokudb/r/change_column_int.result | 0 .../tokudb/r/change_column_int_default.result | 0 .../tokudb/r/change_column_int_descriptor.result | 0 .../tokudb/r/change_column_int_key.result | 0 .../tokudb/r/change_column_int_not_supported.result | 0 .../tokudb/r/change_column_int_rename.result | 0 .../tokudb/r/change_column_multiple_columns.result | 0 .../tokudb/r/change_column_multiple_int.result | 0 .../mysql-test}/tokudb/r/change_column_text.result | 0 .../tokudb/r/change_column_text_data.result | 0 .../tokudb/r/change_column_varbin.result | 0 .../tokudb/r/change_column_varbin_cross256.result | 0 .../tokudb/r/change_column_varbin_default.result | 0 .../tokudb/r/change_column_varbin_descriptor.result | 0 .../tokudb/r/change_column_varbin_key.result | 0 .../tokudb/r/change_column_varbin_multiple.result | 0 .../tokudb/r/change_column_varbin_null.result | 0 .../tokudb/r/change_column_varbin_rename.result | 0 .../tokudb/r/change_column_varbin_varchar.result | 0 .../tokudb/r/change_column_varchar.result | 0 .../tokudb/r/change_column_varchar_charset.result | 0 .../tokudb/r/change_column_varchar_cross256.result | 0 .../tokudb/r/change_column_varchar_default.result | 0 .../r/change_column_varchar_descriptor.result | 0 .../tokudb/r/change_column_varchar_key.result | 0 .../tokudb/r/change_column_varchar_null.result | 0 .../tokudb/r/change_column_varchar_prefix_a.result | 0 .../tokudb/r/change_column_varchar_prefix_b.result | 0 .../tokudb/r/change_column_varchar_rename.result | 0 .../r/change_column_varchar_sum_cross256.result | 0 .../tokudb/r/change_column_varchar_varbin.result | 0 .../tokudb/mysql-test}/tokudb/r/cluster_1829.result | 0 .../mysql-test}/tokudb/r/cluster_2968-0.result | 0 .../mysql-test}/tokudb/r/cluster_2968-1.result | 0 .../mysql-test}/tokudb/r/cluster_2968-2.result | 0 .../mysql-test}/tokudb/r/cluster_2968-3.result | 0 .../tokudb/r/cluster_create_table.result | 0 .../mysql-test}/tokudb/r/cluster_delete.result | 0 .../mysql-test}/tokudb/r/cluster_delete2.result | 0 .../mysql-test}/tokudb/r/cluster_filter.result | 0 .../tokudb/r/cluster_filter_hidden.result | 0 .../mysql-test}/tokudb/r/cluster_filter_key.result | 0 .../tokudb/r/cluster_filter_unpack_varchar.result | 0 ...ster_filter_unpack_varchar_and_int_hidden.result | 0 .../r/cluster_filter_unpack_varchar_hidden.result | 0 .../tokudb/r/cluster_filter_varchar_prefix.result | 0 .../tokudb/mysql-test}/tokudb/r/cluster_key.result | 0 .../mysql-test}/tokudb/r/cluster_key_part.result | 0 .../mysql-test}/tokudb/r/cluster_query_plan.result | 0 .../tokudb/r/cluster_tokudb_bug_993.result | 0 .../tokudb/r/cluster_tokudb_bug_993_2.result | 0 .../mysql-test}/tokudb/r/cluster_update.result | 0 .../mysql-test}/tokudb/r/cluster_update2.result | 0 .../tokudb/mysql-test}/tokudb/r/ctype_ascii.result | 0 .../mysql-test}/tokudb/r/ctype_collate.result | 0 .../mysql-test}/tokudb/r/ctype_cp1250_ch.result | 0 .../tokudb/mysql-test}/tokudb/r/ctype_cp1251.result | 0 .../mysql-test}/tokudb/r/ext_key_1_innodb.result | 0 .../mysql-test}/tokudb/r/ext_key_1_tokudb.result | 0 .../mysql-test}/tokudb/r/ext_key_2_innodb.result | 0 .../mysql-test}/tokudb/r/ext_key_2_tokudb.result | 0 .../tokudb/r/fast_update_binlog_mixed.result | 0 .../tokudb/r/fast_update_binlog_row.result | 0 .../tokudb/r/fast_update_binlog_statement.result | 0 .../mysql-test}/tokudb/r/fast_update_blobs.result | 0 .../tokudb/r/fast_update_blobs_fixed_varchar.result | 0 .../tokudb/r/fast_update_blobs_with_varchar.result | 0 .../mysql-test}/tokudb/r/fast_update_char.result | 0 .../tokudb/r/fast_update_deadlock.result | 0 .../tokudb/r/fast_update_decr_floor.result | 0 .../tokudb/r/fast_update_disable_slow_update.result | 0 .../mysql-test}/tokudb/r/fast_update_error.result | 0 .../mysql-test}/tokudb/r/fast_update_int.result | 0 .../tokudb/r/fast_update_int_bounds.result | 0 .../mysql-test}/tokudb/r/fast_update_key.result | 0 .../mysql-test}/tokudb/r/fast_update_sqlmode.result | 0 .../tokudb/r/fast_update_uint_bounds.result | 0 .../mysql-test}/tokudb/r/fast_update_varchar.result | 0 .../mysql-test}/tokudb/r/fast_upsert_bin_pad.result | Bin .../mysql-test}/tokudb/r/fast_upsert_char.result | 0 .../tokudb/r/fast_upsert_deadlock.result | 0 .../mysql-test}/tokudb/r/fast_upsert_int.result | 0 .../mysql-test}/tokudb/r/fast_upsert_key.result | 0 .../mysql-test}/tokudb/r/fast_upsert_sqlmode.result | 0 .../mysql-test}/tokudb/r/fast_upsert_values.result | 0 .../mysql-test}/tokudb/r/hotindex-del-0.result | 0 .../mysql-test}/tokudb/r/hotindex-del-1.result | 0 .../mysql-test}/tokudb/r/hotindex-del-fast.result | 0 .../mysql-test}/tokudb/r/hotindex-del-slow.result | 0 .../mysql-test}/tokudb/r/hotindex-insert-0.result | 0 .../mysql-test}/tokudb/r/hotindex-insert-1.result | 0 .../mysql-test}/tokudb/r/hotindex-insert-2.result | 0 .../tokudb/r/hotindex-insert-bigchar.result | 0 .../mysql-test}/tokudb/r/hotindex-update-0.result | 0 .../mysql-test}/tokudb/r/hotindex-update-1.result | 0 .../tokudb/r/i_s_tokudb_lock_waits_released.result | 0 .../tokudb/r/i_s_tokudb_lock_waits_timeout.result | 0 .../mysql-test}/tokudb/r/i_s_tokudb_locks.result | 0 .../tokudb/r/i_s_tokudb_locks_released.result | 0 .../mysql-test}/tokudb/r/i_s_tokudb_trx.result | 0 .../r/information-schema-global-status.result | 0 .../tokudb/r/lockretry-insert.writelocktable.result | 0 .../tokudb/r/lockretry-writelocktable.insert.result | 0 .../r/lockretry-writelocktable.insert2.result | 0 .../tokudb/r/locks-blocking-row-locks-getset.result | 0 .../tokudb/r/locks-blocking-row-locks-race.result | 0 .../tokudb/r/locks-blocking-row-locks.result | 0 .../tokudb/r/locks-delete-deadlock-1.result | 0 ...ocks-no-read-lock-serializable-autocommit.result | 0 .../tokudb/r/locks-select-update-1.result | 0 .../tokudb/r/locks-select-update-2.result | 0 .../tokudb/r/locks-select-update-3.result | 0 .../tokudb/r/locks-update-deadlock-1.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-1.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-10.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-11.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-12.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-13.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-14.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-15.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-16.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-17.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-18.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-19.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-2.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-20.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-21.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-22.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-23.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-24.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-25.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-26.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-27.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-28.result | 0 .../tokudb/r/mvcc-2808-read-committed.result | 0 .../tokudb/r/mvcc-2808-read-uncommitted.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-29.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-3.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-30.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-31.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-33.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-34.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-35.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-36.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-37.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-38.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-39.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-4.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-40.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-5.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-6.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-7.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-8.result | 0 .../tokudb/mysql-test}/tokudb/r/mvcc-9.result | 0 .../mysql-test}/tokudb/r/mvcc-checksum-locks.result | 0 .../tokudb/r/nested_txn_autocommit.result | 0 .../mysql-test}/tokudb/r/nested_txn_begin.result | 0 .../tokudb/r/nested_txn_implicit_commit.result | 0 .../tokudb/mysql-test}/tokudb/r/prim_key_1.result | 0 .../tokudb/mysql-test}/tokudb/r/prim_key_2.result | 0 .../tokudb/mysql-test}/tokudb/r/prim_key_3.result | 0 .../tokudb/mysql-test}/tokudb/r/prim_key_4.result | 0 .../tokudb/mysql-test}/tokudb/r/prim_key_5.result | 0 .../tokudb/mysql-test}/tokudb/r/prim_key_6.result | 0 .../mysql-test}/tokudb/r/replace-ignore.result | 0 .../tokudb/mysql-test}/tokudb/r/rows-32m-0.result | 0 .../tokudb/mysql-test}/tokudb/r/rows-32m-1.result | 0 .../tokudb/r/rows-32m-rand-insert.result | 0 .../mysql-test}/tokudb/r/rows-32m-seq-insert.result | 0 .../mysql-test}/tokudb/r/savepoint-1078-2.result | 0 .../mysql-test}/tokudb/r/savepoint-1078-3.result | 0 .../mysql-test}/tokudb/r/savepoint-1078-4.result | 0 .../mysql-test}/tokudb/r/savepoint-1078.result | 0 .../tokudb/mysql-test}/tokudb/r/savepoint-2.result | 0 .../tokudb/mysql-test}/tokudb/r/savepoint-3.result | 0 .../tokudb/mysql-test}/tokudb/r/savepoint-4.result | 0 .../tokudb/mysql-test}/tokudb/r/savepoint-5.result | 0 .../mysql-test}/tokudb/r/simple_delete_all.result | 0 .../tokudb/r/simple_join_tokudb_innodb.result | 0 .../tokudb/r/simple_join_tokudb_myisam.result | 0 .../mysql-test}/tokudb/r/simple_truncate.result | 0 .../mysql-test}/tokudb/r/sql_mode_default.result | 0 .../tokudb/r/storage_engine_default.result | 0 .../mysql-test}/tokudb/r/tokudb_support_xa.result | 0 .../mysql-test}/tokudb/r/truncate_row_count.result | 0 .../mysql-test}/tokudb/r/truncate_txn_commit.result | 0 .../tokudb/r/truncate_txn_rollback.result | 0 .../tokudb/r/truncate_txn_rollback_innodb.result | 0 .../tokudb/mysql-test}/tokudb/r/type_binary.result | 0 .../tokudb/mysql-test}/tokudb/r/type_bit.result | 0 .../mysql-test}/tokudb/r/type_bit_innodb.result | 0 .../tokudb/mysql-test}/tokudb/r/type_blob.result | 0 .../tokudb/mysql-test}/tokudb/r/type_date.result | 0 .../mysql-test}/tokudb/r/type_datetime.result | 0 .../tokudb/mysql-test}/tokudb/r/type_decimal.result | 0 .../tokudb/mysql-test}/tokudb/r/type_enum.result | 0 .../tokudb/mysql-test}/tokudb/r/type_float.result | 0 .../tokudb/mysql-test}/tokudb/r/type_nchar.result | 0 .../mysql-test}/tokudb/r/type_newdecimal-big.result | 0 .../mysql-test}/tokudb/r/type_newdecimal.result | 0 .../tokudb/mysql-test}/tokudb/r/type_ranges.result | 0 .../tokudb/mysql-test}/tokudb/r/type_set.result | 0 .../tokudb/r/type_temporal_fractional.result | 0 .../tokudb/r/type_temporal_upgrade.result | 0 .../tokudb/mysql-test}/tokudb/r/type_time.result | 0 .../mysql-test}/tokudb/r/type_timestamp.result | 0 .../tokudb/r/type_timestamp_explicit.result | 0 .../tokudb/mysql-test}/tokudb/r/type_uint.result | 0 .../tokudb/mysql-test}/tokudb/r/type_varchar.result | 0 .../tokudb/mysql-test}/tokudb/r/type_year.result | 0 .../tokudb/mysql-test}/tokudb/replace-ignore-gen.py | 0 .../tokudb/mysql-test}/tokudb/t/auto_increment.test | 0 .../tokudb/t/auto_increment_boundary.test | 0 .../t/auto_increment_boundary_traditional.test | 0 .../tokudb/t/background_job_manager.test | 0 .../mysql-test}/tokudb/t/bf_create_select.test | 0 .../tokudb/t/bf_create_select_hash_part.test | 0 .../tokudb/t/bf_create_select_range_part.test | 0 .../mysql-test}/tokudb/t/bf_create_temp_select.test | 0 .../tokudb/mysql-test}/tokudb/t/bf_delete.test | 0 .../mysql-test}/tokudb/t/bf_delete_trigger.test | 0 .../mysql-test}/tokudb/t/bf_insert_select.test | 0 .../tokudb/t/bf_insert_select_dup_key.test | 0 .../tokudb/t/bf_insert_select_trigger.test | 0 .../tokudb/t/bf_insert_select_update_trigger.test | 0 .../mysql-test}/tokudb/t/bf_replace_select.test | 0 .../tokudb/t/bf_replace_select_trigger.test | 0 .../mysql-test}/tokudb/t/bf_select_hash_part.test | 0 .../mysql-test}/tokudb/t/bf_select_range_part.test | 0 .../tokudb/mysql-test}/tokudb/t/bulk-fetch.test | 0 .../tokudb/mysql-test}/tokudb/t/bulk-fetch2.test | 0 .../tokudb/mysql-test}/tokudb/t/card_add_drop.test | 0 .../tokudb/mysql-test}/tokudb/t/card_add_index.test | 0 .../tokudb/t/card_auto_analyze_lots.test | 0 .../mysql-test}/tokudb/t/card_drop_index.test | 0 .../mysql-test}/tokudb/t/card_drop_index_2.test | 0 .../tokudb/mysql-test}/tokudb/t/card_drop_pk.test | 0 .../tokudb/mysql-test}/tokudb/t/card_no_keys.test | 0 .../tokudb/mysql-test}/tokudb/t/card_pk.test | 0 .../tokudb/mysql-test}/tokudb/t/card_pk_2.test | 0 .../tokudb/mysql-test}/tokudb/t/card_pk_sk.test | 0 .../mysql-test}/tokudb/t/card_scale_percent.test | 0 .../tokudb/mysql-test}/tokudb/t/card_sk.test | 0 .../tokudb/mysql-test}/tokudb/t/card_sk_2.test | 0 .../tokudb/mysql-test}/tokudb/t/card_unique_sk.test | 0 .../mysql-test}/tokudb/t/change_column_Makefile | 0 .../mysql-test}/tokudb/t/change_column_all.py | 0 .../tokudb/t/change_column_all_1000_1.test | 0 .../tokudb/t/change_column_all_1000_10.test | 0 .../tokudb/t/change_column_auto_inc.test | 0 .../mysql-test}/tokudb/t/change_column_bin.py | 0 .../mysql-test}/tokudb/t/change_column_bin.test | 0 .../tokudb/t/change_column_bin_descriptor.test | 0 .../mysql-test}/tokudb/t/change_column_bin_key.test | 0 .../mysql-test}/tokudb/t/change_column_bin_pad.test | 0 .../tokudb/t/change_column_bin_rename.py | 0 .../tokudb/t/change_column_bin_rename.test | 0 .../mysql-test}/tokudb/t/change_column_blob.py | 0 .../mysql-test}/tokudb/t/change_column_blob.test | 0 .../mysql-test}/tokudb/t/change_column_blob_data.py | 0 .../tokudb/t/change_column_blob_data.test | 0 .../mysql-test}/tokudb/t/change_column_char.py | 0 .../mysql-test}/tokudb/t/change_column_char.test | 0 .../tokudb/t/change_column_char_binary.py | 0 .../tokudb/t/change_column_char_binary.test | 0 .../tokudb/t/change_column_char_charbinary.py | 0 .../tokudb/t/change_column_char_charbinary.test | 0 .../tokudb/t/change_column_char_charset.test | 0 .../tokudb/t/change_column_char_default.test | 0 .../tokudb/t/change_column_char_descriptor.test | 0 .../tokudb/t/change_column_char_key.test | 0 .../tokudb/t/change_column_char_null.test | 0 .../tokudb/t/change_column_char_rename.py | 0 .../tokudb/t/change_column_char_rename.test | 0 .../t/change_column_delete_change_char_5674.test | 0 .../t/change_column_delete_change_int_5674.test | 0 .../t/change_column_delete_change_varchar_5674.test | 0 .../mysql-test}/tokudb/t/change_column_int.py | 0 .../mysql-test}/tokudb/t/change_column_int.test | 0 .../tokudb/t/change_column_int_default.test | 0 .../tokudb/t/change_column_int_descriptor.test | 0 .../mysql-test}/tokudb/t/change_column_int_key.py | 0 .../mysql-test}/tokudb/t/change_column_int_key.test | 0 .../tokudb/t/change_column_int_not_supported.py | 0 .../tokudb/t/change_column_int_not_supported.test | 0 .../tokudb/t/change_column_int_rename.py | 0 .../tokudb/t/change_column_int_rename.test | 0 .../tokudb/t/change_column_multiple_columns.py | 0 .../tokudb/t/change_column_multiple_columns.test | 0 .../mysql-test}/tokudb/t/change_column_text.py | 0 .../mysql-test}/tokudb/t/change_column_text.test | 0 .../tokudb/t/change_column_text_data.test | 0 .../mysql-test}/tokudb/t/change_column_varbin.test | 0 .../tokudb/t/change_column_varbin_cross256.test | 0 .../tokudb/t/change_column_varbin_default.test | 0 .../tokudb/t/change_column_varbin_descriptor.test | 0 .../tokudb/t/change_column_varbin_key.test | 0 .../tokudb/t/change_column_varbin_multiple.test | 0 .../tokudb/t/change_column_varbin_null.test | 0 .../tokudb/t/change_column_varbin_rename.test | 0 .../tokudb/t/change_column_varbin_varchar.test | 0 .../mysql-test}/tokudb/t/change_column_varchar.test | 0 .../tokudb/t/change_column_varchar_charset.test | 0 .../tokudb/t/change_column_varchar_cross256.test | 0 .../tokudb/t/change_column_varchar_default.test | 0 .../tokudb/t/change_column_varchar_descriptor.test | 0 .../tokudb/t/change_column_varchar_key.test | 0 .../tokudb/t/change_column_varchar_null.test | 0 .../tokudb/t/change_column_varchar_prefix_a.test | 0 .../tokudb/t/change_column_varchar_prefix_b.test | 0 .../tokudb/t/change_column_varchar_rename.test | 0 .../t/change_column_varchar_sum_cross256.test | 0 .../tokudb/t/change_column_varchar_varbin.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_1829.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_2968-0.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_2968-1.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_2968-2.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_2968-3.test | 0 .../mysql-test}/tokudb/t/cluster_create_table.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_delete.test | 0 .../mysql-test}/tokudb/t/cluster_delete2.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_filter.test | 0 .../mysql-test}/tokudb/t/cluster_filter_hidden.test | 0 .../mysql-test}/tokudb/t/cluster_filter_key.test | 0 .../tokudb/t/cluster_filter_unpack_varchar.test | 0 ...luster_filter_unpack_varchar_and_int_hidden.test | 0 .../t/cluster_filter_unpack_varchar_hidden.test | 0 .../tokudb/t/cluster_filter_varchar_prefix.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_key.test | 0 .../mysql-test}/tokudb/t/cluster_key_part.test | 0 .../mysql-test}/tokudb/t/cluster_query_plan.test | 0 .../tokudb/t/cluster_tokudb_bug_993.test | 0 .../tokudb/t/cluster_tokudb_bug_993_2.test | 0 .../tokudb/mysql-test}/tokudb/t/cluster_update.test | 0 .../mysql-test}/tokudb/t/cluster_update2.test | 0 .../tokudb/mysql-test}/tokudb/t/ctype_ascii.test | 0 .../tokudb/mysql-test}/tokudb/t/ctype_collate.test | 0 .../mysql-test}/tokudb/t/ctype_cp1250_ch.test | 0 .../tokudb/mysql-test}/tokudb/t/ctype_cp1251.test | 0 .../tokudb/mysql-test}/tokudb/t/disabled.def | 0 .../mysql-test}/tokudb/t/ext_key_1_innodb.test | 0 .../mysql-test}/tokudb/t/ext_key_1_tokudb.test | 0 .../mysql-test}/tokudb/t/ext_key_2_innodb.test | 0 .../mysql-test}/tokudb/t/ext_key_2_tokudb.test | 0 .../mysql-test}/tokudb/t/fast_update_Makefile | 0 .../tokudb/t/fast_update_binlog_mixed.test | 0 .../tokudb/t/fast_update_binlog_row.test | 0 .../tokudb/t/fast_update_binlog_statement.test | 0 .../mysql-test}/tokudb/t/fast_update_blobs.py | 0 .../mysql-test}/tokudb/t/fast_update_blobs.test | 0 .../tokudb/t/fast_update_blobs_fixed_varchar.py | 0 .../tokudb/t/fast_update_blobs_fixed_varchar.test | 0 .../tokudb/t/fast_update_blobs_with_varchar.py | 0 .../tokudb/t/fast_update_blobs_with_varchar.test | 0 .../mysql-test}/tokudb/t/fast_update_char.test | 0 .../mysql-test}/tokudb/t/fast_update_deadlock.test | 0 .../mysql-test}/tokudb/t/fast_update_decr_floor.py | 0 .../tokudb/t/fast_update_decr_floor.test | 0 .../tokudb/t/fast_update_disable_slow_update.test | 0 .../mysql-test}/tokudb/t/fast_update_error.test | 0 .../tokudb/mysql-test}/tokudb/t/fast_update_int.py | 0 .../mysql-test}/tokudb/t/fast_update_int.test | 0 .../tokudb/t/fast_update_int_bounds.test | 0 .../mysql-test}/tokudb/t/fast_update_key.test | 0 .../mysql-test}/tokudb/t/fast_update_sqlmode.test | 0 .../tokudb/t/fast_update_uint_bounds.test | 0 .../mysql-test}/tokudb/t/fast_update_varchar.py | 0 .../mysql-test}/tokudb/t/fast_update_varchar.test | 0 .../mysql-test}/tokudb/t/fast_upsert_bin_pad.test | 0 .../mysql-test}/tokudb/t/fast_upsert_char.test | 0 .../mysql-test}/tokudb/t/fast_upsert_deadlock.test | 0 .../tokudb/mysql-test}/tokudb/t/fast_upsert_int.py | 0 .../mysql-test}/tokudb/t/fast_upsert_int.test | 0 .../mysql-test}/tokudb/t/fast_upsert_key.test | 0 .../mysql-test}/tokudb/t/fast_upsert_sqlmode.test | 0 .../mysql-test}/tokudb/t/fast_upsert_values.test | 0 .../tokudb/mysql-test}/tokudb/t/hotindex-del-0.test | 0 .../tokudb/mysql-test}/tokudb/t/hotindex-del-1.test | 0 .../mysql-test}/tokudb/t/hotindex-del-fast.test | 0 .../mysql-test}/tokudb/t/hotindex-del-slow.test | 0 .../mysql-test}/tokudb/t/hotindex-insert-0.test | 0 .../mysql-test}/tokudb/t/hotindex-insert-1.test | 0 .../mysql-test}/tokudb/t/hotindex-insert-2.test | 0 .../tokudb/t/hotindex-insert-bigchar.test | 0 .../mysql-test}/tokudb/t/hotindex-update-0.test | 0 .../mysql-test}/tokudb/t/hotindex-update-1.test | 0 .../tokudb/t/i_s_tokudb_lock_waits_released.test | 0 .../tokudb/t/i_s_tokudb_lock_waits_timeout.test | 0 .../mysql-test}/tokudb/t/i_s_tokudb_locks.test | 0 .../tokudb/t/i_s_tokudb_locks_released.test | 0 .../tokudb/mysql-test}/tokudb/t/i_s_tokudb_trx.test | 0 .../tokudb/t/information-schema-global-status.test | 0 .../tokudb/t/lockretry-insert.writelocktable.test | 0 .../tokudb/t/lockretry-writelocktable.insert.test | 0 .../tokudb/t/lockretry-writelocktable.insert2.test | 0 .../tokudb/t/locks-blocking-row-locks-getset.test | 0 .../tokudb/t/locks-blocking-row-locks.test | 0 .../tokudb/t/locks-border-locks.notyet.3981 | 0 .../tokudb/t/locks-delete-deadlock-1.test | 0 .../locks-no-read-lock-serializable-autocommit.test | 0 .../mysql-test}/tokudb/t/locks-select-update-1.test | 0 .../mysql-test}/tokudb/t/locks-select-update-2.test | 0 .../mysql-test}/tokudb/t/locks-select-update-3.test | 0 .../tokudb/t/locks-update-deadlock-1.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-1.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-10.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-11.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-12.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-13.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-14.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-15.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-16.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-17.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-18.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-19.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-2.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-20.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-21.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-22.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-23.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-24.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-25.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-26.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-27.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-28.test | 0 .../tokudb/t/mvcc-2808-read-committed.test | 0 .../tokudb/t/mvcc-2808-read-uncommitted.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-29.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-3.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-30.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-31.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-33.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-34.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-35.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-36.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-37.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-38.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-39.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-4.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-40.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-5.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-6.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-7.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-8.test | 0 .../tokudb/mysql-test}/tokudb/t/mvcc-9.test | 0 .../mysql-test}/tokudb/t/mvcc-checksum-locks.test | 0 .../mysql-test}/tokudb/t/nested_txn_autocommit.test | 0 .../mysql-test}/tokudb/t/nested_txn_begin.test | 0 .../tokudb/t/nested_txn_implicit_commit.test | 0 .../tokudb/mysql-test}/tokudb/t/prim_key_1.test | 0 .../tokudb/mysql-test}/tokudb/t/prim_key_2.test | 0 .../tokudb/mysql-test}/tokudb/t/prim_key_3.test | 0 .../tokudb/mysql-test}/tokudb/t/prim_key_4.test | 0 .../tokudb/mysql-test}/tokudb/t/prim_key_5.test | 0 .../tokudb/mysql-test}/tokudb/t/prim_key_6.test | 0 .../tokudb/mysql-test}/tokudb/t/replace-ignore.test | 0 .../tokudb/mysql-test}/tokudb/t/rows-32m-0.test | 0 .../tokudb/mysql-test}/tokudb/t/rows-32m-1.test | 0 .../mysql-test}/tokudb/t/rows-32m-rand-insert.test | 0 .../mysql-test}/tokudb/t/rows-32m-seq-insert.test | 0 .../mysql-test}/tokudb/t/savepoint-1078-2.test | 0 .../mysql-test}/tokudb/t/savepoint-1078-3.test | 0 .../mysql-test}/tokudb/t/savepoint-1078-4.test | 0 .../tokudb/mysql-test}/tokudb/t/savepoint-1078.test | 0 .../tokudb/mysql-test}/tokudb/t/savepoint-2.test | 0 .../tokudb/mysql-test}/tokudb/t/savepoint-3.test | 0 .../tokudb/mysql-test}/tokudb/t/savepoint-4.test | 0 .../tokudb/mysql-test}/tokudb/t/savepoint-5.test | 0 .../mysql-test}/tokudb/t/simple_delete_all.test | 0 .../tokudb/t/simple_join_tokudb_innodb.test | 0 .../tokudb/t/simple_join_tokudb_myisam.test | 0 .../mysql-test}/tokudb/t/simple_truncate.test | 0 .../mysql-test}/tokudb/t/sql_mode_default.test | 0 .../tokudb/t/storage_engine_default.test | 0 .../tokudb/mysql-test/tokudb}/t/suite.opt | 0 .../mysql-test}/tokudb/t/tokudb_support_xa.test | 0 .../mysql-test}/tokudb/t/truncate_row_count.test | 0 .../mysql-test}/tokudb/t/truncate_txn_commit.test | 0 .../mysql-test}/tokudb/t/truncate_txn_rollback.test | 0 .../tokudb/t/truncate_txn_rollback_innodb.test | 0 .../tokudb/mysql-test}/tokudb/t/type_binary.test | 0 .../tokudb/mysql-test}/tokudb/t/type_bit.test | 0 .../mysql-test}/tokudb/t/type_bit_innodb.test | 0 .../tokudb/mysql-test}/tokudb/t/type_blob.test | 0 .../tokudb/mysql-test}/tokudb/t/type_date.test | 0 .../tokudb/mysql-test}/tokudb/t/type_datetime.test | 0 .../tokudb/mysql-test}/tokudb/t/type_decimal.test | 0 .../tokudb/mysql-test}/tokudb/t/type_enum.test | 0 .../tokudb/mysql-test}/tokudb/t/type_float.test | 0 .../tokudb/mysql-test}/tokudb/t/type_nchar.test | 0 .../mysql-test}/tokudb/t/type_newdecimal-big.test | 0 .../mysql-test}/tokudb/t/type_newdecimal.test | 0 .../tokudb/mysql-test}/tokudb/t/type_ranges.test | 0 .../tokudb/mysql-test}/tokudb/t/type_set.test | 0 .../tokudb/t/type_temporal_fractional.test | 0 .../mysql-test}/tokudb/t/type_temporal_upgrade.test | 0 .../tokudb/mysql-test}/tokudb/t/type_time.test | 0 .../mysql-test}/tokudb/t/type_timestamp-master.opt | 0 .../tokudb/mysql-test}/tokudb/t/type_timestamp.test | 0 .../tokudb/t/type_timestamp_explicit-master.opt | 0 .../tokudb/t/type_timestamp_explicit.test | 0 .../tokudb/mysql-test}/tokudb/t/type_uint.test | 0 .../tokudb/mysql-test}/tokudb/t/type_varchar.test | 0 .../tokudb/mysql-test}/tokudb/t/type_year.test | 0 .../mysql-test/tokudb_add_index}/r/1522.result | 0 .../tokudb_add_index}/r/add_index_1.result | 0 .../tokudb_add_index}/r/add_index_10.result | 0 .../tokudb_add_index}/r/add_index_11.result | 0 .../tokudb_add_index}/r/add_index_12.result | 0 .../tokudb_add_index}/r/add_index_13.result | 0 .../tokudb_add_index}/r/add_index_14.result | 0 .../tokudb_add_index}/r/add_index_15.result | 0 .../tokudb_add_index}/r/add_index_16.result | 0 .../tokudb_add_index}/r/add_index_17.result | 0 .../tokudb_add_index}/r/add_index_18.result | 0 .../tokudb_add_index}/r/add_index_2.result | 0 .../tokudb_add_index}/r/add_index_3.result | 0 .../tokudb_add_index}/r/add_index_4.result | 0 .../tokudb_add_index}/r/add_index_5.result | 0 .../tokudb_add_index}/r/add_index_6.result | 0 .../tokudb_add_index}/r/add_index_7.result | 0 .../tokudb_add_index}/r/add_index_8.result | 0 .../tokudb_add_index}/r/add_index_9.result | 0 .../tokudb_add_index}/r/falcon_bug_22516.result | 0 .../tokudb_add_index}/r/falcon_bug_23691.result | 0 .../tokudb_add_index}/r/falcon_bug_23692.result | 0 .../tokudb_add_index}/r/falcon_bug_23818_1.result | 0 .../tokudb_add_index}/r/falcon_bug_23818_2.result | 0 .../tokudb_add_index}/r/falcon_bug_23818_A.result | 0 .../tokudb_add_index}/r/falcon_bug_23818_B.result | 0 .../tokudb_add_index}/r/falcon_bug_23818_C.result | 0 .../r/hot_create_unique_index.result | 0 .../tokudb_add_index}/r/tokudb_bug_1152.result | 0 .../tokudb/mysql-test/tokudb_add_index}/t/1522.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_1.test | 0 .../tokudb_add_index}/t/add_index_10.test | 0 .../tokudb_add_index}/t/add_index_11.test | 0 .../tokudb_add_index}/t/add_index_12.test | 0 .../tokudb_add_index}/t/add_index_13.test | 0 .../tokudb_add_index}/t/add_index_14.test | 0 .../tokudb_add_index}/t/add_index_15.test | 0 .../tokudb_add_index}/t/add_index_16.test | 0 .../tokudb_add_index}/t/add_index_17.test | 0 .../tokudb_add_index}/t/add_index_18.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_2.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_3.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_4.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_5.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_6.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_7.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_8.test | 0 .../mysql-test/tokudb_add_index}/t/add_index_9.test | 0 .../tokudb_add_index}/t/falcon_bug_22516.test | 0 .../tokudb_add_index}/t/falcon_bug_23691.test | 0 .../tokudb_add_index}/t/falcon_bug_23692.test | 0 .../tokudb_add_index}/t/falcon_bug_23818_1.test | 0 .../tokudb_add_index}/t/falcon_bug_23818_2.test | 0 .../tokudb_add_index}/t/falcon_bug_23818_A.test | 0 .../tokudb_add_index}/t/falcon_bug_23818_B.test | 0 .../tokudb_add_index}/t/falcon_bug_23818_C.test | 0 .../t/hot_create_unique_index.test | 0 .../tokudb/mysql-test/tokudb_add_index}/t/suite.opt | 0 .../tokudb_add_index}/t/tokudb_bug_1152.test | 0 .../mysql-test/tokudb_alter_table}/r/4630.result | 0 .../mysql-test/tokudb_alter_table}/r/5260.result | 0 .../mysql-test/tokudb_alter_table}/r/ai_aui.result | 0 .../mysql-test/tokudb_alter_table}/r/ai_di.result | 0 .../mysql-test/tokudb_alter_table}/r/ai_part.result | 0 .../r/alter_column_default.result | 0 .../tokudb_alter_table}/r/auto_inc.result | 0 .../mysql-test/tokudb_alter_table}/r/di_dui.result | 0 .../tokudb_alter_table}/r/drop_add_pk_104.result | 0 .../r/drop_add_pk_part_104.result | 0 .../r/drop_pk_with_prefix.result | 0 .../tokudb_alter_table}/r/frm_discover.result | 0 .../r/frm_discover_partition.result | 0 .../tokudb_alter_table}/r/hcad_all_add.result | 0 .../tokudb_alter_table}/r/hcad_all_add2.result | 0 .../tokudb_alter_table}/r/hcad_all_add3.result | 0 .../tokudb_alter_table}/r/hcad_all_blob_add.result | 0 .../tokudb_alter_table}/r/hcad_all_blob_drop.result | 0 .../tokudb_alter_table}/r/hcad_all_drop.result | 0 .../tokudb_alter_table}/r/hcad_all_fixed_add.result | 0 .../r/hcad_all_fixed_drop.result | 0 .../tokudb_alter_table}/r/hcad_all_var_add.result | 0 .../tokudb_alter_table}/r/hcad_all_var_drop.result | 0 .../r/hcad_and_rename_table.result | 0 .../tokudb_alter_table}/r/hcad_clustering.result | 0 .../tokudb_alter_table}/r/hcad_clustering2.result | 0 .../r/hcad_diff_num_offset_bytes.result | 0 .../tokudb_alter_table}/r/hcad_drop_char0_t6.result | 0 .../tokudb_alter_table}/r/hcad_fixedblob_add.result | 0 .../r/hcad_fixedblob_add2.result | 0 .../r/hcad_fixedblob_drop.result | 0 .../tokudb_alter_table}/r/hcad_fixedvar_add.result | 0 .../tokudb_alter_table}/r/hcad_fixedvar_add2.result | 0 .../tokudb_alter_table}/r/hcad_fixedvar_drop.result | 0 .../tokudb_alter_table}/r/hcad_indexing_mix.result | 0 .../tokudb_alter_table}/r/hcad_null_bits.result | 0 .../tokudb_alter_table}/r/hcad_part.result | 0 .../mysql-test/tokudb_alter_table}/r/hcad_pk.result | 0 .../tokudb_alter_table}/r/hcad_pk2.result | 0 .../tokudb_alter_table}/r/hcad_template.result | 0 .../tokudb_alter_table}/r/hcad_tmp_tables.result | 0 .../tokudb_alter_table}/r/hcad_tmp_tables_56.result | 0 .../tokudb_alter_table}/r/hcad_varblob_add.result | 0 .../tokudb_alter_table}/r/hcad_varblob_add2.result | 0 .../tokudb_alter_table}/r/hcad_varblob_drop.result | 0 .../tokudb_alter_table}/r/hcad_with_dels.result | 0 .../tokudb_alter_table}/r/hcad_with_lock_sps.result | 0 .../tokudb_alter_table}/r/hcad_with_locks.result | 0 .../mysql-test/tokudb_alter_table}/r/hcr.result | 0 .../mysql-test/tokudb_alter_table}/r/hcr2.result | 0 .../mysql-test/tokudb_alter_table}/r/hcr3.result | 0 .../tokudb_alter_table}/r/hcr_binary1.result | 0 .../tokudb_alter_table}/r/hcr_blob.result | 0 .../tokudb_alter_table}/r/hcr_char1.result | 0 .../tokudb_alter_table}/r/hcr_enum.result | 0 .../tokudb_alter_table}/r/hcr_text.result | 0 .../tokudb_alter_table}/r/hcr_time.result | 0 .../r/hot_row_format_alter.result | 0 .../tokudb_alter_table}/r/mod_enum.result | 0 .../tokudb_alter_table}/r/null_bytes_add_key.result | 0 .../r/null_bytes_col_rename.result | 0 .../r/null_bytes_drop_default.result | 0 .../r/null_bytes_drop_key.result | 0 .../tokudb_alter_table}/r/other_alter.result | 0 .../tokudb_alter_table}/r/other_alter2.result | 0 .../r/rename_column_cold_104.result | 0 .../r/rename_column_cold_part_104.result | 0 .../tokudb_alter_table}/r/row_format_alter.result | 0 .../r/test_field_same_detection.result | Bin .../tokudb_alter_table}/r/virtual_columns.result | 0 .../mysql-test/tokudb_alter_table}/t/4630.test | 0 .../mysql-test/tokudb_alter_table}/t/5260.test | 0 .../mysql-test/tokudb_alter_table}/t/ai_aui.test | 0 .../mysql-test/tokudb_alter_table}/t/ai_di.test | 0 .../mysql-test/tokudb_alter_table}/t/ai_part.test | 0 .../tokudb_alter_table}/t/alter_column_default.test | 0 .../mysql-test/tokudb_alter_table}/t/auto_inc.test | 0 .../mysql-test/tokudb_alter_table}/t/di_dui.test | 0 .../mysql-test/tokudb_alter_table}/t/disabled.def | 0 .../tokudb_alter_table}/t/drop_add_pk_104.test | 0 .../tokudb_alter_table}/t/drop_add_pk_part_104.test | 0 .../tokudb_alter_table}/t/drop_pk_with_prefix.test | 0 .../tokudb_alter_table}/t/frm_discover.test | 0 .../t/frm_discover_partition.test | 0 .../tokudb_alter_table}/t/hcad_all_add.test | 0 .../tokudb_alter_table}/t/hcad_all_add2.test | 0 .../tokudb_alter_table}/t/hcad_all_add3.test | 0 .../tokudb_alter_table}/t/hcad_all_blob_add.test | 0 .../tokudb_alter_table}/t/hcad_all_blob_drop.test | 0 .../tokudb_alter_table}/t/hcad_all_drop.test | 0 .../tokudb_alter_table}/t/hcad_all_fixed_add.test | 0 .../tokudb_alter_table}/t/hcad_all_fixed_drop.test | 0 .../tokudb_alter_table}/t/hcad_all_var_add.test | 0 .../tokudb_alter_table}/t/hcad_all_var_drop.test | 0 .../t/hcad_and_rename_table.test | 0 .../tokudb_alter_table}/t/hcad_clustering.test | 0 .../tokudb_alter_table}/t/hcad_clustering2.test | 0 .../t/hcad_diff_num_offset_bytes.test | 0 .../tokudb_alter_table}/t/hcad_drop_char0_t6.test | 0 .../tokudb_alter_table}/t/hcad_fixedblob_add.test | 0 .../tokudb_alter_table}/t/hcad_fixedblob_add2.test | 0 .../tokudb_alter_table}/t/hcad_fixedblob_drop.test | 0 .../tokudb_alter_table}/t/hcad_fixedvar_add.test | 0 .../tokudb_alter_table}/t/hcad_fixedvar_add2.test | 0 .../tokudb_alter_table}/t/hcad_fixedvar_drop.test | 0 .../tokudb_alter_table}/t/hcad_indexing_mix.test | 0 .../tokudb_alter_table}/t/hcad_null_bits.test | 0 .../mysql-test/tokudb_alter_table}/t/hcad_part.test | 0 .../mysql-test/tokudb_alter_table}/t/hcad_pk.test | 0 .../mysql-test/tokudb_alter_table}/t/hcad_pk2.test | 0 .../tokudb_alter_table}/t/hcad_template.test | 0 .../tokudb_alter_table}/t/hcad_tmp_tables.test | 0 .../tokudb_alter_table}/t/hcad_tmp_tables_56.test | 0 .../tokudb_alter_table}/t/hcad_varblob_add.test | 0 .../tokudb_alter_table}/t/hcad_varblob_add2.test | 0 .../tokudb_alter_table}/t/hcad_varblob_drop.test | 0 .../tokudb_alter_table}/t/hcad_with_dels.test | 0 .../tokudb_alter_table}/t/hcad_with_lock_sps.test | 0 .../tokudb_alter_table}/t/hcad_with_locks.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr2.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr3.test | 0 .../tokudb_alter_table}/t/hcr_binary1.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr_blob.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr_char1.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr_enum.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr_text.test | 0 .../mysql-test/tokudb_alter_table}/t/hcr_time.test | 0 .../tokudb_alter_table}/t/hot_row_format_alter.test | 0 .../mysql-test/tokudb_alter_table}/t/mod_enum.test | 0 .../tokudb_alter_table}/t/null_bytes_add_key.test | 0 .../t/null_bytes_col_rename.test | 0 .../t/null_bytes_drop_default.test | 0 .../tokudb_alter_table}/t/null_bytes_drop_key.test | 0 .../tokudb_alter_table}/t/other_alter.test | 0 .../tokudb_alter_table}/t/other_alter2.test | 0 .../t/rename_column_cold_104.test | 0 .../t/rename_column_cold_part_104.test | 0 .../tokudb_alter_table}/t/row_format_alter.test | 0 .../mysql-test/tokudb_alter_table}/t/suite.opt | 0 .../t/test_field_same_detection.test | 0 .../tokudb_alter_table}/t/virtual_columns.test | 0 .../tokudb_backup}/r/tokudb_backup_exclude.result | 0 .../r/tokudb_backup_set_last_error.result | 0 .../tokudb/mysql-test/tokudb_backup}/t/suite.opt | 0 .../tokudb_backup}/t/tokudb_backup_exclude.test | 0 .../t/tokudb_backup_set_last_error.test | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1648.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1684.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1711.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1795.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1833.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1853.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1872.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1883.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1913.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1938.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/1949.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2043.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2219.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2262.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2383.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2458.result | 0 .../tokudb_bugs}/r/2494-read-committed.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2548.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2641.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2952.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2970.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/2970i.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3014.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3015.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3083.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3441.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3478.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3486.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/3518.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4175.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4260.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4472.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4618.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4633.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4648.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4656.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4656_2.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/4675.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5003.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5089.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5469.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5554.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5585.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5695.result | 0 .../mysql-test/tokudb_bugs}/r/5733_innodb.result | 0 .../mysql-test/tokudb_bugs}/r/5733_tokudb.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5951.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5974-2.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/5974.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/6053.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/6684.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/889.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/895.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/94.result | 0 .../r/alter_external_lock_assert.result | 0 .../tokudb_bugs}/r/alter_part_tokudb_bug_155.result | 0 .../tokudb_bugs}/r/alter_table_copy_table.result | 0 .../mysql-test/tokudb_bugs}/r/bulk_fetch.result | 0 .../tokudb_bugs}/r/checkpoint_lock.result | 0 .../tokudb_bugs}/r/checkpoint_lock_2.result | 0 .../tokudb_bugs}/r/checkpoint_lock_3.result | 0 .../tokudb_bugs}/r/commit_index_end_1.result | 0 .../tokudb_bugs}/r/commit_index_end_2.result | 0 .../tokudb_bugs}/r/db397_delete_trigger.result | 0 .../tokudb_bugs}/r/db397_insert_trigger.result | 0 .../tokudb_bugs}/r/db397_update_trigger.result | 0 .../mysql-test/tokudb_bugs}/r/db739_insert.result | 0 .../mysql-test/tokudb_bugs}/r/db739_replace.result | 0 .../mysql-test/tokudb_bugs}/r/db739_upsert.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db743.result | 0 .../tokudb_bugs}/r/db756_card_part_hash.result | 0 .../tokudb_bugs}/r/db756_card_part_hash_1.result | 0 .../r/db756_card_part_hash_1_pick.result | 0 .../tokudb_bugs}/r/db756_card_part_hash_2.result | 0 .../r/db756_card_part_hash_2_pick.result | 0 .../tokudb_bugs}/r/db757_part_alter_analyze.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db762.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db766.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db768.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db771.result | 0 .../tokudb_bugs}/r/db788-optimize-index-name.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db801.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db805.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db806.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db811.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db811s.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db817.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/db823.result | 0 .../mysql-test/tokudb_bugs}/r/dict_leak_3518.result | 0 .../tokudb_bugs}/r/expand_tinytext_text.result | 0 .../mysql-test/tokudb_bugs}/r/fileops-2.result | 0 .../mysql-test/tokudb_bugs}/r/fileops-3.result | 0 .../mysql-test/tokudb_bugs}/r/fileops-4.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/fileops.result | 0 .../mysql-test/tokudb_bugs}/r/frm_store.result | 0 .../mysql-test/tokudb_bugs}/r/frm_store2.result | 0 .../mysql-test/tokudb_bugs}/r/frm_store3.result | 0 .../mysql-test/tokudb_bugs}/r/ft-index-40.result | 0 .../mysql-test/tokudb_bugs}/r/index_read.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/leak172.result | 0 .../tokudb_bugs}/r/lock_uniq_key_empty.result | 0 .../tokudb_bugs}/r/lock_uniq_key_left.result | 0 .../tokudb_bugs}/r/lock_uniq_key_middle.result | 0 .../tokudb_bugs}/r/lock_uniq_key_right.result | 0 .../mysql-test/tokudb_bugs}/r/mdev4533.result | 0 .../mysql-test/tokudb_bugs}/r/mdev5932.result | 0 .../r/optimize_temp_table_tokudb.result | 0 .../tokudb_bugs}/r/rpl_mixed_replace_into.result | 0 .../tokudb_bugs}/r/rpl_row_replace_into.result | 0 .../tokudb_bugs}/r/rpl_stmt_replace_into.result | 0 .../mysql-test/tokudb_bugs}/r/simple_icp.result | 0 .../r/subselect_index_next_same_bug_157.result | 0 .../mysql-test/tokudb_bugs}/r/tokudb718.result | 0 .../r/tokudb_drop_part_table_668.result | 0 .../r/tokudb_drop_simple_table_668.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa-1.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa-2.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa-3.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa-4.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa-5.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa-6.result | 0 .../tokudb/mysql-test/tokudb_bugs}/r/xa.result | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1648.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1684.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1711.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1795.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1833.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1853.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1872.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1883.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1913.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1938.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/1949.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2043.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2219.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2262.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2383.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2458.test | 0 .../tokudb_bugs}/t/2494-read-committed.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2548.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2641.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2952.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2970.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/2970i.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3014.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3015.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3083.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3441.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3478.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3486.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/3518.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4175.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4260.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4472.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4618.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4633.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4648.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4656.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4656_2.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/4675.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5003.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5089.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5469.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5554.test | 0 .../mysql-test/tokudb_bugs}/t/5585-master.opt | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5585.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5695.test | 0 .../mysql-test/tokudb_bugs}/t/5733_innodb.test | 0 .../mysql-test/tokudb_bugs}/t/5733_tokudb.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5951.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5974-2.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/5974.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/6053.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/6684.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/889.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/895.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/94.test | 0 .../tokudb_bugs}/t/alter_external_lock_assert.test | 0 .../tokudb_bugs}/t/alter_part_tokudb_bug_155.test | 0 .../tokudb_bugs}/t/alter_table_copy_table.test | 0 .../mysql-test/tokudb_bugs}/t/bulk_fetch.test | 0 .../mysql-test/tokudb_bugs}/t/checkpoint_lock.test | 0 .../tokudb_bugs}/t/checkpoint_lock_2.test | 0 .../tokudb_bugs}/t/checkpoint_lock_3.test | 0 .../tokudb_bugs}/t/commit_index_end_1.test | 0 .../tokudb_bugs}/t/commit_index_end_2.test | 0 .../tokudb_bugs}/t/db397_delete_trigger.test | 0 .../tokudb_bugs}/t/db397_insert_trigger.test | 0 .../tokudb_bugs}/t/db397_update_trigger.test | 0 .../mysql-test/tokudb_bugs}/t/db739_insert.test | 0 .../mysql-test/tokudb_bugs}/t/db739_replace.test | 0 .../mysql-test/tokudb_bugs}/t/db739_upsert.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db743.test | 0 .../tokudb_bugs}/t/db756_card_part_hash.test | 0 .../tokudb_bugs}/t/db756_card_part_hash_1.test | 0 .../tokudb_bugs}/t/db756_card_part_hash_1_pick.test | 0 .../tokudb_bugs}/t/db756_card_part_hash_2.test | 0 .../tokudb_bugs}/t/db756_card_part_hash_2_pick.test | 0 .../tokudb_bugs}/t/db757_part_alter_analyze.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db762.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db766.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db768.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db771.test | 0 .../tokudb_bugs}/t/db788-optimize-index-name.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db801.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db805.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db806.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db811.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db811s.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db817.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/db823.test | 0 .../mysql-test/tokudb_bugs}/t/dict_leak_3518.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/disabled.def | 0 .../tokudb_bugs}/t/expand_tinytext_text.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/fileops-2.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/fileops-3.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/fileops-4.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/fileops.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/frm_store.test | 0 .../mysql-test/tokudb_bugs}/t/frm_store2.test | 0 .../mysql-test/tokudb_bugs}/t/frm_store3.test | 0 .../mysql-test/tokudb_bugs}/t/ft-index-40.test | 0 .../mysql-test/tokudb_bugs}/t/index_read.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/leak172.test | 0 .../tokudb_bugs}/t/lock_uniq_key_empty.test | 0 .../tokudb_bugs}/t/lock_uniq_key_left.test | 0 .../tokudb_bugs}/t/lock_uniq_key_middle.test | 0 .../tokudb_bugs}/t/lock_uniq_key_right.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/mdev4533.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/mdev5932.test | 0 .../tokudb_bugs}/t/optimize_temp_table_tokudb.test | 0 .../tokudb_bugs}/t/rpl_mixed_replace_into.test | 0 .../tokudb_bugs}/t/rpl_row_replace_into.test | 0 .../tokudb_bugs}/t/rpl_stmt_replace_into.test | 0 .../mysql-test/tokudb_bugs}/t/simple_icp.test | 0 .../t/subselect_index_next_same_bug_157.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/suite.opt | 0 .../tokudb/mysql-test/tokudb_bugs}/t/tokudb718.test | 0 .../tokudb_bugs}/t/tokudb_drop_part_table_668.test | 0 .../t/tokudb_drop_simple_table_668.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa-1.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa-2.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa-3.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa-4.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa-5.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa-6.test | 0 .../tokudb/mysql-test/tokudb_bugs}/t/xa.test | 0 .../r/part_blocked_sql_func_tokudb.result | 0 .../r/part_supported_sql_func_tokudb.result | 0 .../r/partition_alter1_1_2_tokudb.result | 0 .../r/partition_alter1_1_tokudb.result | 0 .../r/partition_alter1_2_tokudb.result | 0 .../r/partition_alter2_1_1_tokudb.result | 0 .../r/partition_alter2_1_2_tokudb.result | 0 .../r/partition_alter2_2_1_tokudb.result | 0 .../r/partition_alter2_2_2_tokudb.result | 0 .../tokudb_parts}/r/partition_alter3_tokudb.result | 0 .../tokudb_parts}/r/partition_alter4_tokudb.result | 0 .../r/partition_auto_increment_tokudb.result | 0 .../r/partition_basic_symlink_tokudb.result | 0 .../tokudb_parts}/r/partition_basic_tokudb.result | 0 .../tokudb_parts}/r/partition_bit_tokudb.result | 0 .../tokudb_parts}/r/partition_char_tokudb.result | 0 .../r/partition_datetime_tokudb.result | 0 .../r/partition_debug_sync_tokudb.result | 0 .../tokudb_parts}/r/partition_debug_tokudb.result | 0 .../tokudb_parts}/r/partition_decimal_tokudb.result | 0 .../tokudb_parts}/r/partition_engine_tokudb.result | 0 .../r/partition_exch_myisam_tokudb.result | 0 .../r/partition_exch_qa_1_tokudb.result | 0 .../r/partition_exch_qa_4_tokudb.result | 0 .../r/partition_exch_qa_5_tokudb.result | 0 .../r/partition_exch_qa_7_tokudb.result | 0 .../r/partition_exch_qa_8_tokudb.result | 0 .../tokudb_parts}/r/partition_exch_tokudb.result | 0 .../r/partition_exchange_tokudb.result | 0 .../tokudb_parts}/r/partition_float_tokudb.result | 0 .../tokudb_parts}/r/partition_int_tokudb.result | 0 .../r/partition_max_parts_hash_tokudb.result | 0 .../r/partition_max_parts_inv_tokudb.result | 0 .../r/partition_max_parts_key_tokudb.result | 0 .../r/partition_max_parts_list_tokudb.result | 0 .../r/partition_max_parts_range_tokudb.result | 0 .../partition_max_sub_parts_key_list_tokudb.result | 0 .../partition_max_sub_parts_key_range_tokudb.result | 0 .../r/partition_max_sub_parts_list_tokudb.result | 0 .../r/partition_max_sub_parts_range_tokudb.result | 0 .../tokudb_parts}/r/partition_mgm_lc0_tokudb.result | 0 .../r/partition_mgm_lc10_tokudb.result | 0 .../tokudb_parts}/r/partition_mgm_lc1_tokudb.result | 0 .../tokudb_parts}/r/partition_mgm_lc2_tokudb.result | 0 .../r/partition_reorganize_tokudb.result | 0 .../tokudb_parts}/r/partition_special_tokudb.result | 0 .../tokudb_parts}/r/partition_syntax_tokudb.result | 0 .../tokudb_parts}/r/partition_value_tokudb.result | 0 .../tokudb/mysql-test/tokudb_parts}/t/disabled.def | 0 .../t/part_blocked_sql_func_tokudb.test | 0 .../t/part_supported_sql_func_tokudb.test | 0 .../t/partition_alter1_1_2_tokudb.test | 0 .../tokudb_parts}/t/partition_alter1_1_tokudb.test | 0 .../tokudb_parts}/t/partition_alter1_2_tokudb.test | 0 .../t/partition_alter2_1_1_tokudb.test | 0 .../t/partition_alter2_1_2_tokudb.test | 0 .../t/partition_alter2_2_1_tokudb.test | 0 .../t/partition_alter2_2_2_tokudb.test | 0 .../tokudb_parts}/t/partition_alter3_tokudb.test | 0 .../tokudb_parts}/t/partition_alter4_tokudb.test | 0 .../t/partition_auto_increment_tokudb.test | 0 .../t/partition_basic_symlink_tokudb.test | 0 .../tokudb_parts}/t/partition_basic_tokudb.test | 0 .../tokudb_parts}/t/partition_bit_tokudb.test | 0 .../tokudb_parts}/t/partition_char_tokudb.test | 0 .../tokudb_parts}/t/partition_datetime_tokudb.test | 0 .../t/partition_debug_sync_tokudb-master.opt | 0 .../t/partition_debug_sync_tokudb.test | 0 .../t/partition_debug_tokudb-master.opt | 0 .../tokudb_parts}/t/partition_debug_tokudb.test | 0 .../tokudb_parts}/t/partition_decimal_tokudb.test | 0 .../tokudb_parts}/t/partition_engine_tokudb.test | 0 .../t/partition_exch_myisam_tokudb.test | 0 .../tokudb_parts}/t/partition_exch_qa_1_tokudb.test | 0 .../tokudb_parts}/t/partition_exch_qa_4_tokudb.test | 0 .../tokudb_parts}/t/partition_exch_qa_5_tokudb.test | 0 .../tokudb_parts}/t/partition_exch_qa_7_tokudb.test | 0 .../tokudb_parts}/t/partition_exch_qa_8_tokudb.test | 0 .../tokudb_parts}/t/partition_exch_tokudb.test | 0 .../tokudb_parts}/t/partition_exchange_tokudb.test | 0 .../tokudb_parts}/t/partition_float_tokudb.test | 0 .../tokudb_parts}/t/partition_int_tokudb.test | 0 .../t/partition_max_parts_hash_tokudb-master.opt | 0 .../t/partition_max_parts_hash_tokudb.test | 0 .../t/partition_max_parts_inv_tokudb-master.opt | 0 .../t/partition_max_parts_inv_tokudb.test | 0 .../t/partition_max_parts_key_tokudb-master.opt | 0 .../t/partition_max_parts_key_tokudb.test | 0 .../t/partition_max_parts_list_tokudb-master.opt | 0 .../t/partition_max_parts_list_tokudb.test | 0 .../t/partition_max_parts_range_tokudb-master.opt | 0 .../t/partition_max_parts_range_tokudb.test | 0 ...rtition_max_sub_parts_key_list_tokudb-master.opt | 0 .../t/partition_max_sub_parts_key_list_tokudb.test | 0 ...tition_max_sub_parts_key_range_tokudb-master.opt | 0 .../t/partition_max_sub_parts_key_range_tokudb.test | 0 .../partition_max_sub_parts_list_tokudb-master.opt | 0 .../t/partition_max_sub_parts_list_tokudb.test | 0 .../partition_max_sub_parts_range_tokudb-master.opt | 0 .../t/partition_max_sub_parts_range_tokudb.test | 0 .../tokudb_parts}/t/partition_mgm_lc0_tokudb.test | 0 .../tokudb_parts}/t/partition_mgm_lc10_tokudb.test | 0 .../t/partition_mgm_lc1_tokudb-master.opt | 0 .../tokudb_parts}/t/partition_mgm_lc1_tokudb.test | 0 .../t/partition_mgm_lc2_tokudb-master.opt | 0 .../tokudb_parts}/t/partition_mgm_lc2_tokudb.test | 0 .../t/partition_reorganize_tokudb.test | 0 .../t/partition_special_tokudb-master.opt | 0 .../tokudb_parts}/t/partition_special_tokudb.test | 0 .../tokudb_parts}/t/partition_syntax_tokudb.test | 0 .../t/partition_tokudb_status_file-master.opt | 0 .../tokudb_parts}/t/partition_value_tokudb.test | 0 .../tokudb/mysql-test/tokudb_parts}/t/suite.opt | 0 .../tokudb/mysql-test/tokudb_rpl}/combinations | 0 .../tokudb_rpl}/r/rpl_deadlock_tokudb.result | 0 .../r/rpl_extra_col_master_tokudb.result | 0 .../tokudb_rpl}/r/rpl_extra_col_slave_tokudb.result | 0 .../tokudb_rpl}/r/rpl_foreign_key_tokudb.result | 0 .../tokudb_rpl}/r/rpl_mixed_row_tokudb.result | 0 .../tokudb_rpl}/r/rpl_not_null_tokudb.result | 0 .../tokudb_rpl}/r/rpl_parallel_tokudb.result | 0 .../r/rpl_parallel_tokudb_delete_pk.result | 0 ...rpl_parallel_tokudb_update_pk_uc0_lookup0.result | 0 .../r/rpl_parallel_tokudb_write_pk.result | 0 .../tokudb_rpl}/r/rpl_partition_tokudb.result | 0 .../tokudb_rpl}/r/rpl_relay_space_tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_basic_3tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_blob_tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_log_tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_rec_comp_tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_sp002_tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_sp007_tokudb.result | 0 .../tokudb_rpl}/r/rpl_row_tabledefs_3tokudb.result | 0 .../tokudb_rpl}/r/rpl_set_null_tokudb.result | 0 .../mysql-test/tokudb_rpl}/r/rpl_stm_tokudb.result | 0 .../tokudb_rpl}/r/rpl_tokudb_bug28430.result | 0 .../tokudb_rpl}/r/rpl_tokudb_bug30888.result | 0 .../tokudb_rpl}/r/rpl_tokudb_delete_pk.result | 0 .../r/rpl_tokudb_delete_pk_lookup1.result | 0 .../tokudb_rpl}/r/rpl_tokudb_mixed_ddl.result | 0 .../tokudb_rpl}/r/rpl_tokudb_mixed_dml.result | 0 .../tokudb_rpl}/r/rpl_tokudb_read_only_ff.result | 0 .../tokudb_rpl}/r/rpl_tokudb_read_only_ft.result | 0 .../tokudb_rpl}/r/rpl_tokudb_read_only_tf.result | 0 .../tokudb_rpl}/r/rpl_tokudb_read_only_tt.result | 0 .../r/rpl_tokudb_update_pk_uc0_lookup0.result | 0 .../r/rpl_tokudb_update_pk_uc0_lookup1.result | 0 .../r/rpl_tokudb_update_pk_uc1_lookup0.result | 0 .../r/rpl_tokudb_update_pk_uc1_lookup1.result | 0 .../r/rpl_tokudb_update_unique_uc0_lookup0.result | 0 .../r/rpl_tokudb_update_unique_uc0_lookup1.result | 0 .../tokudb_rpl}/r/rpl_tokudb_write_pk.result | 0 .../tokudb_rpl}/r/rpl_tokudb_write_pk_uc1.result | 0 .../tokudb_rpl}/r/rpl_tokudb_write_unique.result | 0 .../r/rpl_tokudb_write_unique_uc1.result | 0 .../tokudb_rpl}/r/rpl_truncate_3tokudb.result | 0 .../tokudb_rpl}/r/rpl_typeconv_tokudb.result | 0 .../tokudb_rpl}/r/tokudb_innodb_xa_crash.result | 0 .../tokudb/mysql-test/tokudb_rpl}/t/disabled.def | 0 .../tokudb_rpl}/t/rpl_deadlock_tokudb-slave.opt | 0 .../tokudb_rpl}/t/rpl_deadlock_tokudb.test | 0 .../tokudb_rpl}/t/rpl_extra_col_master_tokudb.test | 0 .../tokudb_rpl}/t/rpl_extra_col_slave_tokudb.test | 0 .../tokudb_rpl}/t/rpl_foreign_key_tokudb.test | 0 .../tokudb_rpl}/t/rpl_mixed_row_tokudb-master.opt | 0 .../tokudb_rpl}/t/rpl_not_null_tokudb.test | 0 .../tokudb_rpl}/t/rpl_parallel_tokudb-master.opt | 0 .../tokudb_rpl}/t/rpl_parallel_tokudb-slave.opt | 0 .../tokudb_rpl}/t/rpl_parallel_tokudb.test | 0 .../t/rpl_parallel_tokudb_delete_pk-slave.opt | 0 .../t/rpl_parallel_tokudb_delete_pk.test | 0 ..._parallel_tokudb_update_pk_uc0_lookup0-slave.opt | 0 .../rpl_parallel_tokudb_update_pk_uc0_lookup0.test | 0 .../t/rpl_parallel_tokudb_write_pk-slave.opt | 0 .../tokudb_rpl}/t/rpl_parallel_tokudb_write_pk.test | 0 .../tokudb_rpl}/t/rpl_partition_tokudb-master.opt | 0 .../tokudb_rpl}/t/rpl_partition_tokudb.test | 0 .../tokudb_rpl}/t/rpl_relay_space_tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_basic_3tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_blob_tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_log_tokudb-master.opt | 0 .../tokudb_rpl}/t/rpl_row_log_tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_rec_comp_tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_sp002_tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_sp007_tokudb.test | 0 .../tokudb_rpl}/t/rpl_row_tabledefs_3tokudb.test | 0 .../tokudb_rpl}/t/rpl_set_null_tokudb.test | 0 .../mysql-test/tokudb_rpl}/t/rpl_stm_tokudb.test | 0 .../mysql-test/tokudb_rpl}/t/rpl_tokudb-master.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_bug28430-master.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_bug28430-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_bug28430.test | 0 .../tokudb_rpl}/t/rpl_tokudb_bug30888.test | 0 .../tokudb_rpl}/t/rpl_tokudb_delete_pk-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_delete_pk.test | 0 .../t/rpl_tokudb_delete_pk_lookup1-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_delete_pk_lookup1.test | 0 .../tokudb_rpl}/t/rpl_tokudb_mixed_ddl.test | 0 .../tokudb_rpl}/t/rpl_tokudb_mixed_dml.test | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_ff-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_ff.test | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_ft-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_ft.test | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_tf-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_tf.test | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_tt-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_read_only_tt.test | 0 .../t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt | 0 .../t/rpl_tokudb_update_pk_uc0_lookup0.test | 0 .../t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt | 0 .../t/rpl_tokudb_update_pk_uc0_lookup1.test | 0 .../t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt | 0 .../t/rpl_tokudb_update_pk_uc1_lookup0.test | 0 .../t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt | 0 .../t/rpl_tokudb_update_pk_uc1_lookup1.test | 0 .../rpl_tokudb_update_unique_uc0_lookup0-slave.opt | 0 .../t/rpl_tokudb_update_unique_uc0_lookup0.test | 0 .../rpl_tokudb_update_unique_uc0_lookup1-slave.opt | 0 .../t/rpl_tokudb_update_unique_uc0_lookup1.test | 0 .../tokudb_rpl}/t/rpl_tokudb_write_pk-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_write_pk.test | 0 .../tokudb_rpl}/t/rpl_tokudb_write_pk_uc1-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_write_pk_uc1.test | 0 .../tokudb_rpl}/t/rpl_tokudb_write_unique-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_write_unique.test | 0 .../t/rpl_tokudb_write_unique_uc1-slave.opt | 0 .../tokudb_rpl}/t/rpl_tokudb_write_unique_uc1.test | 0 .../tokudb_rpl}/t/rpl_truncate_3tokudb.test | 0 .../tokudb_rpl}/t/rpl_typeconv_tokudb.test | 0 .../tokudb/mysql-test/tokudb_rpl}/t/suite.opt | 0 .../tokudb_rpl}/t/tokudb_innodb_xa_crash-slave.opt | 0 .../tokudb_rpl}/t/tokudb_innodb_xa_crash.test | 0 .../r/tokudb_analyze_delete_fraction.result | 0 .../r/tokudb_analyze_in_background_basic.result | 0 .../r/tokudb_analyze_mode_basic.result | 0 .../r/tokudb_analyze_throttle_basic.result | 0 .../r/tokudb_analyze_time_basic.result | 0 .../tokudb_sys_vars}/r/tokudb_auto_analyze.result | 0 .../r/tokudb_cardinality_scale_percent_basic.result | 0 .../tokudb/mysql-test/tokudb_sys_vars}/t/suite.opt | 0 .../t/tokudb_analyze_delete_fraction.test | 0 .../t/tokudb_analyze_in_background_basic.test | 0 .../t/tokudb_analyze_mode_basic.test | 0 .../t/tokudb_analyze_throttle_basic.test | 0 .../t/tokudb_analyze_time_basic.test | 0 .../tokudb_sys_vars}/t/tokudb_auto_analyze.test | 0 .../t/tokudb_cardinality_scale_percent_basic.test | 0 1264 files changed, 0 insertions(+), 0 deletions(-) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/bulk-fetch-gen.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/include/cluster_key.inc (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/locks-blocking-row-locks-testgen.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/auto_increment.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/auto_increment_boundary.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/auto_increment_boundary_traditional.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/background_job_manager.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_create_select.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_create_select_hash_part.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_create_select_range_part.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_create_temp_select.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_delete.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_delete_trigger.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_insert_select.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_insert_select_dup_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_insert_select_trigger.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_insert_select_update_trigger.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_replace_select.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_replace_select_trigger.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_select_hash_part.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bf_select_range_part.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bulk-fetch.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/bulk-fetch2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_add_drop.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_add_index.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_auto_analyze_lots.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_drop_index.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_drop_index_2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_drop_pk.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_no_keys.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_pk.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_pk_2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_pk_sk.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_scale_percent.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_sk.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_sk_2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/card_unique_sk.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_all_1000_1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_all_1000_10.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_auto_inc.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_bin.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_bin_descriptor.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_bin_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_bin_pad.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_bin_rename.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_blob.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_blob_data.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_carchar_sum_cross256.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_binary.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_charbinary.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_charset.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_default.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_descriptor.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_null.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_char_rename.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_delete_change_char_5674.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_delete_change_int_5674.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_delete_change_varchar_5674.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_int.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_int_default.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_int_descriptor.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_int_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_int_not_supported.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_int_rename.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_multiple_columns.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_multiple_int.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_text.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_text_data.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_cross256.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_default.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_descriptor.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_multiple.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_null.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_rename.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varbin_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_charset.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_cross256.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_default.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_descriptor.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_null.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_prefix_a.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_prefix_b.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_rename.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_sum_cross256.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/change_column_varchar_varbin.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_1829.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_2968-0.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_2968-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_2968-2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_2968-3.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_create_table.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_delete.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_delete2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter_hidden.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter_unpack_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter_unpack_varchar_hidden.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_filter_varchar_prefix.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_key_part.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_query_plan.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_tokudb_bug_993.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_tokudb_bug_993_2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_update.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/cluster_update2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ctype_ascii.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ctype_collate.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ctype_cp1250_ch.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ctype_cp1251.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ext_key_1_innodb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ext_key_1_tokudb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ext_key_2_innodb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/ext_key_2_tokudb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_binlog_mixed.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_binlog_row.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_binlog_statement.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_blobs.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_blobs_fixed_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_blobs_with_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_char.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_deadlock.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_decr_floor.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_disable_slow_update.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_error.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_int.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_int_bounds.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_sqlmode.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_uint_bounds.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_update_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_bin_pad.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_char.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_deadlock.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_int.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_key.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_sqlmode.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/fast_upsert_values.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-del-0.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-del-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-del-fast.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-del-slow.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-insert-0.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-insert-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-insert-2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-insert-bigchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-update-0.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/hotindex-update-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/i_s_tokudb_lock_waits_released.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/i_s_tokudb_lock_waits_timeout.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/i_s_tokudb_locks.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/i_s_tokudb_locks_released.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/i_s_tokudb_trx.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/information-schema-global-status.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/lockretry-insert.writelocktable.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/lockretry-writelocktable.insert.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/lockretry-writelocktable.insert2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-blocking-row-locks-getset.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-blocking-row-locks-race.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-blocking-row-locks.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-delete-deadlock-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-no-read-lock-serializable-autocommit.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-select-update-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-select-update-2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-select-update-3.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/locks-update-deadlock-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-10.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-11.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-12.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-13.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-14.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-15.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-16.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-17.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-18.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-19.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-20.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-21.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-22.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-23.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-24.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-25.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-26.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-27.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-28.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-2808-read-committed.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-2808-read-uncommitted.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-29.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-3.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-30.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-31.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-33.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-34.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-35.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-36.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-37.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-38.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-39.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-4.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-40.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-5.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-6.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-7.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-8.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-9.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/mvcc-checksum-locks.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/nested_txn_autocommit.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/nested_txn_begin.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/nested_txn_implicit_commit.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/prim_key_1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/prim_key_2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/prim_key_3.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/prim_key_4.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/prim_key_5.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/prim_key_6.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/replace-ignore.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/rows-32m-0.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/rows-32m-1.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/rows-32m-rand-insert.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/rows-32m-seq-insert.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-1078-2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-1078-3.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-1078-4.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-1078.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-2.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-3.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-4.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/savepoint-5.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/simple_delete_all.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/simple_join_tokudb_innodb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/simple_join_tokudb_myisam.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/simple_truncate.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/sql_mode_default.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/storage_engine_default.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/tokudb_support_xa.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/truncate_row_count.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/truncate_txn_commit.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/truncate_txn_rollback.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/truncate_txn_rollback_innodb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_binary.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_bit.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_bit_innodb.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_blob.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_date.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_datetime.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_decimal.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_enum.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_float.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_nchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_newdecimal-big.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_newdecimal.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_ranges.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_set.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_temporal_fractional.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_temporal_upgrade.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_time.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_timestamp.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_timestamp_explicit.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_uint.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_varchar.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/r/type_year.result (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/replace-ignore-gen.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/auto_increment.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/auto_increment_boundary.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/auto_increment_boundary_traditional.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/background_job_manager.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_create_select.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_create_select_hash_part.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_create_select_range_part.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_create_temp_select.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_delete.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_delete_trigger.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_insert_select.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_insert_select_dup_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_insert_select_trigger.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_insert_select_update_trigger.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_replace_select.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_replace_select_trigger.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_select_hash_part.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bf_select_range_part.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bulk-fetch.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/bulk-fetch2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_add_drop.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_add_index.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_auto_analyze_lots.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_drop_index.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_drop_index_2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_drop_pk.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_no_keys.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_pk.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_pk_2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_pk_sk.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_scale_percent.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_sk.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_sk_2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/card_unique_sk.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_Makefile (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_all.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_all_1000_1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_all_1000_10.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_auto_inc.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin_descriptor.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin_pad.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin_rename.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_bin_rename.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_blob.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_blob.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_blob_data.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_blob_data.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_binary.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_binary.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_charbinary.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_charbinary.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_charset.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_default.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_descriptor.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_null.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_rename.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_char_rename.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_delete_change_char_5674.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_delete_change_int_5674.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_delete_change_varchar_5674.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_default.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_descriptor.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_key.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_not_supported.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_not_supported.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_rename.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_int_rename.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_multiple_columns.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_multiple_columns.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_text.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_text.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_text_data.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_cross256.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_default.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_descriptor.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_multiple.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_null.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_rename.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varbin_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_charset.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_cross256.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_default.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_descriptor.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_null.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_prefix_a.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_prefix_b.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_rename.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_sum_cross256.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/change_column_varchar_varbin.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_1829.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_2968-0.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_2968-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_2968-2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_2968-3.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_create_table.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_delete.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_delete2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter_hidden.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter_unpack_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter_unpack_varchar_hidden.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_filter_varchar_prefix.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_key_part.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_query_plan.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_tokudb_bug_993.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_tokudb_bug_993_2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_update.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/cluster_update2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ctype_ascii.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ctype_collate.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ctype_cp1250_ch.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ctype_cp1251.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/disabled.def (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ext_key_1_innodb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ext_key_1_tokudb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ext_key_2_innodb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/ext_key_2_tokudb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_Makefile (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_binlog_mixed.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_binlog_row.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_binlog_statement.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_blobs.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_blobs.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_blobs_fixed_varchar.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_blobs_fixed_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_blobs_with_varchar.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_blobs_with_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_char.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_deadlock.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_decr_floor.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_decr_floor.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_disable_slow_update.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_error.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_int.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_int.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_int_bounds.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_sqlmode.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_uint_bounds.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_varchar.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_update_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_bin_pad.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_char.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_deadlock.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_int.py (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_int.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_key.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_sqlmode.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/fast_upsert_values.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-del-0.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-del-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-del-fast.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-del-slow.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-insert-0.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-insert-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-insert-2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-insert-bigchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-update-0.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/hotindex-update-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/i_s_tokudb_lock_waits_released.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/i_s_tokudb_lock_waits_timeout.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/i_s_tokudb_locks.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/i_s_tokudb_locks_released.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/i_s_tokudb_trx.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/information-schema-global-status.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/lockretry-insert.writelocktable.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/lockretry-writelocktable.insert.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/lockretry-writelocktable.insert2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-blocking-row-locks-getset.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-blocking-row-locks.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-border-locks.notyet.3981 (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-delete-deadlock-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-no-read-lock-serializable-autocommit.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-select-update-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-select-update-2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-select-update-3.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/locks-update-deadlock-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-10.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-11.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-12.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-13.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-14.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-15.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-16.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-17.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-18.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-19.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-20.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-21.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-22.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-23.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-24.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-25.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-26.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-27.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-28.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-2808-read-committed.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-2808-read-uncommitted.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-29.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-3.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-30.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-31.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-33.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-34.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-35.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-36.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-37.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-38.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-39.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-4.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-40.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-5.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-6.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-7.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-8.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-9.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/mvcc-checksum-locks.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/nested_txn_autocommit.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/nested_txn_begin.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/nested_txn_implicit_commit.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/prim_key_1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/prim_key_2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/prim_key_3.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/prim_key_4.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/prim_key_5.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/prim_key_6.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/replace-ignore.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/rows-32m-0.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/rows-32m-1.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/rows-32m-rand-insert.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/rows-32m-seq-insert.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-1078-2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-1078-3.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-1078-4.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-1078.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-2.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-3.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-4.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/savepoint-5.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/simple_delete_all.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/simple_join_tokudb_innodb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/simple_join_tokudb_myisam.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/simple_truncate.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/sql_mode_default.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/storage_engine_default.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb}/t/suite.opt (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/tokudb_support_xa.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/truncate_row_count.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/truncate_txn_commit.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/truncate_txn_rollback.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/truncate_txn_rollback_innodb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_binary.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_bit.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_bit_innodb.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_blob.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_date.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_datetime.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_decimal.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_enum.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_float.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_nchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_newdecimal-big.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_newdecimal.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_ranges.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_set.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_temporal_fractional.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_temporal_upgrade.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_time.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_timestamp-master.opt (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_timestamp.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_timestamp_explicit-master.opt (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_timestamp_explicit.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_uint.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_varchar.test (100%) rename {mysql-test/suite => storage/tokudb/mysql-test}/tokudb/t/type_year.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/1522.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_1.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_10.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_11.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_12.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_13.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_14.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_15.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_16.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_17.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_18.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_2.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_3.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_4.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_5.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_6.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_7.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_8.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/add_index_9.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_22516.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23691.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23692.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23818_1.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23818_2.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23818_A.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23818_B.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/falcon_bug_23818_C.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/hot_create_unique_index.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/r/tokudb_bug_1152.result (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/1522.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_1.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_10.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_11.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_12.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_13.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_14.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_15.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_16.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_17.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_18.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_2.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_3.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_4.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_5.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_6.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_7.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_8.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/add_index_9.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_22516.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23691.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23692.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23818_1.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23818_2.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23818_A.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23818_B.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/falcon_bug_23818_C.test (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/hot_create_unique_index.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_add_index}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.add_index => storage/tokudb/mysql-test/tokudb_add_index}/t/tokudb_bug_1152.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/4630.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/5260.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/ai_aui.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/ai_di.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/ai_part.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/alter_column_default.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/auto_inc.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/di_dui.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/drop_add_pk_104.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/drop_add_pk_part_104.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/drop_pk_with_prefix.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/frm_discover.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/frm_discover_partition.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_add2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_add3.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_blob_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_blob_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_fixed_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_fixed_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_var_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_all_var_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_and_rename_table.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_clustering.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_clustering2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_diff_num_offset_bytes.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_drop_char0_t6.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_fixedblob_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_fixedblob_add2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_fixedblob_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_fixedvar_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_fixedvar_add2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_fixedvar_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_indexing_mix.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_null_bits.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_part.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_pk.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_pk2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_template.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_tmp_tables.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_tmp_tables_56.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_varblob_add.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_varblob_add2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_varblob_drop.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_with_dels.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_with_lock_sps.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcad_with_locks.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr3.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr_binary1.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr_blob.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr_char1.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr_enum.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr_text.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hcr_time.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/hot_row_format_alter.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/mod_enum.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/null_bytes_add_key.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/null_bytes_col_rename.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/null_bytes_drop_default.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/null_bytes_drop_key.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/other_alter.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/other_alter2.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/rename_column_cold_104.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/rename_column_cold_part_104.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/row_format_alter.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/test_field_same_detection.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/r/virtual_columns.result (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/4630.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/5260.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/ai_aui.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/ai_di.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/ai_part.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/alter_column_default.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/auto_inc.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/di_dui.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/disabled.def (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/drop_add_pk_104.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/drop_add_pk_part_104.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/drop_pk_with_prefix.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/frm_discover.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/frm_discover_partition.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_add2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_add3.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_blob_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_blob_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_fixed_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_fixed_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_var_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_all_var_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_and_rename_table.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_clustering.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_clustering2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_diff_num_offset_bytes.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_drop_char0_t6.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_fixedblob_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_fixedblob_add2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_fixedblob_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_fixedvar_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_fixedvar_add2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_fixedvar_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_indexing_mix.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_null_bits.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_part.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_pk.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_pk2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_template.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_tmp_tables.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_tmp_tables_56.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_varblob_add.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_varblob_add2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_varblob_drop.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_with_dels.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_with_lock_sps.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcad_with_locks.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr3.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr_binary1.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr_blob.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr_char1.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr_enum.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr_text.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hcr_time.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/hot_row_format_alter.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/mod_enum.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/null_bytes_add_key.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/null_bytes_col_rename.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/null_bytes_drop_default.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/null_bytes_drop_key.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/other_alter.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/other_alter2.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/rename_column_cold_104.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/rename_column_cold_part_104.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/row_format_alter.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_alter_table}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/test_field_same_detection.test (100%) rename {mysql-test/suite/tokudb.alter_table => storage/tokudb/mysql-test/tokudb_alter_table}/t/virtual_columns.test (100%) rename {mysql-test/suite/tokudb.backup => storage/tokudb/mysql-test/tokudb_backup}/r/tokudb_backup_exclude.result (100%) rename {mysql-test/suite/tokudb.backup => storage/tokudb/mysql-test/tokudb_backup}/r/tokudb_backup_set_last_error.result (100%) rename {mysql-test/suite/tokudb.backup => storage/tokudb/mysql-test/tokudb_backup}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.backup => storage/tokudb/mysql-test/tokudb_backup}/t/tokudb_backup_exclude.test (100%) rename {mysql-test/suite/tokudb.backup => storage/tokudb/mysql-test/tokudb_backup}/t/tokudb_backup_set_last_error.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1648.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1684.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1711.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1795.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1833.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1853.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1872.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1883.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1913.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1938.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/1949.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2043.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2219.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2262.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2383.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2458.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2494-read-committed.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2548.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2641.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2952.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2970.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/2970i.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3014.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3015.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3083.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3441.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3478.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3486.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/3518.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4175.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4260.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4472.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4618.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4633.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4648.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4656.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4656_2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/4675.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5003.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5089.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5469.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5554.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5585.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5695.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5733_innodb.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5733_tokudb.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5951.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5974-2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/5974.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/6053.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/6684.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/889.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/895.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/94.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/alter_external_lock_assert.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/alter_part_tokudb_bug_155.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/alter_table_copy_table.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/bulk_fetch.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/checkpoint_lock.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/checkpoint_lock_2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/checkpoint_lock_3.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/commit_index_end_1.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/commit_index_end_2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db397_delete_trigger.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db397_insert_trigger.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db397_update_trigger.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db739_insert.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db739_replace.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db739_upsert.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db743.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db756_card_part_hash.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db756_card_part_hash_1.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db756_card_part_hash_1_pick.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db756_card_part_hash_2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db756_card_part_hash_2_pick.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db757_part_alter_analyze.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db762.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db766.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db768.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db771.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db788-optimize-index-name.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db801.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db805.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db806.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db811.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db811s.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db817.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/db823.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/dict_leak_3518.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/expand_tinytext_text.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/fileops-2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/fileops-3.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/fileops-4.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/fileops.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/frm_store.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/frm_store2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/frm_store3.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/ft-index-40.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/index_read.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/leak172.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/lock_uniq_key_empty.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/lock_uniq_key_left.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/lock_uniq_key_middle.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/lock_uniq_key_right.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/mdev4533.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/mdev5932.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/optimize_temp_table_tokudb.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/rpl_mixed_replace_into.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/rpl_row_replace_into.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/rpl_stmt_replace_into.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/simple_icp.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/subselect_index_next_same_bug_157.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/tokudb718.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/tokudb_drop_part_table_668.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/tokudb_drop_simple_table_668.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa-1.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa-2.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa-3.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa-4.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa-5.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa-6.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/r/xa.result (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1648.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1684.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1711.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1795.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1833.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1853.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1872.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1883.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1913.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1938.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/1949.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2043.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2219.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2262.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2383.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2458.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2494-read-committed.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2548.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2641.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2952.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2970.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/2970i.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3014.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3015.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3083.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3441.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3478.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3486.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/3518.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4175.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4260.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4472.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4618.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4633.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4648.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4656.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4656_2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/4675.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5003.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5089.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5469.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5554.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5585-master.opt (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5585.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5695.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5733_innodb.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5733_tokudb.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5951.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5974-2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/5974.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/6053.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/6684.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/889.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/895.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/94.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/alter_external_lock_assert.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/alter_part_tokudb_bug_155.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/alter_table_copy_table.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/bulk_fetch.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/checkpoint_lock.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/checkpoint_lock_2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/checkpoint_lock_3.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/commit_index_end_1.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/commit_index_end_2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db397_delete_trigger.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db397_insert_trigger.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db397_update_trigger.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db739_insert.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db739_replace.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db739_upsert.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db743.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db756_card_part_hash.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db756_card_part_hash_1.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db756_card_part_hash_1_pick.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db756_card_part_hash_2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db756_card_part_hash_2_pick.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db757_part_alter_analyze.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db762.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db766.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db768.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db771.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db788-optimize-index-name.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db801.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db805.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db806.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db811.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db811s.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db817.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/db823.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/dict_leak_3518.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/disabled.def (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/expand_tinytext_text.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/fileops-2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/fileops-3.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/fileops-4.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/fileops.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/frm_store.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/frm_store2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/frm_store3.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/ft-index-40.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/index_read.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/leak172.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/lock_uniq_key_empty.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/lock_uniq_key_left.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/lock_uniq_key_middle.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/lock_uniq_key_right.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/mdev4533.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/mdev5932.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/optimize_temp_table_tokudb.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/rpl_mixed_replace_into.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/rpl_row_replace_into.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/rpl_stmt_replace_into.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/simple_icp.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/subselect_index_next_same_bug_157.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_bugs}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/tokudb718.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/tokudb_drop_part_table_668.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/tokudb_drop_simple_table_668.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa-1.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa-2.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa-3.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa-4.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa-5.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa-6.test (100%) rename {mysql-test/suite/tokudb.bugs => storage/tokudb/mysql-test/tokudb_bugs}/t/xa.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/part_blocked_sql_func_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/part_supported_sql_func_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter1_1_2_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter1_1_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter1_2_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter2_1_1_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter2_1_2_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter2_2_1_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter2_2_2_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter3_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_alter4_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_auto_increment_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_basic_symlink_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_basic_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_bit_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_char_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_datetime_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_debug_sync_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_debug_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_decimal_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_engine_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_myisam_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_qa_1_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_qa_4_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_qa_5_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_qa_7_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_qa_8_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exch_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_exchange_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_float_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_int_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_parts_hash_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_parts_inv_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_parts_key_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_parts_list_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_parts_range_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_sub_parts_key_list_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_sub_parts_key_range_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_sub_parts_list_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_max_sub_parts_range_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_mgm_lc0_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_mgm_lc10_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_mgm_lc1_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_mgm_lc2_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_reorganize_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_special_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_syntax_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/r/partition_value_tokudb.result (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/disabled.def (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/part_blocked_sql_func_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/part_supported_sql_func_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter1_1_2_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter1_1_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter1_2_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter2_1_1_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter2_1_2_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter2_2_1_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter2_2_2_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter3_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_alter4_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_auto_increment_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_basic_symlink_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_basic_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_bit_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_char_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_datetime_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_debug_sync_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_debug_sync_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_debug_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_debug_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_decimal_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_engine_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_myisam_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_qa_1_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_qa_4_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_qa_5_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_qa_7_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_qa_8_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exch_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_exchange_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_float_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_int_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_hash_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_hash_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_inv_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_inv_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_key_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_key_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_list_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_list_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_range_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_parts_range_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_key_list_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_key_list_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_key_range_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_key_range_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_list_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_list_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_range_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_max_sub_parts_range_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_mgm_lc0_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_mgm_lc10_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_mgm_lc1_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_mgm_lc1_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_mgm_lc2_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_mgm_lc2_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_reorganize_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_special_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_special_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_syntax_tokudb.test (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_tokudb_status_file-master.opt (100%) rename {mysql-test/suite/tokudb.parts => storage/tokudb/mysql-test/tokudb_parts}/t/partition_value_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_parts}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/combinations (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_deadlock_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_extra_col_master_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_extra_col_slave_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_foreign_key_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_mixed_row_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_not_null_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_parallel_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_parallel_tokudb_delete_pk.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_parallel_tokudb_write_pk.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_partition_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_relay_space_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_basic_3tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_blob_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_log_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_rec_comp_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_sp002_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_sp007_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_row_tabledefs_3tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_set_null_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_stm_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_bug28430.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_bug30888.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_delete_pk.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_delete_pk_lookup1.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_mixed_ddl.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_mixed_dml.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_read_only_ff.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_read_only_ft.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_read_only_tf.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_read_only_tt.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_update_pk_uc0_lookup0.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_update_pk_uc0_lookup1.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_update_pk_uc1_lookup0.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_update_pk_uc1_lookup1.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_update_unique_uc0_lookup0.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_update_unique_uc0_lookup1.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_write_pk.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_write_pk_uc1.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_write_unique.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_tokudb_write_unique_uc1.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_truncate_3tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/rpl_typeconv_tokudb.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/r/tokudb_innodb_xa_crash.result (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/disabled.def (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_deadlock_tokudb-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_deadlock_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_extra_col_master_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_extra_col_slave_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_foreign_key_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_mixed_row_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_not_null_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb_delete_pk-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb_delete_pk.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb_write_pk-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_parallel_tokudb_write_pk.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_partition_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_partition_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_relay_space_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_basic_3tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_blob_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_log_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_log_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_rec_comp_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_sp002_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_sp007_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_row_tabledefs_3tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_set_null_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_stm_tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb-master.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_bug28430-master.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_bug28430-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_bug28430.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_bug30888.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_delete_pk-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_delete_pk.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_delete_pk_lookup1-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_delete_pk_lookup1.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_mixed_ddl.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_mixed_dml.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_ff-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_ff.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_ft-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_ft.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_tf-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_tf.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_tt-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_read_only_tt.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc0_lookup0.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc0_lookup1.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc1_lookup0.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_pk_uc1_lookup1.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_unique_uc0_lookup0.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_update_unique_uc0_lookup1.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_pk-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_pk.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_pk_uc1-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_pk_uc1.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_unique-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_unique.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_unique_uc1-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_tokudb_write_unique_uc1.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_truncate_3tokudb.test (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/rpl_typeconv_tokudb.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_rpl}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/tokudb_innodb_xa_crash-slave.opt (100%) rename {mysql-test/suite/tokudb.rpl => storage/tokudb/mysql-test/tokudb_rpl}/t/tokudb_innodb_xa_crash.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_analyze_delete_fraction.result (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_analyze_in_background_basic.result (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_analyze_mode_basic.result (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_analyze_throttle_basic.result (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_analyze_time_basic.result (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_auto_analyze.result (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/r/tokudb_cardinality_scale_percent_basic.result (100%) rename {mysql-test/suite/tokudb => storage/tokudb/mysql-test/tokudb_sys_vars}/t/suite.opt (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_analyze_delete_fraction.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_analyze_in_background_basic.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_analyze_mode_basic.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_analyze_throttle_basic.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_analyze_time_basic.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_auto_analyze.test (100%) rename {mysql-test/suite/tokudb.sys_vars => storage/tokudb/mysql-test/tokudb_sys_vars}/t/tokudb_cardinality_scale_percent_basic.test (100%) diff --git a/mysql-test/suite/tokudb/bulk-fetch-gen.py b/storage/tokudb/mysql-test/tokudb/bulk-fetch-gen.py similarity index 100% rename from mysql-test/suite/tokudb/bulk-fetch-gen.py rename to storage/tokudb/mysql-test/tokudb/bulk-fetch-gen.py diff --git a/mysql-test/suite/tokudb/include/cluster_key.inc b/storage/tokudb/mysql-test/tokudb/include/cluster_key.inc similarity index 100% rename from mysql-test/suite/tokudb/include/cluster_key.inc rename to storage/tokudb/mysql-test/tokudb/include/cluster_key.inc diff --git a/mysql-test/suite/tokudb/locks-blocking-row-locks-testgen.py b/storage/tokudb/mysql-test/tokudb/locks-blocking-row-locks-testgen.py similarity index 100% rename from mysql-test/suite/tokudb/locks-blocking-row-locks-testgen.py rename to storage/tokudb/mysql-test/tokudb/locks-blocking-row-locks-testgen.py diff --git a/mysql-test/suite/tokudb/r/auto_increment.result b/storage/tokudb/mysql-test/tokudb/r/auto_increment.result similarity index 100% rename from mysql-test/suite/tokudb/r/auto_increment.result rename to storage/tokudb/mysql-test/tokudb/r/auto_increment.result diff --git a/mysql-test/suite/tokudb/r/auto_increment_boundary.result b/storage/tokudb/mysql-test/tokudb/r/auto_increment_boundary.result similarity index 100% rename from mysql-test/suite/tokudb/r/auto_increment_boundary.result rename to storage/tokudb/mysql-test/tokudb/r/auto_increment_boundary.result diff --git a/mysql-test/suite/tokudb/r/auto_increment_boundary_traditional.result b/storage/tokudb/mysql-test/tokudb/r/auto_increment_boundary_traditional.result similarity index 100% rename from mysql-test/suite/tokudb/r/auto_increment_boundary_traditional.result rename to storage/tokudb/mysql-test/tokudb/r/auto_increment_boundary_traditional.result diff --git a/mysql-test/suite/tokudb/r/background_job_manager.result b/storage/tokudb/mysql-test/tokudb/r/background_job_manager.result similarity index 100% rename from mysql-test/suite/tokudb/r/background_job_manager.result rename to storage/tokudb/mysql-test/tokudb/r/background_job_manager.result diff --git a/mysql-test/suite/tokudb/r/bf_create_select.result b/storage/tokudb/mysql-test/tokudb/r/bf_create_select.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_create_select.result rename to storage/tokudb/mysql-test/tokudb/r/bf_create_select.result diff --git a/mysql-test/suite/tokudb/r/bf_create_select_hash_part.result b/storage/tokudb/mysql-test/tokudb/r/bf_create_select_hash_part.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_create_select_hash_part.result rename to storage/tokudb/mysql-test/tokudb/r/bf_create_select_hash_part.result diff --git a/mysql-test/suite/tokudb/r/bf_create_select_range_part.result b/storage/tokudb/mysql-test/tokudb/r/bf_create_select_range_part.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_create_select_range_part.result rename to storage/tokudb/mysql-test/tokudb/r/bf_create_select_range_part.result diff --git a/mysql-test/suite/tokudb/r/bf_create_temp_select.result b/storage/tokudb/mysql-test/tokudb/r/bf_create_temp_select.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_create_temp_select.result rename to storage/tokudb/mysql-test/tokudb/r/bf_create_temp_select.result diff --git a/mysql-test/suite/tokudb/r/bf_delete.result b/storage/tokudb/mysql-test/tokudb/r/bf_delete.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_delete.result rename to storage/tokudb/mysql-test/tokudb/r/bf_delete.result diff --git a/mysql-test/suite/tokudb/r/bf_delete_trigger.result b/storage/tokudb/mysql-test/tokudb/r/bf_delete_trigger.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_delete_trigger.result rename to storage/tokudb/mysql-test/tokudb/r/bf_delete_trigger.result diff --git a/mysql-test/suite/tokudb/r/bf_insert_select.result b/storage/tokudb/mysql-test/tokudb/r/bf_insert_select.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_insert_select.result rename to storage/tokudb/mysql-test/tokudb/r/bf_insert_select.result diff --git a/mysql-test/suite/tokudb/r/bf_insert_select_dup_key.result b/storage/tokudb/mysql-test/tokudb/r/bf_insert_select_dup_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_insert_select_dup_key.result rename to storage/tokudb/mysql-test/tokudb/r/bf_insert_select_dup_key.result diff --git a/mysql-test/suite/tokudb/r/bf_insert_select_trigger.result b/storage/tokudb/mysql-test/tokudb/r/bf_insert_select_trigger.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_insert_select_trigger.result rename to storage/tokudb/mysql-test/tokudb/r/bf_insert_select_trigger.result diff --git a/mysql-test/suite/tokudb/r/bf_insert_select_update_trigger.result b/storage/tokudb/mysql-test/tokudb/r/bf_insert_select_update_trigger.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_insert_select_update_trigger.result rename to storage/tokudb/mysql-test/tokudb/r/bf_insert_select_update_trigger.result diff --git a/mysql-test/suite/tokudb/r/bf_replace_select.result b/storage/tokudb/mysql-test/tokudb/r/bf_replace_select.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_replace_select.result rename to storage/tokudb/mysql-test/tokudb/r/bf_replace_select.result diff --git a/mysql-test/suite/tokudb/r/bf_replace_select_trigger.result b/storage/tokudb/mysql-test/tokudb/r/bf_replace_select_trigger.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_replace_select_trigger.result rename to storage/tokudb/mysql-test/tokudb/r/bf_replace_select_trigger.result diff --git a/mysql-test/suite/tokudb/r/bf_select_hash_part.result b/storage/tokudb/mysql-test/tokudb/r/bf_select_hash_part.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_select_hash_part.result rename to storage/tokudb/mysql-test/tokudb/r/bf_select_hash_part.result diff --git a/mysql-test/suite/tokudb/r/bf_select_range_part.result b/storage/tokudb/mysql-test/tokudb/r/bf_select_range_part.result similarity index 100% rename from mysql-test/suite/tokudb/r/bf_select_range_part.result rename to storage/tokudb/mysql-test/tokudb/r/bf_select_range_part.result diff --git a/mysql-test/suite/tokudb/r/bulk-fetch.result b/storage/tokudb/mysql-test/tokudb/r/bulk-fetch.result similarity index 100% rename from mysql-test/suite/tokudb/r/bulk-fetch.result rename to storage/tokudb/mysql-test/tokudb/r/bulk-fetch.result diff --git a/mysql-test/suite/tokudb/r/bulk-fetch2.result b/storage/tokudb/mysql-test/tokudb/r/bulk-fetch2.result similarity index 100% rename from mysql-test/suite/tokudb/r/bulk-fetch2.result rename to storage/tokudb/mysql-test/tokudb/r/bulk-fetch2.result diff --git a/mysql-test/suite/tokudb/r/card_add_drop.result b/storage/tokudb/mysql-test/tokudb/r/card_add_drop.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_add_drop.result rename to storage/tokudb/mysql-test/tokudb/r/card_add_drop.result diff --git a/mysql-test/suite/tokudb/r/card_add_index.result b/storage/tokudb/mysql-test/tokudb/r/card_add_index.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_add_index.result rename to storage/tokudb/mysql-test/tokudb/r/card_add_index.result diff --git a/mysql-test/suite/tokudb/r/card_auto_analyze_lots.result b/storage/tokudb/mysql-test/tokudb/r/card_auto_analyze_lots.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_auto_analyze_lots.result rename to storage/tokudb/mysql-test/tokudb/r/card_auto_analyze_lots.result diff --git a/mysql-test/suite/tokudb/r/card_drop_index.result b/storage/tokudb/mysql-test/tokudb/r/card_drop_index.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_drop_index.result rename to storage/tokudb/mysql-test/tokudb/r/card_drop_index.result diff --git a/mysql-test/suite/tokudb/r/card_drop_index_2.result b/storage/tokudb/mysql-test/tokudb/r/card_drop_index_2.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_drop_index_2.result rename to storage/tokudb/mysql-test/tokudb/r/card_drop_index_2.result diff --git a/mysql-test/suite/tokudb/r/card_drop_pk.result b/storage/tokudb/mysql-test/tokudb/r/card_drop_pk.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_drop_pk.result rename to storage/tokudb/mysql-test/tokudb/r/card_drop_pk.result diff --git a/mysql-test/suite/tokudb/r/card_no_keys.result b/storage/tokudb/mysql-test/tokudb/r/card_no_keys.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_no_keys.result rename to storage/tokudb/mysql-test/tokudb/r/card_no_keys.result diff --git a/mysql-test/suite/tokudb/r/card_pk.result b/storage/tokudb/mysql-test/tokudb/r/card_pk.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_pk.result rename to storage/tokudb/mysql-test/tokudb/r/card_pk.result diff --git a/mysql-test/suite/tokudb/r/card_pk_2.result b/storage/tokudb/mysql-test/tokudb/r/card_pk_2.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_pk_2.result rename to storage/tokudb/mysql-test/tokudb/r/card_pk_2.result diff --git a/mysql-test/suite/tokudb/r/card_pk_sk.result b/storage/tokudb/mysql-test/tokudb/r/card_pk_sk.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_pk_sk.result rename to storage/tokudb/mysql-test/tokudb/r/card_pk_sk.result diff --git a/mysql-test/suite/tokudb/r/card_scale_percent.result b/storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_scale_percent.result rename to storage/tokudb/mysql-test/tokudb/r/card_scale_percent.result diff --git a/mysql-test/suite/tokudb/r/card_sk.result b/storage/tokudb/mysql-test/tokudb/r/card_sk.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_sk.result rename to storage/tokudb/mysql-test/tokudb/r/card_sk.result diff --git a/mysql-test/suite/tokudb/r/card_sk_2.result b/storage/tokudb/mysql-test/tokudb/r/card_sk_2.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_sk_2.result rename to storage/tokudb/mysql-test/tokudb/r/card_sk_2.result diff --git a/mysql-test/suite/tokudb/r/card_unique_sk.result b/storage/tokudb/mysql-test/tokudb/r/card_unique_sk.result similarity index 100% rename from mysql-test/suite/tokudb/r/card_unique_sk.result rename to storage/tokudb/mysql-test/tokudb/r/card_unique_sk.result diff --git a/mysql-test/suite/tokudb/r/change_column_all_1000_1.result b/storage/tokudb/mysql-test/tokudb/r/change_column_all_1000_1.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_all_1000_1.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_all_1000_1.result diff --git a/mysql-test/suite/tokudb/r/change_column_all_1000_10.result b/storage/tokudb/mysql-test/tokudb/r/change_column_all_1000_10.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_all_1000_10.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_all_1000_10.result diff --git a/mysql-test/suite/tokudb/r/change_column_auto_inc.result b/storage/tokudb/mysql-test/tokudb/r/change_column_auto_inc.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_auto_inc.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_auto_inc.result diff --git a/mysql-test/suite/tokudb/r/change_column_bin.result b/storage/tokudb/mysql-test/tokudb/r/change_column_bin.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_bin.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_bin.result diff --git a/mysql-test/suite/tokudb/r/change_column_bin_descriptor.result b/storage/tokudb/mysql-test/tokudb/r/change_column_bin_descriptor.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_bin_descriptor.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_bin_descriptor.result diff --git a/mysql-test/suite/tokudb/r/change_column_bin_key.result b/storage/tokudb/mysql-test/tokudb/r/change_column_bin_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_bin_key.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_bin_key.result diff --git a/mysql-test/suite/tokudb/r/change_column_bin_pad.result b/storage/tokudb/mysql-test/tokudb/r/change_column_bin_pad.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_bin_pad.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_bin_pad.result diff --git a/mysql-test/suite/tokudb/r/change_column_bin_rename.result b/storage/tokudb/mysql-test/tokudb/r/change_column_bin_rename.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_bin_rename.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_bin_rename.result diff --git a/mysql-test/suite/tokudb/r/change_column_blob.result b/storage/tokudb/mysql-test/tokudb/r/change_column_blob.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_blob.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_blob.result diff --git a/mysql-test/suite/tokudb/r/change_column_blob_data.result b/storage/tokudb/mysql-test/tokudb/r/change_column_blob_data.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_blob_data.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_blob_data.result diff --git a/mysql-test/suite/tokudb/r/change_column_carchar_sum_cross256.result b/storage/tokudb/mysql-test/tokudb/r/change_column_carchar_sum_cross256.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_carchar_sum_cross256.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_carchar_sum_cross256.result diff --git a/mysql-test/suite/tokudb/r/change_column_char.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_binary.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_binary.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_binary.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_binary.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_charbinary.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_charbinary.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_charbinary.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_charbinary.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_charset.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_charset.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_charset.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_charset.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_default.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_default.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_default.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_descriptor.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_descriptor.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_descriptor.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_descriptor.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_key.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_key.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_key.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_null.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_null.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_null.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_null.result diff --git a/mysql-test/suite/tokudb/r/change_column_char_rename.result b/storage/tokudb/mysql-test/tokudb/r/change_column_char_rename.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_char_rename.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_char_rename.result diff --git a/mysql-test/suite/tokudb/r/change_column_delete_change_char_5674.result b/storage/tokudb/mysql-test/tokudb/r/change_column_delete_change_char_5674.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_delete_change_char_5674.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_delete_change_char_5674.result diff --git a/mysql-test/suite/tokudb/r/change_column_delete_change_int_5674.result b/storage/tokudb/mysql-test/tokudb/r/change_column_delete_change_int_5674.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_delete_change_int_5674.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_delete_change_int_5674.result diff --git a/mysql-test/suite/tokudb/r/change_column_delete_change_varchar_5674.result b/storage/tokudb/mysql-test/tokudb/r/change_column_delete_change_varchar_5674.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_delete_change_varchar_5674.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_delete_change_varchar_5674.result diff --git a/mysql-test/suite/tokudb/r/change_column_int.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_int.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_int.result diff --git a/mysql-test/suite/tokudb/r/change_column_int_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int_default.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_int_default.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_int_default.result diff --git a/mysql-test/suite/tokudb/r/change_column_int_descriptor.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int_descriptor.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_int_descriptor.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_int_descriptor.result diff --git a/mysql-test/suite/tokudb/r/change_column_int_key.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_int_key.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_int_key.result diff --git a/mysql-test/suite/tokudb/r/change_column_int_not_supported.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int_not_supported.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_int_not_supported.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_int_not_supported.result diff --git a/mysql-test/suite/tokudb/r/change_column_int_rename.result b/storage/tokudb/mysql-test/tokudb/r/change_column_int_rename.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_int_rename.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_int_rename.result diff --git a/mysql-test/suite/tokudb/r/change_column_multiple_columns.result b/storage/tokudb/mysql-test/tokudb/r/change_column_multiple_columns.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_multiple_columns.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_multiple_columns.result diff --git a/mysql-test/suite/tokudb/r/change_column_multiple_int.result b/storage/tokudb/mysql-test/tokudb/r/change_column_multiple_int.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_multiple_int.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_multiple_int.result diff --git a/mysql-test/suite/tokudb/r/change_column_text.result b/storage/tokudb/mysql-test/tokudb/r/change_column_text.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_text.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_text.result diff --git a/mysql-test/suite/tokudb/r/change_column_text_data.result b/storage/tokudb/mysql-test/tokudb/r/change_column_text_data.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_text_data.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_text_data.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_cross256.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_cross256.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_cross256.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_cross256.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_default.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_default.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_default.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_descriptor.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_descriptor.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_descriptor.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_descriptor.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_key.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_key.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_key.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_multiple.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_multiple.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_multiple.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_multiple.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_null.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_null.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_null.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_null.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_rename.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_rename.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_rename.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_rename.result diff --git a/mysql-test/suite/tokudb/r/change_column_varbin_varchar.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varbin_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varbin_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varbin_varchar.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_charset.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_charset.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_charset.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_charset.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_cross256.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_cross256.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_cross256.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_cross256.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_default.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_default.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_default.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_default.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_descriptor.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_descriptor.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_descriptor.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_descriptor.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_key.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_key.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_key.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_null.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_null.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_null.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_null.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_prefix_a.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_a.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_prefix_a.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_a.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_prefix_b.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_b.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_prefix_b.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_prefix_b.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_rename.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_rename.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_rename.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_rename.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_sum_cross256.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_sum_cross256.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_sum_cross256.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_sum_cross256.result diff --git a/mysql-test/suite/tokudb/r/change_column_varchar_varbin.result b/storage/tokudb/mysql-test/tokudb/r/change_column_varchar_varbin.result similarity index 100% rename from mysql-test/suite/tokudb/r/change_column_varchar_varbin.result rename to storage/tokudb/mysql-test/tokudb/r/change_column_varchar_varbin.result diff --git a/mysql-test/suite/tokudb/r/cluster_1829.result b/storage/tokudb/mysql-test/tokudb/r/cluster_1829.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_1829.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_1829.result diff --git a/mysql-test/suite/tokudb/r/cluster_2968-0.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-0.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_2968-0.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_2968-0.result diff --git a/mysql-test/suite/tokudb/r/cluster_2968-1.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_2968-1.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_2968-1.result diff --git a/mysql-test/suite/tokudb/r/cluster_2968-2.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-2.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_2968-2.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_2968-2.result diff --git a/mysql-test/suite/tokudb/r/cluster_2968-3.result b/storage/tokudb/mysql-test/tokudb/r/cluster_2968-3.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_2968-3.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_2968-3.result diff --git a/mysql-test/suite/tokudb/r/cluster_create_table.result b/storage/tokudb/mysql-test/tokudb/r/cluster_create_table.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_create_table.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_create_table.result diff --git a/mysql-test/suite/tokudb/r/cluster_delete.result b/storage/tokudb/mysql-test/tokudb/r/cluster_delete.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_delete.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_delete.result diff --git a/mysql-test/suite/tokudb/r/cluster_delete2.result b/storage/tokudb/mysql-test/tokudb/r/cluster_delete2.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_delete2.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_delete2.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter_hidden.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_hidden.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter_hidden.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter_hidden.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter_key.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter_key.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter_key.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter_unpack_varchar.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter_unpack_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_and_int_hidden.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter_unpack_varchar_hidden.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_hidden.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter_unpack_varchar_hidden.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter_unpack_varchar_hidden.result diff --git a/mysql-test/suite/tokudb/r/cluster_filter_varchar_prefix.result b/storage/tokudb/mysql-test/tokudb/r/cluster_filter_varchar_prefix.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_filter_varchar_prefix.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_filter_varchar_prefix.result diff --git a/mysql-test/suite/tokudb/r/cluster_key.result b/storage/tokudb/mysql-test/tokudb/r/cluster_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_key.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_key.result diff --git a/mysql-test/suite/tokudb/r/cluster_key_part.result b/storage/tokudb/mysql-test/tokudb/r/cluster_key_part.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_key_part.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_key_part.result diff --git a/mysql-test/suite/tokudb/r/cluster_query_plan.result b/storage/tokudb/mysql-test/tokudb/r/cluster_query_plan.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_query_plan.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_query_plan.result diff --git a/mysql-test/suite/tokudb/r/cluster_tokudb_bug_993.result b/storage/tokudb/mysql-test/tokudb/r/cluster_tokudb_bug_993.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_tokudb_bug_993.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_tokudb_bug_993.result diff --git a/mysql-test/suite/tokudb/r/cluster_tokudb_bug_993_2.result b/storage/tokudb/mysql-test/tokudb/r/cluster_tokudb_bug_993_2.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_tokudb_bug_993_2.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_tokudb_bug_993_2.result diff --git a/mysql-test/suite/tokudb/r/cluster_update.result b/storage/tokudb/mysql-test/tokudb/r/cluster_update.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_update.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_update.result diff --git a/mysql-test/suite/tokudb/r/cluster_update2.result b/storage/tokudb/mysql-test/tokudb/r/cluster_update2.result similarity index 100% rename from mysql-test/suite/tokudb/r/cluster_update2.result rename to storage/tokudb/mysql-test/tokudb/r/cluster_update2.result diff --git a/mysql-test/suite/tokudb/r/ctype_ascii.result b/storage/tokudb/mysql-test/tokudb/r/ctype_ascii.result similarity index 100% rename from mysql-test/suite/tokudb/r/ctype_ascii.result rename to storage/tokudb/mysql-test/tokudb/r/ctype_ascii.result diff --git a/mysql-test/suite/tokudb/r/ctype_collate.result b/storage/tokudb/mysql-test/tokudb/r/ctype_collate.result similarity index 100% rename from mysql-test/suite/tokudb/r/ctype_collate.result rename to storage/tokudb/mysql-test/tokudb/r/ctype_collate.result diff --git a/mysql-test/suite/tokudb/r/ctype_cp1250_ch.result b/storage/tokudb/mysql-test/tokudb/r/ctype_cp1250_ch.result similarity index 100% rename from mysql-test/suite/tokudb/r/ctype_cp1250_ch.result rename to storage/tokudb/mysql-test/tokudb/r/ctype_cp1250_ch.result diff --git a/mysql-test/suite/tokudb/r/ctype_cp1251.result b/storage/tokudb/mysql-test/tokudb/r/ctype_cp1251.result similarity index 100% rename from mysql-test/suite/tokudb/r/ctype_cp1251.result rename to storage/tokudb/mysql-test/tokudb/r/ctype_cp1251.result diff --git a/mysql-test/suite/tokudb/r/ext_key_1_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result similarity index 100% rename from mysql-test/suite/tokudb/r/ext_key_1_innodb.result rename to storage/tokudb/mysql-test/tokudb/r/ext_key_1_innodb.result diff --git a/mysql-test/suite/tokudb/r/ext_key_1_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb/r/ext_key_1_tokudb.result rename to storage/tokudb/mysql-test/tokudb/r/ext_key_1_tokudb.result diff --git a/mysql-test/suite/tokudb/r/ext_key_2_innodb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result similarity index 100% rename from mysql-test/suite/tokudb/r/ext_key_2_innodb.result rename to storage/tokudb/mysql-test/tokudb/r/ext_key_2_innodb.result diff --git a/mysql-test/suite/tokudb/r/ext_key_2_tokudb.result b/storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb/r/ext_key_2_tokudb.result rename to storage/tokudb/mysql-test/tokudb/r/ext_key_2_tokudb.result diff --git a/mysql-test/suite/tokudb/r/fast_update_binlog_mixed.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_binlog_mixed.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_binlog_mixed.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_binlog_mixed.result diff --git a/mysql-test/suite/tokudb/r/fast_update_binlog_row.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_binlog_row.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_binlog_row.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_binlog_row.result diff --git a/mysql-test/suite/tokudb/r/fast_update_binlog_statement.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_binlog_statement.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_binlog_statement.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_binlog_statement.result diff --git a/mysql-test/suite/tokudb/r/fast_update_blobs.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_blobs.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_blobs.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_blobs.result diff --git a/mysql-test/suite/tokudb/r/fast_update_blobs_fixed_varchar.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_blobs_fixed_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_blobs_fixed_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_blobs_fixed_varchar.result diff --git a/mysql-test/suite/tokudb/r/fast_update_blobs_with_varchar.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_blobs_with_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_blobs_with_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_blobs_with_varchar.result diff --git a/mysql-test/suite/tokudb/r/fast_update_char.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_char.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_char.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_char.result diff --git a/mysql-test/suite/tokudb/r/fast_update_deadlock.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_deadlock.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_deadlock.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_deadlock.result diff --git a/mysql-test/suite/tokudb/r/fast_update_decr_floor.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_decr_floor.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_decr_floor.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_decr_floor.result diff --git a/mysql-test/suite/tokudb/r/fast_update_disable_slow_update.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_disable_slow_update.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_disable_slow_update.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_disable_slow_update.result diff --git a/mysql-test/suite/tokudb/r/fast_update_error.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_error.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_error.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_error.result diff --git a/mysql-test/suite/tokudb/r/fast_update_int.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_int.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_int.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_int.result diff --git a/mysql-test/suite/tokudb/r/fast_update_int_bounds.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_int_bounds.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_int_bounds.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_int_bounds.result diff --git a/mysql-test/suite/tokudb/r/fast_update_key.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_key.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_key.result diff --git a/mysql-test/suite/tokudb/r/fast_update_sqlmode.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_sqlmode.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_sqlmode.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_sqlmode.result diff --git a/mysql-test/suite/tokudb/r/fast_update_uint_bounds.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_uint_bounds.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_uint_bounds.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_uint_bounds.result diff --git a/mysql-test/suite/tokudb/r/fast_update_varchar.result b/storage/tokudb/mysql-test/tokudb/r/fast_update_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_update_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/fast_update_varchar.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_bin_pad.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_bin_pad.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_bin_pad.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_bin_pad.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_char.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_char.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_char.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_char.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_deadlock.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_deadlock.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_deadlock.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_deadlock.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_int.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_int.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_int.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_int.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_key.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_key.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_key.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_key.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_sqlmode.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_sqlmode.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_sqlmode.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_sqlmode.result diff --git a/mysql-test/suite/tokudb/r/fast_upsert_values.result b/storage/tokudb/mysql-test/tokudb/r/fast_upsert_values.result similarity index 100% rename from mysql-test/suite/tokudb/r/fast_upsert_values.result rename to storage/tokudb/mysql-test/tokudb/r/fast_upsert_values.result diff --git a/mysql-test/suite/tokudb/r/hotindex-del-0.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-del-0.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-del-0.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-del-0.result diff --git a/mysql-test/suite/tokudb/r/hotindex-del-1.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-del-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-del-1.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-del-1.result diff --git a/mysql-test/suite/tokudb/r/hotindex-del-fast.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-del-fast.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-del-fast.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-del-fast.result diff --git a/mysql-test/suite/tokudb/r/hotindex-del-slow.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-del-slow.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-del-slow.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-del-slow.result diff --git a/mysql-test/suite/tokudb/r/hotindex-insert-0.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-insert-0.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-insert-0.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-insert-0.result diff --git a/mysql-test/suite/tokudb/r/hotindex-insert-1.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-insert-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-insert-1.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-insert-1.result diff --git a/mysql-test/suite/tokudb/r/hotindex-insert-2.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-insert-2.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-insert-2.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-insert-2.result diff --git a/mysql-test/suite/tokudb/r/hotindex-insert-bigchar.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-insert-bigchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-insert-bigchar.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-insert-bigchar.result diff --git a/mysql-test/suite/tokudb/r/hotindex-update-0.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-update-0.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-update-0.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-update-0.result diff --git a/mysql-test/suite/tokudb/r/hotindex-update-1.result b/storage/tokudb/mysql-test/tokudb/r/hotindex-update-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/hotindex-update-1.result rename to storage/tokudb/mysql-test/tokudb/r/hotindex-update-1.result diff --git a/mysql-test/suite/tokudb/r/i_s_tokudb_lock_waits_released.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result similarity index 100% rename from mysql-test/suite/tokudb/r/i_s_tokudb_lock_waits_released.result rename to storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result diff --git a/mysql-test/suite/tokudb/r/i_s_tokudb_lock_waits_timeout.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result similarity index 100% rename from mysql-test/suite/tokudb/r/i_s_tokudb_lock_waits_timeout.result rename to storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result diff --git a/mysql-test/suite/tokudb/r/i_s_tokudb_locks.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result similarity index 100% rename from mysql-test/suite/tokudb/r/i_s_tokudb_locks.result rename to storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result diff --git a/mysql-test/suite/tokudb/r/i_s_tokudb_locks_released.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result similarity index 100% rename from mysql-test/suite/tokudb/r/i_s_tokudb_locks_released.result rename to storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result diff --git a/mysql-test/suite/tokudb/r/i_s_tokudb_trx.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_trx.result similarity index 100% rename from mysql-test/suite/tokudb/r/i_s_tokudb_trx.result rename to storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_trx.result diff --git a/mysql-test/suite/tokudb/r/information-schema-global-status.result b/storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result similarity index 100% rename from mysql-test/suite/tokudb/r/information-schema-global-status.result rename to storage/tokudb/mysql-test/tokudb/r/information-schema-global-status.result diff --git a/mysql-test/suite/tokudb/r/lockretry-insert.writelocktable.result b/storage/tokudb/mysql-test/tokudb/r/lockretry-insert.writelocktable.result similarity index 100% rename from mysql-test/suite/tokudb/r/lockretry-insert.writelocktable.result rename to storage/tokudb/mysql-test/tokudb/r/lockretry-insert.writelocktable.result diff --git a/mysql-test/suite/tokudb/r/lockretry-writelocktable.insert.result b/storage/tokudb/mysql-test/tokudb/r/lockretry-writelocktable.insert.result similarity index 100% rename from mysql-test/suite/tokudb/r/lockretry-writelocktable.insert.result rename to storage/tokudb/mysql-test/tokudb/r/lockretry-writelocktable.insert.result diff --git a/mysql-test/suite/tokudb/r/lockretry-writelocktable.insert2.result b/storage/tokudb/mysql-test/tokudb/r/lockretry-writelocktable.insert2.result similarity index 100% rename from mysql-test/suite/tokudb/r/lockretry-writelocktable.insert2.result rename to storage/tokudb/mysql-test/tokudb/r/lockretry-writelocktable.insert2.result diff --git a/mysql-test/suite/tokudb/r/locks-blocking-row-locks-getset.result b/storage/tokudb/mysql-test/tokudb/r/locks-blocking-row-locks-getset.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-blocking-row-locks-getset.result rename to storage/tokudb/mysql-test/tokudb/r/locks-blocking-row-locks-getset.result diff --git a/mysql-test/suite/tokudb/r/locks-blocking-row-locks-race.result b/storage/tokudb/mysql-test/tokudb/r/locks-blocking-row-locks-race.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-blocking-row-locks-race.result rename to storage/tokudb/mysql-test/tokudb/r/locks-blocking-row-locks-race.result diff --git a/mysql-test/suite/tokudb/r/locks-blocking-row-locks.result b/storage/tokudb/mysql-test/tokudb/r/locks-blocking-row-locks.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-blocking-row-locks.result rename to storage/tokudb/mysql-test/tokudb/r/locks-blocking-row-locks.result diff --git a/mysql-test/suite/tokudb/r/locks-delete-deadlock-1.result b/storage/tokudb/mysql-test/tokudb/r/locks-delete-deadlock-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-delete-deadlock-1.result rename to storage/tokudb/mysql-test/tokudb/r/locks-delete-deadlock-1.result diff --git a/mysql-test/suite/tokudb/r/locks-no-read-lock-serializable-autocommit.result b/storage/tokudb/mysql-test/tokudb/r/locks-no-read-lock-serializable-autocommit.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-no-read-lock-serializable-autocommit.result rename to storage/tokudb/mysql-test/tokudb/r/locks-no-read-lock-serializable-autocommit.result diff --git a/mysql-test/suite/tokudb/r/locks-select-update-1.result b/storage/tokudb/mysql-test/tokudb/r/locks-select-update-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-select-update-1.result rename to storage/tokudb/mysql-test/tokudb/r/locks-select-update-1.result diff --git a/mysql-test/suite/tokudb/r/locks-select-update-2.result b/storage/tokudb/mysql-test/tokudb/r/locks-select-update-2.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-select-update-2.result rename to storage/tokudb/mysql-test/tokudb/r/locks-select-update-2.result diff --git a/mysql-test/suite/tokudb/r/locks-select-update-3.result b/storage/tokudb/mysql-test/tokudb/r/locks-select-update-3.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-select-update-3.result rename to storage/tokudb/mysql-test/tokudb/r/locks-select-update-3.result diff --git a/mysql-test/suite/tokudb/r/locks-update-deadlock-1.result b/storage/tokudb/mysql-test/tokudb/r/locks-update-deadlock-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/locks-update-deadlock-1.result rename to storage/tokudb/mysql-test/tokudb/r/locks-update-deadlock-1.result diff --git a/mysql-test/suite/tokudb/r/mvcc-1.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-1.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-1.result diff --git a/mysql-test/suite/tokudb/r/mvcc-10.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-10.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-10.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-10.result diff --git a/mysql-test/suite/tokudb/r/mvcc-11.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-11.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-11.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-11.result diff --git a/mysql-test/suite/tokudb/r/mvcc-12.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-12.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-12.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-12.result diff --git a/mysql-test/suite/tokudb/r/mvcc-13.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-13.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-13.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-13.result diff --git a/mysql-test/suite/tokudb/r/mvcc-14.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-14.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-14.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-14.result diff --git a/mysql-test/suite/tokudb/r/mvcc-15.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-15.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-15.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-15.result diff --git a/mysql-test/suite/tokudb/r/mvcc-16.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-16.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-16.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-16.result diff --git a/mysql-test/suite/tokudb/r/mvcc-17.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-17.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-17.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-17.result diff --git a/mysql-test/suite/tokudb/r/mvcc-18.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-18.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-18.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-18.result diff --git a/mysql-test/suite/tokudb/r/mvcc-19.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-19.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-19.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-19.result diff --git a/mysql-test/suite/tokudb/r/mvcc-2.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-2.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-2.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-2.result diff --git a/mysql-test/suite/tokudb/r/mvcc-20.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-20.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-20.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-20.result diff --git a/mysql-test/suite/tokudb/r/mvcc-21.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-21.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-21.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-21.result diff --git a/mysql-test/suite/tokudb/r/mvcc-22.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-22.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-22.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-22.result diff --git a/mysql-test/suite/tokudb/r/mvcc-23.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-23.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-23.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-23.result diff --git a/mysql-test/suite/tokudb/r/mvcc-24.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-24.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-24.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-24.result diff --git a/mysql-test/suite/tokudb/r/mvcc-25.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-25.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-25.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-25.result diff --git a/mysql-test/suite/tokudb/r/mvcc-26.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-26.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-26.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-26.result diff --git a/mysql-test/suite/tokudb/r/mvcc-27.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-27.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-27.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-27.result diff --git a/mysql-test/suite/tokudb/r/mvcc-28.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-28.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-28.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-28.result diff --git a/mysql-test/suite/tokudb/r/mvcc-2808-read-committed.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-2808-read-committed.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-2808-read-committed.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-2808-read-committed.result diff --git a/mysql-test/suite/tokudb/r/mvcc-2808-read-uncommitted.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-2808-read-uncommitted.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-2808-read-uncommitted.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-2808-read-uncommitted.result diff --git a/mysql-test/suite/tokudb/r/mvcc-29.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-29.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-29.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-29.result diff --git a/mysql-test/suite/tokudb/r/mvcc-3.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-3.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-3.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-3.result diff --git a/mysql-test/suite/tokudb/r/mvcc-30.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-30.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-30.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-30.result diff --git a/mysql-test/suite/tokudb/r/mvcc-31.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-31.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-31.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-31.result diff --git a/mysql-test/suite/tokudb/r/mvcc-33.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-33.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-33.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-33.result diff --git a/mysql-test/suite/tokudb/r/mvcc-34.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-34.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-34.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-34.result diff --git a/mysql-test/suite/tokudb/r/mvcc-35.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-35.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-35.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-35.result diff --git a/mysql-test/suite/tokudb/r/mvcc-36.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-36.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-36.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-36.result diff --git a/mysql-test/suite/tokudb/r/mvcc-37.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-37.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-37.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-37.result diff --git a/mysql-test/suite/tokudb/r/mvcc-38.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-38.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-38.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-38.result diff --git a/mysql-test/suite/tokudb/r/mvcc-39.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-39.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-39.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-39.result diff --git a/mysql-test/suite/tokudb/r/mvcc-4.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-4.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-4.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-4.result diff --git a/mysql-test/suite/tokudb/r/mvcc-40.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-40.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-40.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-40.result diff --git a/mysql-test/suite/tokudb/r/mvcc-5.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-5.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-5.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-5.result diff --git a/mysql-test/suite/tokudb/r/mvcc-6.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-6.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-6.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-6.result diff --git a/mysql-test/suite/tokudb/r/mvcc-7.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-7.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-7.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-7.result diff --git a/mysql-test/suite/tokudb/r/mvcc-8.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-8.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-8.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-8.result diff --git a/mysql-test/suite/tokudb/r/mvcc-9.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-9.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-9.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-9.result diff --git a/mysql-test/suite/tokudb/r/mvcc-checksum-locks.result b/storage/tokudb/mysql-test/tokudb/r/mvcc-checksum-locks.result similarity index 100% rename from mysql-test/suite/tokudb/r/mvcc-checksum-locks.result rename to storage/tokudb/mysql-test/tokudb/r/mvcc-checksum-locks.result diff --git a/mysql-test/suite/tokudb/r/nested_txn_autocommit.result b/storage/tokudb/mysql-test/tokudb/r/nested_txn_autocommit.result similarity index 100% rename from mysql-test/suite/tokudb/r/nested_txn_autocommit.result rename to storage/tokudb/mysql-test/tokudb/r/nested_txn_autocommit.result diff --git a/mysql-test/suite/tokudb/r/nested_txn_begin.result b/storage/tokudb/mysql-test/tokudb/r/nested_txn_begin.result similarity index 100% rename from mysql-test/suite/tokudb/r/nested_txn_begin.result rename to storage/tokudb/mysql-test/tokudb/r/nested_txn_begin.result diff --git a/mysql-test/suite/tokudb/r/nested_txn_implicit_commit.result b/storage/tokudb/mysql-test/tokudb/r/nested_txn_implicit_commit.result similarity index 100% rename from mysql-test/suite/tokudb/r/nested_txn_implicit_commit.result rename to storage/tokudb/mysql-test/tokudb/r/nested_txn_implicit_commit.result diff --git a/mysql-test/suite/tokudb/r/prim_key_1.result b/storage/tokudb/mysql-test/tokudb/r/prim_key_1.result similarity index 100% rename from mysql-test/suite/tokudb/r/prim_key_1.result rename to storage/tokudb/mysql-test/tokudb/r/prim_key_1.result diff --git a/mysql-test/suite/tokudb/r/prim_key_2.result b/storage/tokudb/mysql-test/tokudb/r/prim_key_2.result similarity index 100% rename from mysql-test/suite/tokudb/r/prim_key_2.result rename to storage/tokudb/mysql-test/tokudb/r/prim_key_2.result diff --git a/mysql-test/suite/tokudb/r/prim_key_3.result b/storage/tokudb/mysql-test/tokudb/r/prim_key_3.result similarity index 100% rename from mysql-test/suite/tokudb/r/prim_key_3.result rename to storage/tokudb/mysql-test/tokudb/r/prim_key_3.result diff --git a/mysql-test/suite/tokudb/r/prim_key_4.result b/storage/tokudb/mysql-test/tokudb/r/prim_key_4.result similarity index 100% rename from mysql-test/suite/tokudb/r/prim_key_4.result rename to storage/tokudb/mysql-test/tokudb/r/prim_key_4.result diff --git a/mysql-test/suite/tokudb/r/prim_key_5.result b/storage/tokudb/mysql-test/tokudb/r/prim_key_5.result similarity index 100% rename from mysql-test/suite/tokudb/r/prim_key_5.result rename to storage/tokudb/mysql-test/tokudb/r/prim_key_5.result diff --git a/mysql-test/suite/tokudb/r/prim_key_6.result b/storage/tokudb/mysql-test/tokudb/r/prim_key_6.result similarity index 100% rename from mysql-test/suite/tokudb/r/prim_key_6.result rename to storage/tokudb/mysql-test/tokudb/r/prim_key_6.result diff --git a/mysql-test/suite/tokudb/r/replace-ignore.result b/storage/tokudb/mysql-test/tokudb/r/replace-ignore.result similarity index 100% rename from mysql-test/suite/tokudb/r/replace-ignore.result rename to storage/tokudb/mysql-test/tokudb/r/replace-ignore.result diff --git a/mysql-test/suite/tokudb/r/rows-32m-0.result b/storage/tokudb/mysql-test/tokudb/r/rows-32m-0.result similarity index 100% rename from mysql-test/suite/tokudb/r/rows-32m-0.result rename to storage/tokudb/mysql-test/tokudb/r/rows-32m-0.result diff --git a/mysql-test/suite/tokudb/r/rows-32m-1.result b/storage/tokudb/mysql-test/tokudb/r/rows-32m-1.result similarity index 100% rename from mysql-test/suite/tokudb/r/rows-32m-1.result rename to storage/tokudb/mysql-test/tokudb/r/rows-32m-1.result diff --git a/mysql-test/suite/tokudb/r/rows-32m-rand-insert.result b/storage/tokudb/mysql-test/tokudb/r/rows-32m-rand-insert.result similarity index 100% rename from mysql-test/suite/tokudb/r/rows-32m-rand-insert.result rename to storage/tokudb/mysql-test/tokudb/r/rows-32m-rand-insert.result diff --git a/mysql-test/suite/tokudb/r/rows-32m-seq-insert.result b/storage/tokudb/mysql-test/tokudb/r/rows-32m-seq-insert.result similarity index 100% rename from mysql-test/suite/tokudb/r/rows-32m-seq-insert.result rename to storage/tokudb/mysql-test/tokudb/r/rows-32m-seq-insert.result diff --git a/mysql-test/suite/tokudb/r/savepoint-1078-2.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-1078-2.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-1078-2.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-1078-2.result diff --git a/mysql-test/suite/tokudb/r/savepoint-1078-3.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-1078-3.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-1078-3.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-1078-3.result diff --git a/mysql-test/suite/tokudb/r/savepoint-1078-4.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-1078-4.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-1078-4.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-1078-4.result diff --git a/mysql-test/suite/tokudb/r/savepoint-1078.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-1078.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-1078.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-1078.result diff --git a/mysql-test/suite/tokudb/r/savepoint-2.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-2.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-2.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-2.result diff --git a/mysql-test/suite/tokudb/r/savepoint-3.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-3.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-3.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-3.result diff --git a/mysql-test/suite/tokudb/r/savepoint-4.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-4.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-4.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-4.result diff --git a/mysql-test/suite/tokudb/r/savepoint-5.result b/storage/tokudb/mysql-test/tokudb/r/savepoint-5.result similarity index 100% rename from mysql-test/suite/tokudb/r/savepoint-5.result rename to storage/tokudb/mysql-test/tokudb/r/savepoint-5.result diff --git a/mysql-test/suite/tokudb/r/simple_delete_all.result b/storage/tokudb/mysql-test/tokudb/r/simple_delete_all.result similarity index 100% rename from mysql-test/suite/tokudb/r/simple_delete_all.result rename to storage/tokudb/mysql-test/tokudb/r/simple_delete_all.result diff --git a/mysql-test/suite/tokudb/r/simple_join_tokudb_innodb.result b/storage/tokudb/mysql-test/tokudb/r/simple_join_tokudb_innodb.result similarity index 100% rename from mysql-test/suite/tokudb/r/simple_join_tokudb_innodb.result rename to storage/tokudb/mysql-test/tokudb/r/simple_join_tokudb_innodb.result diff --git a/mysql-test/suite/tokudb/r/simple_join_tokudb_myisam.result b/storage/tokudb/mysql-test/tokudb/r/simple_join_tokudb_myisam.result similarity index 100% rename from mysql-test/suite/tokudb/r/simple_join_tokudb_myisam.result rename to storage/tokudb/mysql-test/tokudb/r/simple_join_tokudb_myisam.result diff --git a/mysql-test/suite/tokudb/r/simple_truncate.result b/storage/tokudb/mysql-test/tokudb/r/simple_truncate.result similarity index 100% rename from mysql-test/suite/tokudb/r/simple_truncate.result rename to storage/tokudb/mysql-test/tokudb/r/simple_truncate.result diff --git a/mysql-test/suite/tokudb/r/sql_mode_default.result b/storage/tokudb/mysql-test/tokudb/r/sql_mode_default.result similarity index 100% rename from mysql-test/suite/tokudb/r/sql_mode_default.result rename to storage/tokudb/mysql-test/tokudb/r/sql_mode_default.result diff --git a/mysql-test/suite/tokudb/r/storage_engine_default.result b/storage/tokudb/mysql-test/tokudb/r/storage_engine_default.result similarity index 100% rename from mysql-test/suite/tokudb/r/storage_engine_default.result rename to storage/tokudb/mysql-test/tokudb/r/storage_engine_default.result diff --git a/mysql-test/suite/tokudb/r/tokudb_support_xa.result b/storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result similarity index 100% rename from mysql-test/suite/tokudb/r/tokudb_support_xa.result rename to storage/tokudb/mysql-test/tokudb/r/tokudb_support_xa.result diff --git a/mysql-test/suite/tokudb/r/truncate_row_count.result b/storage/tokudb/mysql-test/tokudb/r/truncate_row_count.result similarity index 100% rename from mysql-test/suite/tokudb/r/truncate_row_count.result rename to storage/tokudb/mysql-test/tokudb/r/truncate_row_count.result diff --git a/mysql-test/suite/tokudb/r/truncate_txn_commit.result b/storage/tokudb/mysql-test/tokudb/r/truncate_txn_commit.result similarity index 100% rename from mysql-test/suite/tokudb/r/truncate_txn_commit.result rename to storage/tokudb/mysql-test/tokudb/r/truncate_txn_commit.result diff --git a/mysql-test/suite/tokudb/r/truncate_txn_rollback.result b/storage/tokudb/mysql-test/tokudb/r/truncate_txn_rollback.result similarity index 100% rename from mysql-test/suite/tokudb/r/truncate_txn_rollback.result rename to storage/tokudb/mysql-test/tokudb/r/truncate_txn_rollback.result diff --git a/mysql-test/suite/tokudb/r/truncate_txn_rollback_innodb.result b/storage/tokudb/mysql-test/tokudb/r/truncate_txn_rollback_innodb.result similarity index 100% rename from mysql-test/suite/tokudb/r/truncate_txn_rollback_innodb.result rename to storage/tokudb/mysql-test/tokudb/r/truncate_txn_rollback_innodb.result diff --git a/mysql-test/suite/tokudb/r/type_binary.result b/storage/tokudb/mysql-test/tokudb/r/type_binary.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_binary.result rename to storage/tokudb/mysql-test/tokudb/r/type_binary.result diff --git a/mysql-test/suite/tokudb/r/type_bit.result b/storage/tokudb/mysql-test/tokudb/r/type_bit.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_bit.result rename to storage/tokudb/mysql-test/tokudb/r/type_bit.result diff --git a/mysql-test/suite/tokudb/r/type_bit_innodb.result b/storage/tokudb/mysql-test/tokudb/r/type_bit_innodb.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_bit_innodb.result rename to storage/tokudb/mysql-test/tokudb/r/type_bit_innodb.result diff --git a/mysql-test/suite/tokudb/r/type_blob.result b/storage/tokudb/mysql-test/tokudb/r/type_blob.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_blob.result rename to storage/tokudb/mysql-test/tokudb/r/type_blob.result diff --git a/mysql-test/suite/tokudb/r/type_date.result b/storage/tokudb/mysql-test/tokudb/r/type_date.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_date.result rename to storage/tokudb/mysql-test/tokudb/r/type_date.result diff --git a/mysql-test/suite/tokudb/r/type_datetime.result b/storage/tokudb/mysql-test/tokudb/r/type_datetime.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_datetime.result rename to storage/tokudb/mysql-test/tokudb/r/type_datetime.result diff --git a/mysql-test/suite/tokudb/r/type_decimal.result b/storage/tokudb/mysql-test/tokudb/r/type_decimal.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_decimal.result rename to storage/tokudb/mysql-test/tokudb/r/type_decimal.result diff --git a/mysql-test/suite/tokudb/r/type_enum.result b/storage/tokudb/mysql-test/tokudb/r/type_enum.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_enum.result rename to storage/tokudb/mysql-test/tokudb/r/type_enum.result diff --git a/mysql-test/suite/tokudb/r/type_float.result b/storage/tokudb/mysql-test/tokudb/r/type_float.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_float.result rename to storage/tokudb/mysql-test/tokudb/r/type_float.result diff --git a/mysql-test/suite/tokudb/r/type_nchar.result b/storage/tokudb/mysql-test/tokudb/r/type_nchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_nchar.result rename to storage/tokudb/mysql-test/tokudb/r/type_nchar.result diff --git a/mysql-test/suite/tokudb/r/type_newdecimal-big.result b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal-big.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_newdecimal-big.result rename to storage/tokudb/mysql-test/tokudb/r/type_newdecimal-big.result diff --git a/mysql-test/suite/tokudb/r/type_newdecimal.result b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_newdecimal.result rename to storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result diff --git a/mysql-test/suite/tokudb/r/type_ranges.result b/storage/tokudb/mysql-test/tokudb/r/type_ranges.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_ranges.result rename to storage/tokudb/mysql-test/tokudb/r/type_ranges.result diff --git a/mysql-test/suite/tokudb/r/type_set.result b/storage/tokudb/mysql-test/tokudb/r/type_set.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_set.result rename to storage/tokudb/mysql-test/tokudb/r/type_set.result diff --git a/mysql-test/suite/tokudb/r/type_temporal_fractional.result b/storage/tokudb/mysql-test/tokudb/r/type_temporal_fractional.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_temporal_fractional.result rename to storage/tokudb/mysql-test/tokudb/r/type_temporal_fractional.result diff --git a/mysql-test/suite/tokudb/r/type_temporal_upgrade.result b/storage/tokudb/mysql-test/tokudb/r/type_temporal_upgrade.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_temporal_upgrade.result rename to storage/tokudb/mysql-test/tokudb/r/type_temporal_upgrade.result diff --git a/mysql-test/suite/tokudb/r/type_time.result b/storage/tokudb/mysql-test/tokudb/r/type_time.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_time.result rename to storage/tokudb/mysql-test/tokudb/r/type_time.result diff --git a/mysql-test/suite/tokudb/r/type_timestamp.result b/storage/tokudb/mysql-test/tokudb/r/type_timestamp.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_timestamp.result rename to storage/tokudb/mysql-test/tokudb/r/type_timestamp.result diff --git a/mysql-test/suite/tokudb/r/type_timestamp_explicit.result b/storage/tokudb/mysql-test/tokudb/r/type_timestamp_explicit.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_timestamp_explicit.result rename to storage/tokudb/mysql-test/tokudb/r/type_timestamp_explicit.result diff --git a/mysql-test/suite/tokudb/r/type_uint.result b/storage/tokudb/mysql-test/tokudb/r/type_uint.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_uint.result rename to storage/tokudb/mysql-test/tokudb/r/type_uint.result diff --git a/mysql-test/suite/tokudb/r/type_varchar.result b/storage/tokudb/mysql-test/tokudb/r/type_varchar.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_varchar.result rename to storage/tokudb/mysql-test/tokudb/r/type_varchar.result diff --git a/mysql-test/suite/tokudb/r/type_year.result b/storage/tokudb/mysql-test/tokudb/r/type_year.result similarity index 100% rename from mysql-test/suite/tokudb/r/type_year.result rename to storage/tokudb/mysql-test/tokudb/r/type_year.result diff --git a/mysql-test/suite/tokudb/replace-ignore-gen.py b/storage/tokudb/mysql-test/tokudb/replace-ignore-gen.py similarity index 100% rename from mysql-test/suite/tokudb/replace-ignore-gen.py rename to storage/tokudb/mysql-test/tokudb/replace-ignore-gen.py diff --git a/mysql-test/suite/tokudb/t/auto_increment.test b/storage/tokudb/mysql-test/tokudb/t/auto_increment.test similarity index 100% rename from mysql-test/suite/tokudb/t/auto_increment.test rename to storage/tokudb/mysql-test/tokudb/t/auto_increment.test diff --git a/mysql-test/suite/tokudb/t/auto_increment_boundary.test b/storage/tokudb/mysql-test/tokudb/t/auto_increment_boundary.test similarity index 100% rename from mysql-test/suite/tokudb/t/auto_increment_boundary.test rename to storage/tokudb/mysql-test/tokudb/t/auto_increment_boundary.test diff --git a/mysql-test/suite/tokudb/t/auto_increment_boundary_traditional.test b/storage/tokudb/mysql-test/tokudb/t/auto_increment_boundary_traditional.test similarity index 100% rename from mysql-test/suite/tokudb/t/auto_increment_boundary_traditional.test rename to storage/tokudb/mysql-test/tokudb/t/auto_increment_boundary_traditional.test diff --git a/mysql-test/suite/tokudb/t/background_job_manager.test b/storage/tokudb/mysql-test/tokudb/t/background_job_manager.test similarity index 100% rename from mysql-test/suite/tokudb/t/background_job_manager.test rename to storage/tokudb/mysql-test/tokudb/t/background_job_manager.test diff --git a/mysql-test/suite/tokudb/t/bf_create_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_select.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_create_select.test rename to storage/tokudb/mysql-test/tokudb/t/bf_create_select.test diff --git a/mysql-test/suite/tokudb/t/bf_create_select_hash_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_create_select_hash_part.test rename to storage/tokudb/mysql-test/tokudb/t/bf_create_select_hash_part.test diff --git a/mysql-test/suite/tokudb/t/bf_create_select_range_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_create_select_range_part.test rename to storage/tokudb/mysql-test/tokudb/t/bf_create_select_range_part.test diff --git a/mysql-test/suite/tokudb/t/bf_create_temp_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_create_temp_select.test rename to storage/tokudb/mysql-test/tokudb/t/bf_create_temp_select.test diff --git a/mysql-test/suite/tokudb/t/bf_delete.test b/storage/tokudb/mysql-test/tokudb/t/bf_delete.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_delete.test rename to storage/tokudb/mysql-test/tokudb/t/bf_delete.test diff --git a/mysql-test/suite/tokudb/t/bf_delete_trigger.test b/storage/tokudb/mysql-test/tokudb/t/bf_delete_trigger.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_delete_trigger.test rename to storage/tokudb/mysql-test/tokudb/t/bf_delete_trigger.test diff --git a/mysql-test/suite/tokudb/t/bf_insert_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_insert_select.test rename to storage/tokudb/mysql-test/tokudb/t/bf_insert_select.test diff --git a/mysql-test/suite/tokudb/t/bf_insert_select_dup_key.test b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_insert_select_dup_key.test rename to storage/tokudb/mysql-test/tokudb/t/bf_insert_select_dup_key.test diff --git a/mysql-test/suite/tokudb/t/bf_insert_select_trigger.test b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_trigger.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_insert_select_trigger.test rename to storage/tokudb/mysql-test/tokudb/t/bf_insert_select_trigger.test diff --git a/mysql-test/suite/tokudb/t/bf_insert_select_update_trigger.test b/storage/tokudb/mysql-test/tokudb/t/bf_insert_select_update_trigger.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_insert_select_update_trigger.test rename to storage/tokudb/mysql-test/tokudb/t/bf_insert_select_update_trigger.test diff --git a/mysql-test/suite/tokudb/t/bf_replace_select.test b/storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_replace_select.test rename to storage/tokudb/mysql-test/tokudb/t/bf_replace_select.test diff --git a/mysql-test/suite/tokudb/t/bf_replace_select_trigger.test b/storage/tokudb/mysql-test/tokudb/t/bf_replace_select_trigger.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_replace_select_trigger.test rename to storage/tokudb/mysql-test/tokudb/t/bf_replace_select_trigger.test diff --git a/mysql-test/suite/tokudb/t/bf_select_hash_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_select_hash_part.test rename to storage/tokudb/mysql-test/tokudb/t/bf_select_hash_part.test diff --git a/mysql-test/suite/tokudb/t/bf_select_range_part.test b/storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test similarity index 100% rename from mysql-test/suite/tokudb/t/bf_select_range_part.test rename to storage/tokudb/mysql-test/tokudb/t/bf_select_range_part.test diff --git a/mysql-test/suite/tokudb/t/bulk-fetch.test b/storage/tokudb/mysql-test/tokudb/t/bulk-fetch.test similarity index 100% rename from mysql-test/suite/tokudb/t/bulk-fetch.test rename to storage/tokudb/mysql-test/tokudb/t/bulk-fetch.test diff --git a/mysql-test/suite/tokudb/t/bulk-fetch2.test b/storage/tokudb/mysql-test/tokudb/t/bulk-fetch2.test similarity index 100% rename from mysql-test/suite/tokudb/t/bulk-fetch2.test rename to storage/tokudb/mysql-test/tokudb/t/bulk-fetch2.test diff --git a/mysql-test/suite/tokudb/t/card_add_drop.test b/storage/tokudb/mysql-test/tokudb/t/card_add_drop.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_add_drop.test rename to storage/tokudb/mysql-test/tokudb/t/card_add_drop.test diff --git a/mysql-test/suite/tokudb/t/card_add_index.test b/storage/tokudb/mysql-test/tokudb/t/card_add_index.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_add_index.test rename to storage/tokudb/mysql-test/tokudb/t/card_add_index.test diff --git a/mysql-test/suite/tokudb/t/card_auto_analyze_lots.test b/storage/tokudb/mysql-test/tokudb/t/card_auto_analyze_lots.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_auto_analyze_lots.test rename to storage/tokudb/mysql-test/tokudb/t/card_auto_analyze_lots.test diff --git a/mysql-test/suite/tokudb/t/card_drop_index.test b/storage/tokudb/mysql-test/tokudb/t/card_drop_index.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_drop_index.test rename to storage/tokudb/mysql-test/tokudb/t/card_drop_index.test diff --git a/mysql-test/suite/tokudb/t/card_drop_index_2.test b/storage/tokudb/mysql-test/tokudb/t/card_drop_index_2.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_drop_index_2.test rename to storage/tokudb/mysql-test/tokudb/t/card_drop_index_2.test diff --git a/mysql-test/suite/tokudb/t/card_drop_pk.test b/storage/tokudb/mysql-test/tokudb/t/card_drop_pk.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_drop_pk.test rename to storage/tokudb/mysql-test/tokudb/t/card_drop_pk.test diff --git a/mysql-test/suite/tokudb/t/card_no_keys.test b/storage/tokudb/mysql-test/tokudb/t/card_no_keys.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_no_keys.test rename to storage/tokudb/mysql-test/tokudb/t/card_no_keys.test diff --git a/mysql-test/suite/tokudb/t/card_pk.test b/storage/tokudb/mysql-test/tokudb/t/card_pk.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_pk.test rename to storage/tokudb/mysql-test/tokudb/t/card_pk.test diff --git a/mysql-test/suite/tokudb/t/card_pk_2.test b/storage/tokudb/mysql-test/tokudb/t/card_pk_2.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_pk_2.test rename to storage/tokudb/mysql-test/tokudb/t/card_pk_2.test diff --git a/mysql-test/suite/tokudb/t/card_pk_sk.test b/storage/tokudb/mysql-test/tokudb/t/card_pk_sk.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_pk_sk.test rename to storage/tokudb/mysql-test/tokudb/t/card_pk_sk.test diff --git a/mysql-test/suite/tokudb/t/card_scale_percent.test b/storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_scale_percent.test rename to storage/tokudb/mysql-test/tokudb/t/card_scale_percent.test diff --git a/mysql-test/suite/tokudb/t/card_sk.test b/storage/tokudb/mysql-test/tokudb/t/card_sk.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_sk.test rename to storage/tokudb/mysql-test/tokudb/t/card_sk.test diff --git a/mysql-test/suite/tokudb/t/card_sk_2.test b/storage/tokudb/mysql-test/tokudb/t/card_sk_2.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_sk_2.test rename to storage/tokudb/mysql-test/tokudb/t/card_sk_2.test diff --git a/mysql-test/suite/tokudb/t/card_unique_sk.test b/storage/tokudb/mysql-test/tokudb/t/card_unique_sk.test similarity index 100% rename from mysql-test/suite/tokudb/t/card_unique_sk.test rename to storage/tokudb/mysql-test/tokudb/t/card_unique_sk.test diff --git a/mysql-test/suite/tokudb/t/change_column_Makefile b/storage/tokudb/mysql-test/tokudb/t/change_column_Makefile similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_Makefile rename to storage/tokudb/mysql-test/tokudb/t/change_column_Makefile diff --git a/mysql-test/suite/tokudb/t/change_column_all.py b/storage/tokudb/mysql-test/tokudb/t/change_column_all.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_all.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_all.py diff --git a/mysql-test/suite/tokudb/t/change_column_all_1000_1.test b/storage/tokudb/mysql-test/tokudb/t/change_column_all_1000_1.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_all_1000_1.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_all_1000_1.test diff --git a/mysql-test/suite/tokudb/t/change_column_all_1000_10.test b/storage/tokudb/mysql-test/tokudb/t/change_column_all_1000_10.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_all_1000_10.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_all_1000_10.test diff --git a/mysql-test/suite/tokudb/t/change_column_auto_inc.test b/storage/tokudb/mysql-test/tokudb/t/change_column_auto_inc.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_auto_inc.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_auto_inc.test diff --git a/mysql-test/suite/tokudb/t/change_column_bin.py b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin.py diff --git a/mysql-test/suite/tokudb/t/change_column_bin.test b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin.test diff --git a/mysql-test/suite/tokudb/t/change_column_bin_descriptor.test b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_descriptor.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin_descriptor.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin_descriptor.test diff --git a/mysql-test/suite/tokudb/t/change_column_bin_key.test b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin_key.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin_key.test diff --git a/mysql-test/suite/tokudb/t/change_column_bin_pad.test b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_pad.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin_pad.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin_pad.test diff --git a/mysql-test/suite/tokudb/t/change_column_bin_rename.py b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin_rename.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py diff --git a/mysql-test/suite/tokudb/t/change_column_bin_rename.test b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_bin_rename.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.test diff --git a/mysql-test/suite/tokudb/t/change_column_blob.py b/storage/tokudb/mysql-test/tokudb/t/change_column_blob.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_blob.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_blob.py diff --git a/mysql-test/suite/tokudb/t/change_column_blob.test b/storage/tokudb/mysql-test/tokudb/t/change_column_blob.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_blob.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_blob.test diff --git a/mysql-test/suite/tokudb/t/change_column_blob_data.py b/storage/tokudb/mysql-test/tokudb/t/change_column_blob_data.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_blob_data.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_blob_data.py diff --git a/mysql-test/suite/tokudb/t/change_column_blob_data.test b/storage/tokudb/mysql-test/tokudb/t/change_column_blob_data.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_blob_data.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_blob_data.test diff --git a/mysql-test/suite/tokudb/t/change_column_char.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_char.py diff --git a/mysql-test/suite/tokudb/t/change_column_char.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_binary.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_binary.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py diff --git a/mysql-test/suite/tokudb/t/change_column_char_binary.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_binary.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_charbinary.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_charbinary.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py diff --git a/mysql-test/suite/tokudb/t/change_column_char_charbinary.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_charbinary.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_charset.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_charset.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_charset.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_charset.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_default.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_default.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_default.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_default.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_descriptor.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_descriptor.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_descriptor.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_descriptor.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_key.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_key.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_key.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_null.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_null.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_null.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_null.test diff --git a/mysql-test/suite/tokudb/t/change_column_char_rename.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_rename.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py diff --git a/mysql-test/suite/tokudb/t/change_column_char_rename.test b/storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_char_rename.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.test diff --git a/mysql-test/suite/tokudb/t/change_column_delete_change_char_5674.test b/storage/tokudb/mysql-test/tokudb/t/change_column_delete_change_char_5674.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_delete_change_char_5674.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_delete_change_char_5674.test diff --git a/mysql-test/suite/tokudb/t/change_column_delete_change_int_5674.test b/storage/tokudb/mysql-test/tokudb/t/change_column_delete_change_int_5674.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_delete_change_int_5674.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_delete_change_int_5674.test diff --git a/mysql-test/suite/tokudb/t/change_column_delete_change_varchar_5674.test b/storage/tokudb/mysql-test/tokudb/t/change_column_delete_change_varchar_5674.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_delete_change_varchar_5674.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_delete_change_varchar_5674.test diff --git a/mysql-test/suite/tokudb/t/change_column_int.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_int.py diff --git a/mysql-test/suite/tokudb/t/change_column_int.test b/storage/tokudb/mysql-test/tokudb/t/change_column_int.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_int.test diff --git a/mysql-test/suite/tokudb/t/change_column_int_default.test b/storage/tokudb/mysql-test/tokudb/t/change_column_int_default.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_default.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_default.test diff --git a/mysql-test/suite/tokudb/t/change_column_int_descriptor.test b/storage/tokudb/mysql-test/tokudb/t/change_column_int_descriptor.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_descriptor.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_descriptor.test diff --git a/mysql-test/suite/tokudb/t/change_column_int_key.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_key.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py diff --git a/mysql-test/suite/tokudb/t/change_column_int_key.test b/storage/tokudb/mysql-test/tokudb/t/change_column_int_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_key.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_key.test diff --git a/mysql-test/suite/tokudb/t/change_column_int_not_supported.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_not_supported.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py diff --git a/mysql-test/suite/tokudb/t/change_column_int_not_supported.test b/storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_not_supported.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.test diff --git a/mysql-test/suite/tokudb/t/change_column_int_rename.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_rename.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py diff --git a/mysql-test/suite/tokudb/t/change_column_int_rename.test b/storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_int_rename.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.test diff --git a/mysql-test/suite/tokudb/t/change_column_multiple_columns.py b/storage/tokudb/mysql-test/tokudb/t/change_column_multiple_columns.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_multiple_columns.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_multiple_columns.py diff --git a/mysql-test/suite/tokudb/t/change_column_multiple_columns.test b/storage/tokudb/mysql-test/tokudb/t/change_column_multiple_columns.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_multiple_columns.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_multiple_columns.test diff --git a/mysql-test/suite/tokudb/t/change_column_text.py b/storage/tokudb/mysql-test/tokudb/t/change_column_text.py similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_text.py rename to storage/tokudb/mysql-test/tokudb/t/change_column_text.py diff --git a/mysql-test/suite/tokudb/t/change_column_text.test b/storage/tokudb/mysql-test/tokudb/t/change_column_text.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_text.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_text.test diff --git a/mysql-test/suite/tokudb/t/change_column_text_data.test b/storage/tokudb/mysql-test/tokudb/t/change_column_text_data.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_text_data.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_text_data.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_cross256.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_cross256.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_cross256.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_cross256.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_default.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_default.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_default.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_default.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_descriptor.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_descriptor.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_descriptor.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_descriptor.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_key.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_key.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_key.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_multiple.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_multiple.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_multiple.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_multiple.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_null.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_null.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_null.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_null.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_rename.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_rename.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_rename.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_rename.test diff --git a/mysql-test/suite/tokudb/t/change_column_varbin_varchar.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varbin_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varbin_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varbin_varchar.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_charset.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_charset.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_charset.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_charset.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_cross256.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_cross256.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_cross256.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_cross256.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_default.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_default.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_default.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_default.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_descriptor.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_descriptor.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_descriptor.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_descriptor.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_key.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_key.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_key.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_null.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_null.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_null.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_null.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_prefix_a.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_prefix_a.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_prefix_a.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_prefix_a.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_prefix_b.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_prefix_b.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_prefix_b.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_prefix_b.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_rename.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_rename.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_rename.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_rename.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_sum_cross256.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_sum_cross256.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_sum_cross256.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_sum_cross256.test diff --git a/mysql-test/suite/tokudb/t/change_column_varchar_varbin.test b/storage/tokudb/mysql-test/tokudb/t/change_column_varchar_varbin.test similarity index 100% rename from mysql-test/suite/tokudb/t/change_column_varchar_varbin.test rename to storage/tokudb/mysql-test/tokudb/t/change_column_varchar_varbin.test diff --git a/mysql-test/suite/tokudb/t/cluster_1829.test b/storage/tokudb/mysql-test/tokudb/t/cluster_1829.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_1829.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_1829.test diff --git a/mysql-test/suite/tokudb/t/cluster_2968-0.test b/storage/tokudb/mysql-test/tokudb/t/cluster_2968-0.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_2968-0.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_2968-0.test diff --git a/mysql-test/suite/tokudb/t/cluster_2968-1.test b/storage/tokudb/mysql-test/tokudb/t/cluster_2968-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_2968-1.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_2968-1.test diff --git a/mysql-test/suite/tokudb/t/cluster_2968-2.test b/storage/tokudb/mysql-test/tokudb/t/cluster_2968-2.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_2968-2.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_2968-2.test diff --git a/mysql-test/suite/tokudb/t/cluster_2968-3.test b/storage/tokudb/mysql-test/tokudb/t/cluster_2968-3.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_2968-3.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_2968-3.test diff --git a/mysql-test/suite/tokudb/t/cluster_create_table.test b/storage/tokudb/mysql-test/tokudb/t/cluster_create_table.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_create_table.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_create_table.test diff --git a/mysql-test/suite/tokudb/t/cluster_delete.test b/storage/tokudb/mysql-test/tokudb/t/cluster_delete.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_delete.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_delete.test diff --git a/mysql-test/suite/tokudb/t/cluster_delete2.test b/storage/tokudb/mysql-test/tokudb/t/cluster_delete2.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_delete2.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_delete2.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter_hidden.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_hidden.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter_hidden.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter_hidden.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter_key.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter_key.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter_key.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter_unpack_varchar.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter_unpack_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_and_int_hidden.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter_unpack_varchar_hidden.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_hidden.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter_unpack_varchar_hidden.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter_unpack_varchar_hidden.test diff --git a/mysql-test/suite/tokudb/t/cluster_filter_varchar_prefix.test b/storage/tokudb/mysql-test/tokudb/t/cluster_filter_varchar_prefix.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_filter_varchar_prefix.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_filter_varchar_prefix.test diff --git a/mysql-test/suite/tokudb/t/cluster_key.test b/storage/tokudb/mysql-test/tokudb/t/cluster_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_key.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_key.test diff --git a/mysql-test/suite/tokudb/t/cluster_key_part.test b/storage/tokudb/mysql-test/tokudb/t/cluster_key_part.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_key_part.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_key_part.test diff --git a/mysql-test/suite/tokudb/t/cluster_query_plan.test b/storage/tokudb/mysql-test/tokudb/t/cluster_query_plan.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_query_plan.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_query_plan.test diff --git a/mysql-test/suite/tokudb/t/cluster_tokudb_bug_993.test b/storage/tokudb/mysql-test/tokudb/t/cluster_tokudb_bug_993.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_tokudb_bug_993.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_tokudb_bug_993.test diff --git a/mysql-test/suite/tokudb/t/cluster_tokudb_bug_993_2.test b/storage/tokudb/mysql-test/tokudb/t/cluster_tokudb_bug_993_2.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_tokudb_bug_993_2.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_tokudb_bug_993_2.test diff --git a/mysql-test/suite/tokudb/t/cluster_update.test b/storage/tokudb/mysql-test/tokudb/t/cluster_update.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_update.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_update.test diff --git a/mysql-test/suite/tokudb/t/cluster_update2.test b/storage/tokudb/mysql-test/tokudb/t/cluster_update2.test similarity index 100% rename from mysql-test/suite/tokudb/t/cluster_update2.test rename to storage/tokudb/mysql-test/tokudb/t/cluster_update2.test diff --git a/mysql-test/suite/tokudb/t/ctype_ascii.test b/storage/tokudb/mysql-test/tokudb/t/ctype_ascii.test similarity index 100% rename from mysql-test/suite/tokudb/t/ctype_ascii.test rename to storage/tokudb/mysql-test/tokudb/t/ctype_ascii.test diff --git a/mysql-test/suite/tokudb/t/ctype_collate.test b/storage/tokudb/mysql-test/tokudb/t/ctype_collate.test similarity index 100% rename from mysql-test/suite/tokudb/t/ctype_collate.test rename to storage/tokudb/mysql-test/tokudb/t/ctype_collate.test diff --git a/mysql-test/suite/tokudb/t/ctype_cp1250_ch.test b/storage/tokudb/mysql-test/tokudb/t/ctype_cp1250_ch.test similarity index 100% rename from mysql-test/suite/tokudb/t/ctype_cp1250_ch.test rename to storage/tokudb/mysql-test/tokudb/t/ctype_cp1250_ch.test diff --git a/mysql-test/suite/tokudb/t/ctype_cp1251.test b/storage/tokudb/mysql-test/tokudb/t/ctype_cp1251.test similarity index 100% rename from mysql-test/suite/tokudb/t/ctype_cp1251.test rename to storage/tokudb/mysql-test/tokudb/t/ctype_cp1251.test diff --git a/mysql-test/suite/tokudb/t/disabled.def b/storage/tokudb/mysql-test/tokudb/t/disabled.def similarity index 100% rename from mysql-test/suite/tokudb/t/disabled.def rename to storage/tokudb/mysql-test/tokudb/t/disabled.def diff --git a/mysql-test/suite/tokudb/t/ext_key_1_innodb.test b/storage/tokudb/mysql-test/tokudb/t/ext_key_1_innodb.test similarity index 100% rename from mysql-test/suite/tokudb/t/ext_key_1_innodb.test rename to storage/tokudb/mysql-test/tokudb/t/ext_key_1_innodb.test diff --git a/mysql-test/suite/tokudb/t/ext_key_1_tokudb.test b/storage/tokudb/mysql-test/tokudb/t/ext_key_1_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb/t/ext_key_1_tokudb.test rename to storage/tokudb/mysql-test/tokudb/t/ext_key_1_tokudb.test diff --git a/mysql-test/suite/tokudb/t/ext_key_2_innodb.test b/storage/tokudb/mysql-test/tokudb/t/ext_key_2_innodb.test similarity index 100% rename from mysql-test/suite/tokudb/t/ext_key_2_innodb.test rename to storage/tokudb/mysql-test/tokudb/t/ext_key_2_innodb.test diff --git a/mysql-test/suite/tokudb/t/ext_key_2_tokudb.test b/storage/tokudb/mysql-test/tokudb/t/ext_key_2_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb/t/ext_key_2_tokudb.test rename to storage/tokudb/mysql-test/tokudb/t/ext_key_2_tokudb.test diff --git a/mysql-test/suite/tokudb/t/fast_update_Makefile b/storage/tokudb/mysql-test/tokudb/t/fast_update_Makefile similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_Makefile rename to storage/tokudb/mysql-test/tokudb/t/fast_update_Makefile diff --git a/mysql-test/suite/tokudb/t/fast_update_binlog_mixed.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_binlog_mixed.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_binlog_mixed.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_binlog_mixed.test diff --git a/mysql-test/suite/tokudb/t/fast_update_binlog_row.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_binlog_row.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_binlog_row.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_binlog_row.test diff --git a/mysql-test/suite/tokudb/t/fast_update_binlog_statement.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_binlog_statement.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_binlog_statement.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_binlog_statement.test diff --git a/mysql-test/suite/tokudb/t/fast_update_blobs.py b/storage/tokudb/mysql-test/tokudb/t/fast_update_blobs.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_blobs.py rename to storage/tokudb/mysql-test/tokudb/t/fast_update_blobs.py diff --git a/mysql-test/suite/tokudb/t/fast_update_blobs.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_blobs.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_blobs.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_blobs.test diff --git a/mysql-test/suite/tokudb/t/fast_update_blobs_fixed_varchar.py b/storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_fixed_varchar.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_blobs_fixed_varchar.py rename to storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_fixed_varchar.py diff --git a/mysql-test/suite/tokudb/t/fast_update_blobs_fixed_varchar.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_fixed_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_blobs_fixed_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_fixed_varchar.test diff --git a/mysql-test/suite/tokudb/t/fast_update_blobs_with_varchar.py b/storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_with_varchar.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_blobs_with_varchar.py rename to storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_with_varchar.py diff --git a/mysql-test/suite/tokudb/t/fast_update_blobs_with_varchar.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_with_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_blobs_with_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_blobs_with_varchar.test diff --git a/mysql-test/suite/tokudb/t/fast_update_char.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_char.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_char.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_char.test diff --git a/mysql-test/suite/tokudb/t/fast_update_deadlock.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_deadlock.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_deadlock.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_deadlock.test diff --git a/mysql-test/suite/tokudb/t/fast_update_decr_floor.py b/storage/tokudb/mysql-test/tokudb/t/fast_update_decr_floor.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_decr_floor.py rename to storage/tokudb/mysql-test/tokudb/t/fast_update_decr_floor.py diff --git a/mysql-test/suite/tokudb/t/fast_update_decr_floor.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_decr_floor.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_decr_floor.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_decr_floor.test diff --git a/mysql-test/suite/tokudb/t/fast_update_disable_slow_update.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_disable_slow_update.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_disable_slow_update.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_disable_slow_update.test diff --git a/mysql-test/suite/tokudb/t/fast_update_error.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_error.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_error.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_error.test diff --git a/mysql-test/suite/tokudb/t/fast_update_int.py b/storage/tokudb/mysql-test/tokudb/t/fast_update_int.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_int.py rename to storage/tokudb/mysql-test/tokudb/t/fast_update_int.py diff --git a/mysql-test/suite/tokudb/t/fast_update_int.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_int.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_int.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_int.test diff --git a/mysql-test/suite/tokudb/t/fast_update_int_bounds.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_int_bounds.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_int_bounds.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_int_bounds.test diff --git a/mysql-test/suite/tokudb/t/fast_update_key.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_key.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_key.test diff --git a/mysql-test/suite/tokudb/t/fast_update_sqlmode.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_sqlmode.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_sqlmode.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_sqlmode.test diff --git a/mysql-test/suite/tokudb/t/fast_update_uint_bounds.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_uint_bounds.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_uint_bounds.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_uint_bounds.test diff --git a/mysql-test/suite/tokudb/t/fast_update_varchar.py b/storage/tokudb/mysql-test/tokudb/t/fast_update_varchar.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_varchar.py rename to storage/tokudb/mysql-test/tokudb/t/fast_update_varchar.py diff --git a/mysql-test/suite/tokudb/t/fast_update_varchar.test b/storage/tokudb/mysql-test/tokudb/t/fast_update_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_update_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/fast_update_varchar.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_bin_pad.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_bin_pad.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_bin_pad.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_bin_pad.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_char.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_char.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_char.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_char.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_deadlock.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_deadlock.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_deadlock.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_deadlock.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_int.py b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_int.py similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_int.py rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_int.py diff --git a/mysql-test/suite/tokudb/t/fast_upsert_int.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_int.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_int.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_int.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_key.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_key.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_key.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_key.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_sqlmode.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_sqlmode.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_sqlmode.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_sqlmode.test diff --git a/mysql-test/suite/tokudb/t/fast_upsert_values.test b/storage/tokudb/mysql-test/tokudb/t/fast_upsert_values.test similarity index 100% rename from mysql-test/suite/tokudb/t/fast_upsert_values.test rename to storage/tokudb/mysql-test/tokudb/t/fast_upsert_values.test diff --git a/mysql-test/suite/tokudb/t/hotindex-del-0.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-del-0.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-del-0.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-del-0.test diff --git a/mysql-test/suite/tokudb/t/hotindex-del-1.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-del-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-del-1.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-del-1.test diff --git a/mysql-test/suite/tokudb/t/hotindex-del-fast.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-del-fast.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-del-fast.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-del-fast.test diff --git a/mysql-test/suite/tokudb/t/hotindex-del-slow.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-del-slow.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-del-slow.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-del-slow.test diff --git a/mysql-test/suite/tokudb/t/hotindex-insert-0.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-insert-0.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-insert-0.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-insert-0.test diff --git a/mysql-test/suite/tokudb/t/hotindex-insert-1.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-insert-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-insert-1.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-insert-1.test diff --git a/mysql-test/suite/tokudb/t/hotindex-insert-2.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-insert-2.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-insert-2.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-insert-2.test diff --git a/mysql-test/suite/tokudb/t/hotindex-insert-bigchar.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-insert-bigchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-insert-bigchar.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-insert-bigchar.test diff --git a/mysql-test/suite/tokudb/t/hotindex-update-0.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-update-0.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-update-0.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-update-0.test diff --git a/mysql-test/suite/tokudb/t/hotindex-update-1.test b/storage/tokudb/mysql-test/tokudb/t/hotindex-update-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/hotindex-update-1.test rename to storage/tokudb/mysql-test/tokudb/t/hotindex-update-1.test diff --git a/mysql-test/suite/tokudb/t/i_s_tokudb_lock_waits_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test similarity index 100% rename from mysql-test/suite/tokudb/t/i_s_tokudb_lock_waits_released.test rename to storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test diff --git a/mysql-test/suite/tokudb/t/i_s_tokudb_lock_waits_timeout.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test similarity index 100% rename from mysql-test/suite/tokudb/t/i_s_tokudb_lock_waits_timeout.test rename to storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test diff --git a/mysql-test/suite/tokudb/t/i_s_tokudb_locks.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test similarity index 100% rename from mysql-test/suite/tokudb/t/i_s_tokudb_locks.test rename to storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test diff --git a/mysql-test/suite/tokudb/t/i_s_tokudb_locks_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test similarity index 100% rename from mysql-test/suite/tokudb/t/i_s_tokudb_locks_released.test rename to storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test diff --git a/mysql-test/suite/tokudb/t/i_s_tokudb_trx.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_trx.test similarity index 100% rename from mysql-test/suite/tokudb/t/i_s_tokudb_trx.test rename to storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_trx.test diff --git a/mysql-test/suite/tokudb/t/information-schema-global-status.test b/storage/tokudb/mysql-test/tokudb/t/information-schema-global-status.test similarity index 100% rename from mysql-test/suite/tokudb/t/information-schema-global-status.test rename to storage/tokudb/mysql-test/tokudb/t/information-schema-global-status.test diff --git a/mysql-test/suite/tokudb/t/lockretry-insert.writelocktable.test b/storage/tokudb/mysql-test/tokudb/t/lockretry-insert.writelocktable.test similarity index 100% rename from mysql-test/suite/tokudb/t/lockretry-insert.writelocktable.test rename to storage/tokudb/mysql-test/tokudb/t/lockretry-insert.writelocktable.test diff --git a/mysql-test/suite/tokudb/t/lockretry-writelocktable.insert.test b/storage/tokudb/mysql-test/tokudb/t/lockretry-writelocktable.insert.test similarity index 100% rename from mysql-test/suite/tokudb/t/lockretry-writelocktable.insert.test rename to storage/tokudb/mysql-test/tokudb/t/lockretry-writelocktable.insert.test diff --git a/mysql-test/suite/tokudb/t/lockretry-writelocktable.insert2.test b/storage/tokudb/mysql-test/tokudb/t/lockretry-writelocktable.insert2.test similarity index 100% rename from mysql-test/suite/tokudb/t/lockretry-writelocktable.insert2.test rename to storage/tokudb/mysql-test/tokudb/t/lockretry-writelocktable.insert2.test diff --git a/mysql-test/suite/tokudb/t/locks-blocking-row-locks-getset.test b/storage/tokudb/mysql-test/tokudb/t/locks-blocking-row-locks-getset.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-blocking-row-locks-getset.test rename to storage/tokudb/mysql-test/tokudb/t/locks-blocking-row-locks-getset.test diff --git a/mysql-test/suite/tokudb/t/locks-blocking-row-locks.test b/storage/tokudb/mysql-test/tokudb/t/locks-blocking-row-locks.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-blocking-row-locks.test rename to storage/tokudb/mysql-test/tokudb/t/locks-blocking-row-locks.test diff --git a/mysql-test/suite/tokudb/t/locks-border-locks.notyet.3981 b/storage/tokudb/mysql-test/tokudb/t/locks-border-locks.notyet.3981 similarity index 100% rename from mysql-test/suite/tokudb/t/locks-border-locks.notyet.3981 rename to storage/tokudb/mysql-test/tokudb/t/locks-border-locks.notyet.3981 diff --git a/mysql-test/suite/tokudb/t/locks-delete-deadlock-1.test b/storage/tokudb/mysql-test/tokudb/t/locks-delete-deadlock-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-delete-deadlock-1.test rename to storage/tokudb/mysql-test/tokudb/t/locks-delete-deadlock-1.test diff --git a/mysql-test/suite/tokudb/t/locks-no-read-lock-serializable-autocommit.test b/storage/tokudb/mysql-test/tokudb/t/locks-no-read-lock-serializable-autocommit.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-no-read-lock-serializable-autocommit.test rename to storage/tokudb/mysql-test/tokudb/t/locks-no-read-lock-serializable-autocommit.test diff --git a/mysql-test/suite/tokudb/t/locks-select-update-1.test b/storage/tokudb/mysql-test/tokudb/t/locks-select-update-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-select-update-1.test rename to storage/tokudb/mysql-test/tokudb/t/locks-select-update-1.test diff --git a/mysql-test/suite/tokudb/t/locks-select-update-2.test b/storage/tokudb/mysql-test/tokudb/t/locks-select-update-2.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-select-update-2.test rename to storage/tokudb/mysql-test/tokudb/t/locks-select-update-2.test diff --git a/mysql-test/suite/tokudb/t/locks-select-update-3.test b/storage/tokudb/mysql-test/tokudb/t/locks-select-update-3.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-select-update-3.test rename to storage/tokudb/mysql-test/tokudb/t/locks-select-update-3.test diff --git a/mysql-test/suite/tokudb/t/locks-update-deadlock-1.test b/storage/tokudb/mysql-test/tokudb/t/locks-update-deadlock-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/locks-update-deadlock-1.test rename to storage/tokudb/mysql-test/tokudb/t/locks-update-deadlock-1.test diff --git a/mysql-test/suite/tokudb/t/mvcc-1.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-1.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-1.test diff --git a/mysql-test/suite/tokudb/t/mvcc-10.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-10.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-10.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-10.test diff --git a/mysql-test/suite/tokudb/t/mvcc-11.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-11.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-11.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-11.test diff --git a/mysql-test/suite/tokudb/t/mvcc-12.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-12.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-12.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-12.test diff --git a/mysql-test/suite/tokudb/t/mvcc-13.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-13.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-13.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-13.test diff --git a/mysql-test/suite/tokudb/t/mvcc-14.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-14.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-14.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-14.test diff --git a/mysql-test/suite/tokudb/t/mvcc-15.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-15.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-15.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-15.test diff --git a/mysql-test/suite/tokudb/t/mvcc-16.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-16.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-16.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-16.test diff --git a/mysql-test/suite/tokudb/t/mvcc-17.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-17.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-17.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-17.test diff --git a/mysql-test/suite/tokudb/t/mvcc-18.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-18.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-18.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-18.test diff --git a/mysql-test/suite/tokudb/t/mvcc-19.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-19.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-19.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-19.test diff --git a/mysql-test/suite/tokudb/t/mvcc-2.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-2.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-2.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-2.test diff --git a/mysql-test/suite/tokudb/t/mvcc-20.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-20.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-20.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-20.test diff --git a/mysql-test/suite/tokudb/t/mvcc-21.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-21.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-21.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-21.test diff --git a/mysql-test/suite/tokudb/t/mvcc-22.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-22.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-22.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-22.test diff --git a/mysql-test/suite/tokudb/t/mvcc-23.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-23.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-23.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-23.test diff --git a/mysql-test/suite/tokudb/t/mvcc-24.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-24.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-24.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-24.test diff --git a/mysql-test/suite/tokudb/t/mvcc-25.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-25.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-25.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-25.test diff --git a/mysql-test/suite/tokudb/t/mvcc-26.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-26.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-26.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-26.test diff --git a/mysql-test/suite/tokudb/t/mvcc-27.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-27.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-27.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-27.test diff --git a/mysql-test/suite/tokudb/t/mvcc-28.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-28.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-28.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-28.test diff --git a/mysql-test/suite/tokudb/t/mvcc-2808-read-committed.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-2808-read-committed.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-2808-read-committed.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-2808-read-committed.test diff --git a/mysql-test/suite/tokudb/t/mvcc-2808-read-uncommitted.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-2808-read-uncommitted.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-2808-read-uncommitted.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-2808-read-uncommitted.test diff --git a/mysql-test/suite/tokudb/t/mvcc-29.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-29.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-29.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-29.test diff --git a/mysql-test/suite/tokudb/t/mvcc-3.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-3.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-3.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-3.test diff --git a/mysql-test/suite/tokudb/t/mvcc-30.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-30.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-30.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-30.test diff --git a/mysql-test/suite/tokudb/t/mvcc-31.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-31.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-31.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-31.test diff --git a/mysql-test/suite/tokudb/t/mvcc-33.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-33.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-33.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-33.test diff --git a/mysql-test/suite/tokudb/t/mvcc-34.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-34.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-34.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-34.test diff --git a/mysql-test/suite/tokudb/t/mvcc-35.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-35.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-35.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-35.test diff --git a/mysql-test/suite/tokudb/t/mvcc-36.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-36.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-36.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-36.test diff --git a/mysql-test/suite/tokudb/t/mvcc-37.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-37.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-37.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-37.test diff --git a/mysql-test/suite/tokudb/t/mvcc-38.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-38.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-38.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-38.test diff --git a/mysql-test/suite/tokudb/t/mvcc-39.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-39.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-39.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-39.test diff --git a/mysql-test/suite/tokudb/t/mvcc-4.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-4.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-4.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-4.test diff --git a/mysql-test/suite/tokudb/t/mvcc-40.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-40.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-40.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-40.test diff --git a/mysql-test/suite/tokudb/t/mvcc-5.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-5.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-5.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-5.test diff --git a/mysql-test/suite/tokudb/t/mvcc-6.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-6.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-6.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-6.test diff --git a/mysql-test/suite/tokudb/t/mvcc-7.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-7.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-7.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-7.test diff --git a/mysql-test/suite/tokudb/t/mvcc-8.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-8.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-8.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-8.test diff --git a/mysql-test/suite/tokudb/t/mvcc-9.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-9.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-9.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-9.test diff --git a/mysql-test/suite/tokudb/t/mvcc-checksum-locks.test b/storage/tokudb/mysql-test/tokudb/t/mvcc-checksum-locks.test similarity index 100% rename from mysql-test/suite/tokudb/t/mvcc-checksum-locks.test rename to storage/tokudb/mysql-test/tokudb/t/mvcc-checksum-locks.test diff --git a/mysql-test/suite/tokudb/t/nested_txn_autocommit.test b/storage/tokudb/mysql-test/tokudb/t/nested_txn_autocommit.test similarity index 100% rename from mysql-test/suite/tokudb/t/nested_txn_autocommit.test rename to storage/tokudb/mysql-test/tokudb/t/nested_txn_autocommit.test diff --git a/mysql-test/suite/tokudb/t/nested_txn_begin.test b/storage/tokudb/mysql-test/tokudb/t/nested_txn_begin.test similarity index 100% rename from mysql-test/suite/tokudb/t/nested_txn_begin.test rename to storage/tokudb/mysql-test/tokudb/t/nested_txn_begin.test diff --git a/mysql-test/suite/tokudb/t/nested_txn_implicit_commit.test b/storage/tokudb/mysql-test/tokudb/t/nested_txn_implicit_commit.test similarity index 100% rename from mysql-test/suite/tokudb/t/nested_txn_implicit_commit.test rename to storage/tokudb/mysql-test/tokudb/t/nested_txn_implicit_commit.test diff --git a/mysql-test/suite/tokudb/t/prim_key_1.test b/storage/tokudb/mysql-test/tokudb/t/prim_key_1.test similarity index 100% rename from mysql-test/suite/tokudb/t/prim_key_1.test rename to storage/tokudb/mysql-test/tokudb/t/prim_key_1.test diff --git a/mysql-test/suite/tokudb/t/prim_key_2.test b/storage/tokudb/mysql-test/tokudb/t/prim_key_2.test similarity index 100% rename from mysql-test/suite/tokudb/t/prim_key_2.test rename to storage/tokudb/mysql-test/tokudb/t/prim_key_2.test diff --git a/mysql-test/suite/tokudb/t/prim_key_3.test b/storage/tokudb/mysql-test/tokudb/t/prim_key_3.test similarity index 100% rename from mysql-test/suite/tokudb/t/prim_key_3.test rename to storage/tokudb/mysql-test/tokudb/t/prim_key_3.test diff --git a/mysql-test/suite/tokudb/t/prim_key_4.test b/storage/tokudb/mysql-test/tokudb/t/prim_key_4.test similarity index 100% rename from mysql-test/suite/tokudb/t/prim_key_4.test rename to storage/tokudb/mysql-test/tokudb/t/prim_key_4.test diff --git a/mysql-test/suite/tokudb/t/prim_key_5.test b/storage/tokudb/mysql-test/tokudb/t/prim_key_5.test similarity index 100% rename from mysql-test/suite/tokudb/t/prim_key_5.test rename to storage/tokudb/mysql-test/tokudb/t/prim_key_5.test diff --git a/mysql-test/suite/tokudb/t/prim_key_6.test b/storage/tokudb/mysql-test/tokudb/t/prim_key_6.test similarity index 100% rename from mysql-test/suite/tokudb/t/prim_key_6.test rename to storage/tokudb/mysql-test/tokudb/t/prim_key_6.test diff --git a/mysql-test/suite/tokudb/t/replace-ignore.test b/storage/tokudb/mysql-test/tokudb/t/replace-ignore.test similarity index 100% rename from mysql-test/suite/tokudb/t/replace-ignore.test rename to storage/tokudb/mysql-test/tokudb/t/replace-ignore.test diff --git a/mysql-test/suite/tokudb/t/rows-32m-0.test b/storage/tokudb/mysql-test/tokudb/t/rows-32m-0.test similarity index 100% rename from mysql-test/suite/tokudb/t/rows-32m-0.test rename to storage/tokudb/mysql-test/tokudb/t/rows-32m-0.test diff --git a/mysql-test/suite/tokudb/t/rows-32m-1.test b/storage/tokudb/mysql-test/tokudb/t/rows-32m-1.test similarity index 100% rename from mysql-test/suite/tokudb/t/rows-32m-1.test rename to storage/tokudb/mysql-test/tokudb/t/rows-32m-1.test diff --git a/mysql-test/suite/tokudb/t/rows-32m-rand-insert.test b/storage/tokudb/mysql-test/tokudb/t/rows-32m-rand-insert.test similarity index 100% rename from mysql-test/suite/tokudb/t/rows-32m-rand-insert.test rename to storage/tokudb/mysql-test/tokudb/t/rows-32m-rand-insert.test diff --git a/mysql-test/suite/tokudb/t/rows-32m-seq-insert.test b/storage/tokudb/mysql-test/tokudb/t/rows-32m-seq-insert.test similarity index 100% rename from mysql-test/suite/tokudb/t/rows-32m-seq-insert.test rename to storage/tokudb/mysql-test/tokudb/t/rows-32m-seq-insert.test diff --git a/mysql-test/suite/tokudb/t/savepoint-1078-2.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-1078-2.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-1078-2.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-1078-2.test diff --git a/mysql-test/suite/tokudb/t/savepoint-1078-3.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-1078-3.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-1078-3.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-1078-3.test diff --git a/mysql-test/suite/tokudb/t/savepoint-1078-4.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-1078-4.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-1078-4.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-1078-4.test diff --git a/mysql-test/suite/tokudb/t/savepoint-1078.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-1078.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-1078.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-1078.test diff --git a/mysql-test/suite/tokudb/t/savepoint-2.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-2.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-2.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-2.test diff --git a/mysql-test/suite/tokudb/t/savepoint-3.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-3.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-3.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-3.test diff --git a/mysql-test/suite/tokudb/t/savepoint-4.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-4.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-4.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-4.test diff --git a/mysql-test/suite/tokudb/t/savepoint-5.test b/storage/tokudb/mysql-test/tokudb/t/savepoint-5.test similarity index 100% rename from mysql-test/suite/tokudb/t/savepoint-5.test rename to storage/tokudb/mysql-test/tokudb/t/savepoint-5.test diff --git a/mysql-test/suite/tokudb/t/simple_delete_all.test b/storage/tokudb/mysql-test/tokudb/t/simple_delete_all.test similarity index 100% rename from mysql-test/suite/tokudb/t/simple_delete_all.test rename to storage/tokudb/mysql-test/tokudb/t/simple_delete_all.test diff --git a/mysql-test/suite/tokudb/t/simple_join_tokudb_innodb.test b/storage/tokudb/mysql-test/tokudb/t/simple_join_tokudb_innodb.test similarity index 100% rename from mysql-test/suite/tokudb/t/simple_join_tokudb_innodb.test rename to storage/tokudb/mysql-test/tokudb/t/simple_join_tokudb_innodb.test diff --git a/mysql-test/suite/tokudb/t/simple_join_tokudb_myisam.test b/storage/tokudb/mysql-test/tokudb/t/simple_join_tokudb_myisam.test similarity index 100% rename from mysql-test/suite/tokudb/t/simple_join_tokudb_myisam.test rename to storage/tokudb/mysql-test/tokudb/t/simple_join_tokudb_myisam.test diff --git a/mysql-test/suite/tokudb/t/simple_truncate.test b/storage/tokudb/mysql-test/tokudb/t/simple_truncate.test similarity index 100% rename from mysql-test/suite/tokudb/t/simple_truncate.test rename to storage/tokudb/mysql-test/tokudb/t/simple_truncate.test diff --git a/mysql-test/suite/tokudb/t/sql_mode_default.test b/storage/tokudb/mysql-test/tokudb/t/sql_mode_default.test similarity index 100% rename from mysql-test/suite/tokudb/t/sql_mode_default.test rename to storage/tokudb/mysql-test/tokudb/t/sql_mode_default.test diff --git a/mysql-test/suite/tokudb/t/storage_engine_default.test b/storage/tokudb/mysql-test/tokudb/t/storage_engine_default.test similarity index 100% rename from mysql-test/suite/tokudb/t/storage_engine_default.test rename to storage/tokudb/mysql-test/tokudb/t/storage_engine_default.test diff --git a/mysql-test/suite/tokudb.add_index/t/suite.opt b/storage/tokudb/mysql-test/tokudb/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/suite.opt rename to storage/tokudb/mysql-test/tokudb/t/suite.opt diff --git a/mysql-test/suite/tokudb/t/tokudb_support_xa.test b/storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test similarity index 100% rename from mysql-test/suite/tokudb/t/tokudb_support_xa.test rename to storage/tokudb/mysql-test/tokudb/t/tokudb_support_xa.test diff --git a/mysql-test/suite/tokudb/t/truncate_row_count.test b/storage/tokudb/mysql-test/tokudb/t/truncate_row_count.test similarity index 100% rename from mysql-test/suite/tokudb/t/truncate_row_count.test rename to storage/tokudb/mysql-test/tokudb/t/truncate_row_count.test diff --git a/mysql-test/suite/tokudb/t/truncate_txn_commit.test b/storage/tokudb/mysql-test/tokudb/t/truncate_txn_commit.test similarity index 100% rename from mysql-test/suite/tokudb/t/truncate_txn_commit.test rename to storage/tokudb/mysql-test/tokudb/t/truncate_txn_commit.test diff --git a/mysql-test/suite/tokudb/t/truncate_txn_rollback.test b/storage/tokudb/mysql-test/tokudb/t/truncate_txn_rollback.test similarity index 100% rename from mysql-test/suite/tokudb/t/truncate_txn_rollback.test rename to storage/tokudb/mysql-test/tokudb/t/truncate_txn_rollback.test diff --git a/mysql-test/suite/tokudb/t/truncate_txn_rollback_innodb.test b/storage/tokudb/mysql-test/tokudb/t/truncate_txn_rollback_innodb.test similarity index 100% rename from mysql-test/suite/tokudb/t/truncate_txn_rollback_innodb.test rename to storage/tokudb/mysql-test/tokudb/t/truncate_txn_rollback_innodb.test diff --git a/mysql-test/suite/tokudb/t/type_binary.test b/storage/tokudb/mysql-test/tokudb/t/type_binary.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_binary.test rename to storage/tokudb/mysql-test/tokudb/t/type_binary.test diff --git a/mysql-test/suite/tokudb/t/type_bit.test b/storage/tokudb/mysql-test/tokudb/t/type_bit.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_bit.test rename to storage/tokudb/mysql-test/tokudb/t/type_bit.test diff --git a/mysql-test/suite/tokudb/t/type_bit_innodb.test b/storage/tokudb/mysql-test/tokudb/t/type_bit_innodb.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_bit_innodb.test rename to storage/tokudb/mysql-test/tokudb/t/type_bit_innodb.test diff --git a/mysql-test/suite/tokudb/t/type_blob.test b/storage/tokudb/mysql-test/tokudb/t/type_blob.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_blob.test rename to storage/tokudb/mysql-test/tokudb/t/type_blob.test diff --git a/mysql-test/suite/tokudb/t/type_date.test b/storage/tokudb/mysql-test/tokudb/t/type_date.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_date.test rename to storage/tokudb/mysql-test/tokudb/t/type_date.test diff --git a/mysql-test/suite/tokudb/t/type_datetime.test b/storage/tokudb/mysql-test/tokudb/t/type_datetime.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_datetime.test rename to storage/tokudb/mysql-test/tokudb/t/type_datetime.test diff --git a/mysql-test/suite/tokudb/t/type_decimal.test b/storage/tokudb/mysql-test/tokudb/t/type_decimal.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_decimal.test rename to storage/tokudb/mysql-test/tokudb/t/type_decimal.test diff --git a/mysql-test/suite/tokudb/t/type_enum.test b/storage/tokudb/mysql-test/tokudb/t/type_enum.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_enum.test rename to storage/tokudb/mysql-test/tokudb/t/type_enum.test diff --git a/mysql-test/suite/tokudb/t/type_float.test b/storage/tokudb/mysql-test/tokudb/t/type_float.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_float.test rename to storage/tokudb/mysql-test/tokudb/t/type_float.test diff --git a/mysql-test/suite/tokudb/t/type_nchar.test b/storage/tokudb/mysql-test/tokudb/t/type_nchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_nchar.test rename to storage/tokudb/mysql-test/tokudb/t/type_nchar.test diff --git a/mysql-test/suite/tokudb/t/type_newdecimal-big.test b/storage/tokudb/mysql-test/tokudb/t/type_newdecimal-big.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_newdecimal-big.test rename to storage/tokudb/mysql-test/tokudb/t/type_newdecimal-big.test diff --git a/mysql-test/suite/tokudb/t/type_newdecimal.test b/storage/tokudb/mysql-test/tokudb/t/type_newdecimal.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_newdecimal.test rename to storage/tokudb/mysql-test/tokudb/t/type_newdecimal.test diff --git a/mysql-test/suite/tokudb/t/type_ranges.test b/storage/tokudb/mysql-test/tokudb/t/type_ranges.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_ranges.test rename to storage/tokudb/mysql-test/tokudb/t/type_ranges.test diff --git a/mysql-test/suite/tokudb/t/type_set.test b/storage/tokudb/mysql-test/tokudb/t/type_set.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_set.test rename to storage/tokudb/mysql-test/tokudb/t/type_set.test diff --git a/mysql-test/suite/tokudb/t/type_temporal_fractional.test b/storage/tokudb/mysql-test/tokudb/t/type_temporal_fractional.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_temporal_fractional.test rename to storage/tokudb/mysql-test/tokudb/t/type_temporal_fractional.test diff --git a/mysql-test/suite/tokudb/t/type_temporal_upgrade.test b/storage/tokudb/mysql-test/tokudb/t/type_temporal_upgrade.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_temporal_upgrade.test rename to storage/tokudb/mysql-test/tokudb/t/type_temporal_upgrade.test diff --git a/mysql-test/suite/tokudb/t/type_time.test b/storage/tokudb/mysql-test/tokudb/t/type_time.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_time.test rename to storage/tokudb/mysql-test/tokudb/t/type_time.test diff --git a/mysql-test/suite/tokudb/t/type_timestamp-master.opt b/storage/tokudb/mysql-test/tokudb/t/type_timestamp-master.opt similarity index 100% rename from mysql-test/suite/tokudb/t/type_timestamp-master.opt rename to storage/tokudb/mysql-test/tokudb/t/type_timestamp-master.opt diff --git a/mysql-test/suite/tokudb/t/type_timestamp.test b/storage/tokudb/mysql-test/tokudb/t/type_timestamp.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_timestamp.test rename to storage/tokudb/mysql-test/tokudb/t/type_timestamp.test diff --git a/mysql-test/suite/tokudb/t/type_timestamp_explicit-master.opt b/storage/tokudb/mysql-test/tokudb/t/type_timestamp_explicit-master.opt similarity index 100% rename from mysql-test/suite/tokudb/t/type_timestamp_explicit-master.opt rename to storage/tokudb/mysql-test/tokudb/t/type_timestamp_explicit-master.opt diff --git a/mysql-test/suite/tokudb/t/type_timestamp_explicit.test b/storage/tokudb/mysql-test/tokudb/t/type_timestamp_explicit.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_timestamp_explicit.test rename to storage/tokudb/mysql-test/tokudb/t/type_timestamp_explicit.test diff --git a/mysql-test/suite/tokudb/t/type_uint.test b/storage/tokudb/mysql-test/tokudb/t/type_uint.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_uint.test rename to storage/tokudb/mysql-test/tokudb/t/type_uint.test diff --git a/mysql-test/suite/tokudb/t/type_varchar.test b/storage/tokudb/mysql-test/tokudb/t/type_varchar.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_varchar.test rename to storage/tokudb/mysql-test/tokudb/t/type_varchar.test diff --git a/mysql-test/suite/tokudb/t/type_year.test b/storage/tokudb/mysql-test/tokudb/t/type_year.test similarity index 100% rename from mysql-test/suite/tokudb/t/type_year.test rename to storage/tokudb/mysql-test/tokudb/t/type_year.test diff --git a/mysql-test/suite/tokudb.add_index/r/1522.result b/storage/tokudb/mysql-test/tokudb_add_index/r/1522.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/1522.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/1522.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_1.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_1.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_1.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_1.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_10.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_10.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_10.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_10.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_11.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_11.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_11.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_11.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_12.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_12.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_12.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_12.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_13.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_13.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_13.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_13.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_14.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_14.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_14.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_14.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_15.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_15.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_15.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_15.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_16.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_16.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_16.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_16.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_17.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_17.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_17.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_17.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_18.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_18.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_18.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_18.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_2.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_2.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_2.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_2.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_3.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_3.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_3.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_3.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_4.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_4.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_4.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_4.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_5.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_5.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_5.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_5.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_6.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_6.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_6.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_6.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_7.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_7.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_7.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_7.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_8.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_8.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_8.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_8.result diff --git a/mysql-test/suite/tokudb.add_index/r/add_index_9.result b/storage/tokudb/mysql-test/tokudb_add_index/r/add_index_9.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/add_index_9.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/add_index_9.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_22516.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_22516.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_22516.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_22516.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23691.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23691.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23691.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23691.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23692.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23692.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23692.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23692.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_1.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_1.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_1.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_1.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_2.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_2.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_2.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_2.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_A.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_A.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_A.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_A.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_B.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_B.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_B.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_B.result diff --git a/mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_C.result b/storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_C.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/falcon_bug_23818_C.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/falcon_bug_23818_C.result diff --git a/mysql-test/suite/tokudb.add_index/r/hot_create_unique_index.result b/storage/tokudb/mysql-test/tokudb_add_index/r/hot_create_unique_index.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/hot_create_unique_index.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/hot_create_unique_index.result diff --git a/mysql-test/suite/tokudb.add_index/r/tokudb_bug_1152.result b/storage/tokudb/mysql-test/tokudb_add_index/r/tokudb_bug_1152.result similarity index 100% rename from mysql-test/suite/tokudb.add_index/r/tokudb_bug_1152.result rename to storage/tokudb/mysql-test/tokudb_add_index/r/tokudb_bug_1152.result diff --git a/mysql-test/suite/tokudb.add_index/t/1522.test b/storage/tokudb/mysql-test/tokudb_add_index/t/1522.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/1522.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/1522.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_1.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_1.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_1.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_1.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_10.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_10.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_10.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_10.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_11.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_11.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_11.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_11.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_12.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_12.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_12.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_12.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_13.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_13.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_13.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_13.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_14.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_14.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_14.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_14.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_15.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_15.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_15.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_15.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_16.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_16.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_16.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_16.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_17.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_17.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_17.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_17.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_18.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_18.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_18.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_18.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_2.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_2.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_2.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_2.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_3.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_3.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_3.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_3.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_4.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_4.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_4.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_4.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_5.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_5.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_5.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_5.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_6.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_6.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_6.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_6.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_7.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_7.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_7.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_7.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_8.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_8.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_8.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_8.test diff --git a/mysql-test/suite/tokudb.add_index/t/add_index_9.test b/storage/tokudb/mysql-test/tokudb_add_index/t/add_index_9.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/add_index_9.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/add_index_9.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_22516.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_22516.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_22516.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_22516.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23691.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23691.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23691.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23691.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23692.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23692.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23692.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23692.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_1.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_1.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_1.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_1.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_2.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_2.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_2.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_2.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_A.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_A.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_A.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_A.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_B.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_B.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_B.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_B.test diff --git a/mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_C.test b/storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_C.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/falcon_bug_23818_C.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/falcon_bug_23818_C.test diff --git a/mysql-test/suite/tokudb.add_index/t/hot_create_unique_index.test b/storage/tokudb/mysql-test/tokudb_add_index/t/hot_create_unique_index.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/hot_create_unique_index.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/hot_create_unique_index.test diff --git a/mysql-test/suite/tokudb.alter_table/t/suite.opt b/storage/tokudb/mysql-test/tokudb_add_index/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_add_index/t/suite.opt diff --git a/mysql-test/suite/tokudb.add_index/t/tokudb_bug_1152.test b/storage/tokudb/mysql-test/tokudb_add_index/t/tokudb_bug_1152.test similarity index 100% rename from mysql-test/suite/tokudb.add_index/t/tokudb_bug_1152.test rename to storage/tokudb/mysql-test/tokudb_add_index/t/tokudb_bug_1152.test diff --git a/mysql-test/suite/tokudb.alter_table/r/4630.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/4630.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/4630.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/4630.result diff --git a/mysql-test/suite/tokudb.alter_table/r/5260.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/5260.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/5260.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/5260.result diff --git a/mysql-test/suite/tokudb.alter_table/r/ai_aui.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_aui.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/ai_aui.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/ai_aui.result diff --git a/mysql-test/suite/tokudb.alter_table/r/ai_di.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_di.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/ai_di.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/ai_di.result diff --git a/mysql-test/suite/tokudb.alter_table/r/ai_part.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/ai_part.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/ai_part.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/ai_part.result diff --git a/mysql-test/suite/tokudb.alter_table/r/alter_column_default.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/alter_column_default.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/alter_column_default.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/alter_column_default.result diff --git a/mysql-test/suite/tokudb.alter_table/r/auto_inc.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/auto_inc.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/auto_inc.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/auto_inc.result diff --git a/mysql-test/suite/tokudb.alter_table/r/di_dui.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/di_dui.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/di_dui.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/di_dui.result diff --git a/mysql-test/suite/tokudb.alter_table/r/drop_add_pk_104.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/drop_add_pk_104.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/drop_add_pk_104.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/drop_add_pk_104.result diff --git a/mysql-test/suite/tokudb.alter_table/r/drop_add_pk_part_104.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/drop_add_pk_part_104.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/drop_add_pk_part_104.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/drop_add_pk_part_104.result diff --git a/mysql-test/suite/tokudb.alter_table/r/drop_pk_with_prefix.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/drop_pk_with_prefix.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/drop_pk_with_prefix.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/drop_pk_with_prefix.result diff --git a/mysql-test/suite/tokudb.alter_table/r/frm_discover.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/frm_discover.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover.result diff --git a/mysql-test/suite/tokudb.alter_table/r/frm_discover_partition.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover_partition.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/frm_discover_partition.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/frm_discover_partition.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_add2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_add2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_add2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_add2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_add3.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_add3.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_add3.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_add3.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_blob_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_blob_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_blob_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_blob_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_blob_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_blob_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_blob_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_blob_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_fixed_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_fixed_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_fixed_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_fixed_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_fixed_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_fixed_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_fixed_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_fixed_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_var_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_var_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_var_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_var_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_all_var_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_var_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_all_var_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_all_var_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_and_rename_table.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_and_rename_table.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_and_rename_table.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_and_rename_table.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_clustering.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_clustering.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_clustering.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_clustering.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_clustering2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_clustering2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_clustering2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_clustering2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_diff_num_offset_bytes.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_diff_num_offset_bytes.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_diff_num_offset_bytes.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_diff_num_offset_bytes.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_drop_char0_t6.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_drop_char0_t6.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_drop_char0_t6.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_drop_char0_t6.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_fixedblob_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedblob_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_fixedblob_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedblob_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_fixedblob_add2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedblob_add2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_fixedblob_add2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedblob_add2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_fixedblob_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedblob_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_fixedblob_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedblob_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_fixedvar_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedvar_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_fixedvar_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedvar_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_fixedvar_add2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedvar_add2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_fixedvar_add2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedvar_add2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_fixedvar_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedvar_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_fixedvar_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_fixedvar_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_indexing_mix.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_indexing_mix.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_indexing_mix.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_indexing_mix.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_null_bits.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_null_bits.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_null_bits.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_null_bits.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_part.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_part.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_part.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_part.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_pk.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_pk.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_pk.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_pk.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_pk2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_pk2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_pk2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_pk2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_template.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_template.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_template.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_template.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_tmp_tables.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_tmp_tables.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_tmp_tables.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_tmp_tables.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_tmp_tables_56.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_tmp_tables_56.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_tmp_tables_56.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_tmp_tables_56.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_varblob_add.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_varblob_add.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_varblob_add.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_varblob_add.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_varblob_add2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_varblob_add2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_varblob_add2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_varblob_add2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_varblob_drop.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_varblob_drop.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_varblob_drop.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_varblob_drop.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_with_dels.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_with_dels.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_with_dels.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_with_dels.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_with_lock_sps.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_with_lock_sps.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_with_lock_sps.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_with_lock_sps.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcad_with_locks.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_with_locks.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcad_with_locks.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcad_with_locks.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr3.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr3.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr3.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr3.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr_binary1.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_binary1.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr_binary1.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_binary1.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr_blob.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_blob.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr_blob.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_blob.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr_char1.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_char1.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr_char1.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_char1.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr_enum.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_enum.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr_enum.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_enum.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr_text.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_text.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr_text.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_text.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hcr_time.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_time.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hcr_time.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hcr_time.result diff --git a/mysql-test/suite/tokudb.alter_table/r/hot_row_format_alter.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/hot_row_format_alter.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/hot_row_format_alter.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/hot_row_format_alter.result diff --git a/mysql-test/suite/tokudb.alter_table/r/mod_enum.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/mod_enum.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/mod_enum.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/mod_enum.result diff --git a/mysql-test/suite/tokudb.alter_table/r/null_bytes_add_key.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_add_key.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/null_bytes_add_key.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_add_key.result diff --git a/mysql-test/suite/tokudb.alter_table/r/null_bytes_col_rename.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_col_rename.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/null_bytes_col_rename.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_col_rename.result diff --git a/mysql-test/suite/tokudb.alter_table/r/null_bytes_drop_default.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_drop_default.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/null_bytes_drop_default.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_drop_default.result diff --git a/mysql-test/suite/tokudb.alter_table/r/null_bytes_drop_key.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_drop_key.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/null_bytes_drop_key.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/null_bytes_drop_key.result diff --git a/mysql-test/suite/tokudb.alter_table/r/other_alter.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/other_alter.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter.result diff --git a/mysql-test/suite/tokudb.alter_table/r/other_alter2.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter2.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/other_alter2.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/other_alter2.result diff --git a/mysql-test/suite/tokudb.alter_table/r/rename_column_cold_104.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/rename_column_cold_104.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/rename_column_cold_104.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/rename_column_cold_104.result diff --git a/mysql-test/suite/tokudb.alter_table/r/rename_column_cold_part_104.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/rename_column_cold_part_104.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/rename_column_cold_part_104.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/rename_column_cold_part_104.result diff --git a/mysql-test/suite/tokudb.alter_table/r/row_format_alter.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/row_format_alter.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/row_format_alter.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/row_format_alter.result diff --git a/mysql-test/suite/tokudb.alter_table/r/test_field_same_detection.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/test_field_same_detection.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/test_field_same_detection.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/test_field_same_detection.result diff --git a/mysql-test/suite/tokudb.alter_table/r/virtual_columns.result b/storage/tokudb/mysql-test/tokudb_alter_table/r/virtual_columns.result similarity index 100% rename from mysql-test/suite/tokudb.alter_table/r/virtual_columns.result rename to storage/tokudb/mysql-test/tokudb_alter_table/r/virtual_columns.result diff --git a/mysql-test/suite/tokudb.alter_table/t/4630.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/4630.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/4630.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/4630.test diff --git a/mysql-test/suite/tokudb.alter_table/t/5260.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/5260.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/5260.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/5260.test diff --git a/mysql-test/suite/tokudb.alter_table/t/ai_aui.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/ai_aui.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/ai_aui.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/ai_aui.test diff --git a/mysql-test/suite/tokudb.alter_table/t/ai_di.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/ai_di.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/ai_di.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/ai_di.test diff --git a/mysql-test/suite/tokudb.alter_table/t/ai_part.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/ai_part.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/ai_part.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/ai_part.test diff --git a/mysql-test/suite/tokudb.alter_table/t/alter_column_default.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/alter_column_default.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/alter_column_default.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/alter_column_default.test diff --git a/mysql-test/suite/tokudb.alter_table/t/auto_inc.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/auto_inc.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/auto_inc.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/auto_inc.test diff --git a/mysql-test/suite/tokudb.alter_table/t/di_dui.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/di_dui.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/di_dui.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/di_dui.test diff --git a/mysql-test/suite/tokudb.alter_table/t/disabled.def b/storage/tokudb/mysql-test/tokudb_alter_table/t/disabled.def similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/disabled.def rename to storage/tokudb/mysql-test/tokudb_alter_table/t/disabled.def diff --git a/mysql-test/suite/tokudb.alter_table/t/drop_add_pk_104.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/drop_add_pk_104.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/drop_add_pk_104.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/drop_add_pk_104.test diff --git a/mysql-test/suite/tokudb.alter_table/t/drop_add_pk_part_104.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/drop_add_pk_part_104.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/drop_add_pk_part_104.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/drop_add_pk_part_104.test diff --git a/mysql-test/suite/tokudb.alter_table/t/drop_pk_with_prefix.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/drop_pk_with_prefix.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/drop_pk_with_prefix.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/drop_pk_with_prefix.test diff --git a/mysql-test/suite/tokudb.alter_table/t/frm_discover.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/frm_discover.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/frm_discover.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/frm_discover.test diff --git a/mysql-test/suite/tokudb.alter_table/t/frm_discover_partition.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/frm_discover_partition.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/frm_discover_partition.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/frm_discover_partition.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_add2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_add2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_add2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_add2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_add3.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_add3.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_add3.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_add3.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_blob_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_blob_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_blob_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_blob_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_blob_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_blob_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_blob_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_blob_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_fixed_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_fixed_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_fixed_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_fixed_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_fixed_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_fixed_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_fixed_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_fixed_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_var_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_var_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_var_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_var_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_all_var_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_var_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_all_var_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_all_var_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_and_rename_table.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_and_rename_table.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_and_rename_table.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_and_rename_table.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_clustering.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_clustering.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_clustering.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_clustering.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_clustering2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_clustering2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_clustering2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_clustering2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_diff_num_offset_bytes.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_diff_num_offset_bytes.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_diff_num_offset_bytes.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_diff_num_offset_bytes.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_drop_char0_t6.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_drop_char0_t6.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_drop_char0_t6.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_drop_char0_t6.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_fixedblob_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedblob_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_fixedblob_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedblob_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_fixedblob_add2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedblob_add2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_fixedblob_add2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedblob_add2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_fixedblob_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedblob_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_fixedblob_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedblob_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_fixedvar_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedvar_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_fixedvar_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedvar_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_fixedvar_add2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedvar_add2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_fixedvar_add2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedvar_add2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_fixedvar_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedvar_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_fixedvar_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_fixedvar_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_indexing_mix.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_indexing_mix.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_indexing_mix.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_indexing_mix.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_null_bits.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_null_bits.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_null_bits.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_null_bits.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_part.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_part.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_part.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_part.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_pk.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_pk.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_pk.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_pk.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_pk2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_pk2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_pk2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_pk2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_template.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_template.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_template.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_template.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_tmp_tables.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_tmp_tables.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_tmp_tables.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_tmp_tables.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_tmp_tables_56.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_tmp_tables_56.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_tmp_tables_56.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_tmp_tables_56.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_varblob_add.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_varblob_add.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_varblob_add.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_varblob_add.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_varblob_add2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_varblob_add2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_varblob_add2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_varblob_add2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_varblob_drop.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_varblob_drop.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_varblob_drop.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_varblob_drop.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_with_dels.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_with_dels.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_with_dels.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_with_dels.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_with_lock_sps.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_with_lock_sps.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_with_lock_sps.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_with_lock_sps.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcad_with_locks.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_with_locks.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcad_with_locks.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcad_with_locks.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr3.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr3.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr3.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr3.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr_binary1.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_binary1.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr_binary1.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_binary1.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr_blob.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_blob.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr_blob.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_blob.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr_char1.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_char1.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr_char1.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_char1.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr_enum.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_enum.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr_enum.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_enum.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr_text.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_text.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr_text.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_text.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hcr_time.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_time.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hcr_time.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hcr_time.test diff --git a/mysql-test/suite/tokudb.alter_table/t/hot_row_format_alter.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/hot_row_format_alter.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/hot_row_format_alter.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/hot_row_format_alter.test diff --git a/mysql-test/suite/tokudb.alter_table/t/mod_enum.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/mod_enum.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/mod_enum.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/mod_enum.test diff --git a/mysql-test/suite/tokudb.alter_table/t/null_bytes_add_key.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_add_key.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/null_bytes_add_key.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_add_key.test diff --git a/mysql-test/suite/tokudb.alter_table/t/null_bytes_col_rename.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_col_rename.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/null_bytes_col_rename.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_col_rename.test diff --git a/mysql-test/suite/tokudb.alter_table/t/null_bytes_drop_default.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_drop_default.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/null_bytes_drop_default.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_drop_default.test diff --git a/mysql-test/suite/tokudb.alter_table/t/null_bytes_drop_key.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_drop_key.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/null_bytes_drop_key.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/null_bytes_drop_key.test diff --git a/mysql-test/suite/tokudb.alter_table/t/other_alter.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/other_alter.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/other_alter.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/other_alter.test diff --git a/mysql-test/suite/tokudb.alter_table/t/other_alter2.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/other_alter2.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/other_alter2.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/other_alter2.test diff --git a/mysql-test/suite/tokudb.alter_table/t/rename_column_cold_104.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/rename_column_cold_104.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/rename_column_cold_104.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/rename_column_cold_104.test diff --git a/mysql-test/suite/tokudb.alter_table/t/rename_column_cold_part_104.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/rename_column_cold_part_104.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/rename_column_cold_part_104.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/rename_column_cold_part_104.test diff --git a/mysql-test/suite/tokudb.alter_table/t/row_format_alter.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/row_format_alter.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/row_format_alter.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/row_format_alter.test diff --git a/mysql-test/suite/tokudb.bugs/t/suite.opt b/storage/tokudb/mysql-test/tokudb_alter_table/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_alter_table/t/suite.opt diff --git a/mysql-test/suite/tokudb.alter_table/t/test_field_same_detection.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/test_field_same_detection.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/test_field_same_detection.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/test_field_same_detection.test diff --git a/mysql-test/suite/tokudb.alter_table/t/virtual_columns.test b/storage/tokudb/mysql-test/tokudb_alter_table/t/virtual_columns.test similarity index 100% rename from mysql-test/suite/tokudb.alter_table/t/virtual_columns.test rename to storage/tokudb/mysql-test/tokudb_alter_table/t/virtual_columns.test diff --git a/mysql-test/suite/tokudb.backup/r/tokudb_backup_exclude.result b/storage/tokudb/mysql-test/tokudb_backup/r/tokudb_backup_exclude.result similarity index 100% rename from mysql-test/suite/tokudb.backup/r/tokudb_backup_exclude.result rename to storage/tokudb/mysql-test/tokudb_backup/r/tokudb_backup_exclude.result diff --git a/mysql-test/suite/tokudb.backup/r/tokudb_backup_set_last_error.result b/storage/tokudb/mysql-test/tokudb_backup/r/tokudb_backup_set_last_error.result similarity index 100% rename from mysql-test/suite/tokudb.backup/r/tokudb_backup_set_last_error.result rename to storage/tokudb/mysql-test/tokudb_backup/r/tokudb_backup_set_last_error.result diff --git a/mysql-test/suite/tokudb.backup/t/suite.opt b/storage/tokudb/mysql-test/tokudb_backup/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.backup/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_backup/t/suite.opt diff --git a/mysql-test/suite/tokudb.backup/t/tokudb_backup_exclude.test b/storage/tokudb/mysql-test/tokudb_backup/t/tokudb_backup_exclude.test similarity index 100% rename from mysql-test/suite/tokudb.backup/t/tokudb_backup_exclude.test rename to storage/tokudb/mysql-test/tokudb_backup/t/tokudb_backup_exclude.test diff --git a/mysql-test/suite/tokudb.backup/t/tokudb_backup_set_last_error.test b/storage/tokudb/mysql-test/tokudb_backup/t/tokudb_backup_set_last_error.test similarity index 100% rename from mysql-test/suite/tokudb.backup/t/tokudb_backup_set_last_error.test rename to storage/tokudb/mysql-test/tokudb_backup/t/tokudb_backup_set_last_error.test diff --git a/mysql-test/suite/tokudb.bugs/r/1648.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1648.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1648.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1648.result diff --git a/mysql-test/suite/tokudb.bugs/r/1684.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1684.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1684.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1684.result diff --git a/mysql-test/suite/tokudb.bugs/r/1711.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1711.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1711.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1711.result diff --git a/mysql-test/suite/tokudb.bugs/r/1795.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1795.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1795.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1795.result diff --git a/mysql-test/suite/tokudb.bugs/r/1833.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1833.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1833.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1833.result diff --git a/mysql-test/suite/tokudb.bugs/r/1853.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1853.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1853.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1853.result diff --git a/mysql-test/suite/tokudb.bugs/r/1872.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1872.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1872.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1872.result diff --git a/mysql-test/suite/tokudb.bugs/r/1883.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1883.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1883.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1883.result diff --git a/mysql-test/suite/tokudb.bugs/r/1913.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1913.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1913.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1913.result diff --git a/mysql-test/suite/tokudb.bugs/r/1938.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1938.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1938.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1938.result diff --git a/mysql-test/suite/tokudb.bugs/r/1949.result b/storage/tokudb/mysql-test/tokudb_bugs/r/1949.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/1949.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/1949.result diff --git a/mysql-test/suite/tokudb.bugs/r/2043.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2043.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2043.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2043.result diff --git a/mysql-test/suite/tokudb.bugs/r/2219.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2219.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2219.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2219.result diff --git a/mysql-test/suite/tokudb.bugs/r/2262.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2262.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2262.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2262.result diff --git a/mysql-test/suite/tokudb.bugs/r/2383.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2383.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2383.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2383.result diff --git a/mysql-test/suite/tokudb.bugs/r/2458.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2458.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2458.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2458.result diff --git a/mysql-test/suite/tokudb.bugs/r/2494-read-committed.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2494-read-committed.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2494-read-committed.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2494-read-committed.result diff --git a/mysql-test/suite/tokudb.bugs/r/2548.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2548.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2548.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2548.result diff --git a/mysql-test/suite/tokudb.bugs/r/2641.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2641.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2641.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2641.result diff --git a/mysql-test/suite/tokudb.bugs/r/2952.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2952.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2952.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2952.result diff --git a/mysql-test/suite/tokudb.bugs/r/2970.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2970.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2970.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2970.result diff --git a/mysql-test/suite/tokudb.bugs/r/2970i.result b/storage/tokudb/mysql-test/tokudb_bugs/r/2970i.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/2970i.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/2970i.result diff --git a/mysql-test/suite/tokudb.bugs/r/3014.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3014.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3014.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3014.result diff --git a/mysql-test/suite/tokudb.bugs/r/3015.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3015.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3015.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3015.result diff --git a/mysql-test/suite/tokudb.bugs/r/3083.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3083.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3083.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3083.result diff --git a/mysql-test/suite/tokudb.bugs/r/3441.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3441.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3441.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3441.result diff --git a/mysql-test/suite/tokudb.bugs/r/3478.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3478.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3478.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3478.result diff --git a/mysql-test/suite/tokudb.bugs/r/3486.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3486.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3486.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3486.result diff --git a/mysql-test/suite/tokudb.bugs/r/3518.result b/storage/tokudb/mysql-test/tokudb_bugs/r/3518.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/3518.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/3518.result diff --git a/mysql-test/suite/tokudb.bugs/r/4175.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4175.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4175.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4175.result diff --git a/mysql-test/suite/tokudb.bugs/r/4260.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4260.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4260.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4260.result diff --git a/mysql-test/suite/tokudb.bugs/r/4472.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4472.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4472.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4472.result diff --git a/mysql-test/suite/tokudb.bugs/r/4618.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4618.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4618.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4618.result diff --git a/mysql-test/suite/tokudb.bugs/r/4633.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4633.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4633.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4633.result diff --git a/mysql-test/suite/tokudb.bugs/r/4648.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4648.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4648.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4648.result diff --git a/mysql-test/suite/tokudb.bugs/r/4656.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4656.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4656.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4656.result diff --git a/mysql-test/suite/tokudb.bugs/r/4656_2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4656_2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4656_2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4656_2.result diff --git a/mysql-test/suite/tokudb.bugs/r/4675.result b/storage/tokudb/mysql-test/tokudb_bugs/r/4675.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/4675.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/4675.result diff --git a/mysql-test/suite/tokudb.bugs/r/5003.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5003.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5003.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5003.result diff --git a/mysql-test/suite/tokudb.bugs/r/5089.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5089.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5089.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5089.result diff --git a/mysql-test/suite/tokudb.bugs/r/5469.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5469.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5469.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5469.result diff --git a/mysql-test/suite/tokudb.bugs/r/5554.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5554.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5554.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5554.result diff --git a/mysql-test/suite/tokudb.bugs/r/5585.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5585.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5585.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5585.result diff --git a/mysql-test/suite/tokudb.bugs/r/5695.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5695.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5695.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5695.result diff --git a/mysql-test/suite/tokudb.bugs/r/5733_innodb.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5733_innodb.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5733_innodb.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5733_innodb.result diff --git a/mysql-test/suite/tokudb.bugs/r/5733_tokudb.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5733_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5733_tokudb.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5733_tokudb.result diff --git a/mysql-test/suite/tokudb.bugs/r/5951.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5951.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5951.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5951.result diff --git a/mysql-test/suite/tokudb.bugs/r/5974-2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5974-2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5974-2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5974-2.result diff --git a/mysql-test/suite/tokudb.bugs/r/5974.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5974.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/5974.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/5974.result diff --git a/mysql-test/suite/tokudb.bugs/r/6053.result b/storage/tokudb/mysql-test/tokudb_bugs/r/6053.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/6053.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/6053.result diff --git a/mysql-test/suite/tokudb.bugs/r/6684.result b/storage/tokudb/mysql-test/tokudb_bugs/r/6684.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/6684.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/6684.result diff --git a/mysql-test/suite/tokudb.bugs/r/889.result b/storage/tokudb/mysql-test/tokudb_bugs/r/889.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/889.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/889.result diff --git a/mysql-test/suite/tokudb.bugs/r/895.result b/storage/tokudb/mysql-test/tokudb_bugs/r/895.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/895.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/895.result diff --git a/mysql-test/suite/tokudb.bugs/r/94.result b/storage/tokudb/mysql-test/tokudb_bugs/r/94.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/94.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/94.result diff --git a/mysql-test/suite/tokudb.bugs/r/alter_external_lock_assert.result b/storage/tokudb/mysql-test/tokudb_bugs/r/alter_external_lock_assert.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/alter_external_lock_assert.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/alter_external_lock_assert.result diff --git a/mysql-test/suite/tokudb.bugs/r/alter_part_tokudb_bug_155.result b/storage/tokudb/mysql-test/tokudb_bugs/r/alter_part_tokudb_bug_155.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/alter_part_tokudb_bug_155.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/alter_part_tokudb_bug_155.result diff --git a/mysql-test/suite/tokudb.bugs/r/alter_table_copy_table.result b/storage/tokudb/mysql-test/tokudb_bugs/r/alter_table_copy_table.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/alter_table_copy_table.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/alter_table_copy_table.result diff --git a/mysql-test/suite/tokudb.bugs/r/bulk_fetch.result b/storage/tokudb/mysql-test/tokudb_bugs/r/bulk_fetch.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/bulk_fetch.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/bulk_fetch.result diff --git a/mysql-test/suite/tokudb.bugs/r/checkpoint_lock.result b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/checkpoint_lock.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock.result diff --git a/mysql-test/suite/tokudb.bugs/r/checkpoint_lock_2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/checkpoint_lock_2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_2.result diff --git a/mysql-test/suite/tokudb.bugs/r/checkpoint_lock_3.result b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_3.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/checkpoint_lock_3.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_3.result diff --git a/mysql-test/suite/tokudb.bugs/r/commit_index_end_1.result b/storage/tokudb/mysql-test/tokudb_bugs/r/commit_index_end_1.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/commit_index_end_1.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/commit_index_end_1.result diff --git a/mysql-test/suite/tokudb.bugs/r/commit_index_end_2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/commit_index_end_2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/commit_index_end_2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/commit_index_end_2.result diff --git a/mysql-test/suite/tokudb.bugs/r/db397_delete_trigger.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_delete_trigger.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db397_delete_trigger.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db397_delete_trigger.result diff --git a/mysql-test/suite/tokudb.bugs/r/db397_insert_trigger.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_insert_trigger.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db397_insert_trigger.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db397_insert_trigger.result diff --git a/mysql-test/suite/tokudb.bugs/r/db397_update_trigger.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_update_trigger.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db397_update_trigger.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db397_update_trigger.result diff --git a/mysql-test/suite/tokudb.bugs/r/db739_insert.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db739_insert.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db739_insert.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db739_insert.result diff --git a/mysql-test/suite/tokudb.bugs/r/db739_replace.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db739_replace.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db739_replace.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db739_replace.result diff --git a/mysql-test/suite/tokudb.bugs/r/db739_upsert.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db739_upsert.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db739_upsert.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db739_upsert.result diff --git a/mysql-test/suite/tokudb.bugs/r/db743.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db743.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db743.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db743.result diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db756_card_part_hash.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash.result diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1.result diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1_pick.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_1_pick.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2.result diff --git a/mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2_pick.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2_pick.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db756_card_part_hash_2_pick.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2_pick.result diff --git a/mysql-test/suite/tokudb.bugs/r/db757_part_alter_analyze.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db757_part_alter_analyze.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result diff --git a/mysql-test/suite/tokudb.bugs/r/db762.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db762.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db762.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db762.result diff --git a/mysql-test/suite/tokudb.bugs/r/db766.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db766.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db766.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db766.result diff --git a/mysql-test/suite/tokudb.bugs/r/db768.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db768.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db768.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db768.result diff --git a/mysql-test/suite/tokudb.bugs/r/db771.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db771.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db771.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db771.result diff --git a/mysql-test/suite/tokudb.bugs/r/db788-optimize-index-name.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db788-optimize-index-name.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db788-optimize-index-name.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db788-optimize-index-name.result diff --git a/mysql-test/suite/tokudb.bugs/r/db801.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db801.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db801.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db801.result diff --git a/mysql-test/suite/tokudb.bugs/r/db805.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db805.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db805.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db805.result diff --git a/mysql-test/suite/tokudb.bugs/r/db806.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db806.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db806.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db806.result diff --git a/mysql-test/suite/tokudb.bugs/r/db811.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db811.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db811.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db811.result diff --git a/mysql-test/suite/tokudb.bugs/r/db811s.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db811s.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db811s.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db811s.result diff --git a/mysql-test/suite/tokudb.bugs/r/db817.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db817.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db817.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db817.result diff --git a/mysql-test/suite/tokudb.bugs/r/db823.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db823.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/db823.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/db823.result diff --git a/mysql-test/suite/tokudb.bugs/r/dict_leak_3518.result b/storage/tokudb/mysql-test/tokudb_bugs/r/dict_leak_3518.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/dict_leak_3518.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/dict_leak_3518.result diff --git a/mysql-test/suite/tokudb.bugs/r/expand_tinytext_text.result b/storage/tokudb/mysql-test/tokudb_bugs/r/expand_tinytext_text.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/expand_tinytext_text.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/expand_tinytext_text.result diff --git a/mysql-test/suite/tokudb.bugs/r/fileops-2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/fileops-2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/fileops-2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/fileops-2.result diff --git a/mysql-test/suite/tokudb.bugs/r/fileops-3.result b/storage/tokudb/mysql-test/tokudb_bugs/r/fileops-3.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/fileops-3.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/fileops-3.result diff --git a/mysql-test/suite/tokudb.bugs/r/fileops-4.result b/storage/tokudb/mysql-test/tokudb_bugs/r/fileops-4.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/fileops-4.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/fileops-4.result diff --git a/mysql-test/suite/tokudb.bugs/r/fileops.result b/storage/tokudb/mysql-test/tokudb_bugs/r/fileops.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/fileops.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/fileops.result diff --git a/mysql-test/suite/tokudb.bugs/r/frm_store.result b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/frm_store.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/frm_store.result diff --git a/mysql-test/suite/tokudb.bugs/r/frm_store2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/frm_store2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/frm_store2.result diff --git a/mysql-test/suite/tokudb.bugs/r/frm_store3.result b/storage/tokudb/mysql-test/tokudb_bugs/r/frm_store3.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/frm_store3.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/frm_store3.result diff --git a/mysql-test/suite/tokudb.bugs/r/ft-index-40.result b/storage/tokudb/mysql-test/tokudb_bugs/r/ft-index-40.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/ft-index-40.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/ft-index-40.result diff --git a/mysql-test/suite/tokudb.bugs/r/index_read.result b/storage/tokudb/mysql-test/tokudb_bugs/r/index_read.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/index_read.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/index_read.result diff --git a/mysql-test/suite/tokudb.bugs/r/leak172.result b/storage/tokudb/mysql-test/tokudb_bugs/r/leak172.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/leak172.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/leak172.result diff --git a/mysql-test/suite/tokudb.bugs/r/lock_uniq_key_empty.result b/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/lock_uniq_key_empty.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_empty.result diff --git a/mysql-test/suite/tokudb.bugs/r/lock_uniq_key_left.result b/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_left.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/lock_uniq_key_left.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_left.result diff --git a/mysql-test/suite/tokudb.bugs/r/lock_uniq_key_middle.result b/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_middle.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/lock_uniq_key_middle.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_middle.result diff --git a/mysql-test/suite/tokudb.bugs/r/lock_uniq_key_right.result b/storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_right.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/lock_uniq_key_right.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/lock_uniq_key_right.result diff --git a/mysql-test/suite/tokudb.bugs/r/mdev4533.result b/storage/tokudb/mysql-test/tokudb_bugs/r/mdev4533.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/mdev4533.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/mdev4533.result diff --git a/mysql-test/suite/tokudb.bugs/r/mdev5932.result b/storage/tokudb/mysql-test/tokudb_bugs/r/mdev5932.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/mdev5932.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/mdev5932.result diff --git a/mysql-test/suite/tokudb.bugs/r/optimize_temp_table_tokudb.result b/storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/optimize_temp_table_tokudb.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/optimize_temp_table_tokudb.result diff --git a/mysql-test/suite/tokudb.bugs/r/rpl_mixed_replace_into.result b/storage/tokudb/mysql-test/tokudb_bugs/r/rpl_mixed_replace_into.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/rpl_mixed_replace_into.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/rpl_mixed_replace_into.result diff --git a/mysql-test/suite/tokudb.bugs/r/rpl_row_replace_into.result b/storage/tokudb/mysql-test/tokudb_bugs/r/rpl_row_replace_into.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/rpl_row_replace_into.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/rpl_row_replace_into.result diff --git a/mysql-test/suite/tokudb.bugs/r/rpl_stmt_replace_into.result b/storage/tokudb/mysql-test/tokudb_bugs/r/rpl_stmt_replace_into.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/rpl_stmt_replace_into.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/rpl_stmt_replace_into.result diff --git a/mysql-test/suite/tokudb.bugs/r/simple_icp.result b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/simple_icp.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result diff --git a/mysql-test/suite/tokudb.bugs/r/subselect_index_next_same_bug_157.result b/storage/tokudb/mysql-test/tokudb_bugs/r/subselect_index_next_same_bug_157.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/subselect_index_next_same_bug_157.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/subselect_index_next_same_bug_157.result diff --git a/mysql-test/suite/tokudb.bugs/r/tokudb718.result b/storage/tokudb/mysql-test/tokudb_bugs/r/tokudb718.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/tokudb718.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/tokudb718.result diff --git a/mysql-test/suite/tokudb.bugs/r/tokudb_drop_part_table_668.result b/storage/tokudb/mysql-test/tokudb_bugs/r/tokudb_drop_part_table_668.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/tokudb_drop_part_table_668.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/tokudb_drop_part_table_668.result diff --git a/mysql-test/suite/tokudb.bugs/r/tokudb_drop_simple_table_668.result b/storage/tokudb/mysql-test/tokudb_bugs/r/tokudb_drop_simple_table_668.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/tokudb_drop_simple_table_668.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/tokudb_drop_simple_table_668.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa-1.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa-1.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa-1.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa-1.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa-2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa-2.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa-2.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa-2.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa-3.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa-3.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa-3.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa-3.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa-4.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa-4.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa-4.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa-4.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa-5.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa-5.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa-5.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa-5.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa-6.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa-6.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa-6.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa-6.result diff --git a/mysql-test/suite/tokudb.bugs/r/xa.result b/storage/tokudb/mysql-test/tokudb_bugs/r/xa.result similarity index 100% rename from mysql-test/suite/tokudb.bugs/r/xa.result rename to storage/tokudb/mysql-test/tokudb_bugs/r/xa.result diff --git a/mysql-test/suite/tokudb.bugs/t/1648.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1648.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1648.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1648.test diff --git a/mysql-test/suite/tokudb.bugs/t/1684.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1684.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1684.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1684.test diff --git a/mysql-test/suite/tokudb.bugs/t/1711.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1711.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1711.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1711.test diff --git a/mysql-test/suite/tokudb.bugs/t/1795.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1795.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1795.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1795.test diff --git a/mysql-test/suite/tokudb.bugs/t/1833.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1833.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1833.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1833.test diff --git a/mysql-test/suite/tokudb.bugs/t/1853.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1853.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1853.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1853.test diff --git a/mysql-test/suite/tokudb.bugs/t/1872.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1872.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1872.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1872.test diff --git a/mysql-test/suite/tokudb.bugs/t/1883.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1883.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1883.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1883.test diff --git a/mysql-test/suite/tokudb.bugs/t/1913.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1913.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1913.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1913.test diff --git a/mysql-test/suite/tokudb.bugs/t/1938.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1938.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1938.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1938.test diff --git a/mysql-test/suite/tokudb.bugs/t/1949.test b/storage/tokudb/mysql-test/tokudb_bugs/t/1949.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/1949.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/1949.test diff --git a/mysql-test/suite/tokudb.bugs/t/2043.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2043.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2043.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2043.test diff --git a/mysql-test/suite/tokudb.bugs/t/2219.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2219.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2219.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2219.test diff --git a/mysql-test/suite/tokudb.bugs/t/2262.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2262.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2262.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2262.test diff --git a/mysql-test/suite/tokudb.bugs/t/2383.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2383.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2383.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2383.test diff --git a/mysql-test/suite/tokudb.bugs/t/2458.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2458.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2458.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2458.test diff --git a/mysql-test/suite/tokudb.bugs/t/2494-read-committed.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2494-read-committed.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2494-read-committed.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2494-read-committed.test diff --git a/mysql-test/suite/tokudb.bugs/t/2548.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2548.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2548.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2548.test diff --git a/mysql-test/suite/tokudb.bugs/t/2641.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2641.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2641.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2641.test diff --git a/mysql-test/suite/tokudb.bugs/t/2952.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2952.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2952.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2952.test diff --git a/mysql-test/suite/tokudb.bugs/t/2970.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2970.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2970.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2970.test diff --git a/mysql-test/suite/tokudb.bugs/t/2970i.test b/storage/tokudb/mysql-test/tokudb_bugs/t/2970i.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/2970i.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/2970i.test diff --git a/mysql-test/suite/tokudb.bugs/t/3014.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3014.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3014.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3014.test diff --git a/mysql-test/suite/tokudb.bugs/t/3015.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3015.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3015.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3015.test diff --git a/mysql-test/suite/tokudb.bugs/t/3083.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3083.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3083.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3083.test diff --git a/mysql-test/suite/tokudb.bugs/t/3441.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3441.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3441.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3441.test diff --git a/mysql-test/suite/tokudb.bugs/t/3478.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3478.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3478.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3478.test diff --git a/mysql-test/suite/tokudb.bugs/t/3486.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3486.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3486.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3486.test diff --git a/mysql-test/suite/tokudb.bugs/t/3518.test b/storage/tokudb/mysql-test/tokudb_bugs/t/3518.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/3518.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/3518.test diff --git a/mysql-test/suite/tokudb.bugs/t/4175.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4175.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4175.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4175.test diff --git a/mysql-test/suite/tokudb.bugs/t/4260.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4260.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4260.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4260.test diff --git a/mysql-test/suite/tokudb.bugs/t/4472.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4472.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4472.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4472.test diff --git a/mysql-test/suite/tokudb.bugs/t/4618.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4618.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4618.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4618.test diff --git a/mysql-test/suite/tokudb.bugs/t/4633.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4633.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4633.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4633.test diff --git a/mysql-test/suite/tokudb.bugs/t/4648.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4648.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4648.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4648.test diff --git a/mysql-test/suite/tokudb.bugs/t/4656.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4656.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4656.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4656.test diff --git a/mysql-test/suite/tokudb.bugs/t/4656_2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4656_2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4656_2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4656_2.test diff --git a/mysql-test/suite/tokudb.bugs/t/4675.test b/storage/tokudb/mysql-test/tokudb_bugs/t/4675.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/4675.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/4675.test diff --git a/mysql-test/suite/tokudb.bugs/t/5003.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5003.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5003.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5003.test diff --git a/mysql-test/suite/tokudb.bugs/t/5089.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5089.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5089.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5089.test diff --git a/mysql-test/suite/tokudb.bugs/t/5469.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5469.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5469.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5469.test diff --git a/mysql-test/suite/tokudb.bugs/t/5554.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5554.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5554.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5554.test diff --git a/mysql-test/suite/tokudb.bugs/t/5585-master.opt b/storage/tokudb/mysql-test/tokudb_bugs/t/5585-master.opt similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5585-master.opt rename to storage/tokudb/mysql-test/tokudb_bugs/t/5585-master.opt diff --git a/mysql-test/suite/tokudb.bugs/t/5585.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5585.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5585.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5585.test diff --git a/mysql-test/suite/tokudb.bugs/t/5695.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5695.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5695.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5695.test diff --git a/mysql-test/suite/tokudb.bugs/t/5733_innodb.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5733_innodb.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5733_innodb.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5733_innodb.test diff --git a/mysql-test/suite/tokudb.bugs/t/5733_tokudb.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5733_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5733_tokudb.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5733_tokudb.test diff --git a/mysql-test/suite/tokudb.bugs/t/5951.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5951.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5951.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5951.test diff --git a/mysql-test/suite/tokudb.bugs/t/5974-2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5974-2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5974-2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5974-2.test diff --git a/mysql-test/suite/tokudb.bugs/t/5974.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5974.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/5974.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/5974.test diff --git a/mysql-test/suite/tokudb.bugs/t/6053.test b/storage/tokudb/mysql-test/tokudb_bugs/t/6053.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/6053.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/6053.test diff --git a/mysql-test/suite/tokudb.bugs/t/6684.test b/storage/tokudb/mysql-test/tokudb_bugs/t/6684.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/6684.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/6684.test diff --git a/mysql-test/suite/tokudb.bugs/t/889.test b/storage/tokudb/mysql-test/tokudb_bugs/t/889.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/889.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/889.test diff --git a/mysql-test/suite/tokudb.bugs/t/895.test b/storage/tokudb/mysql-test/tokudb_bugs/t/895.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/895.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/895.test diff --git a/mysql-test/suite/tokudb.bugs/t/94.test b/storage/tokudb/mysql-test/tokudb_bugs/t/94.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/94.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/94.test diff --git a/mysql-test/suite/tokudb.bugs/t/alter_external_lock_assert.test b/storage/tokudb/mysql-test/tokudb_bugs/t/alter_external_lock_assert.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/alter_external_lock_assert.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/alter_external_lock_assert.test diff --git a/mysql-test/suite/tokudb.bugs/t/alter_part_tokudb_bug_155.test b/storage/tokudb/mysql-test/tokudb_bugs/t/alter_part_tokudb_bug_155.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/alter_part_tokudb_bug_155.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/alter_part_tokudb_bug_155.test diff --git a/mysql-test/suite/tokudb.bugs/t/alter_table_copy_table.test b/storage/tokudb/mysql-test/tokudb_bugs/t/alter_table_copy_table.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/alter_table_copy_table.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/alter_table_copy_table.test diff --git a/mysql-test/suite/tokudb.bugs/t/bulk_fetch.test b/storage/tokudb/mysql-test/tokudb_bugs/t/bulk_fetch.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/bulk_fetch.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/bulk_fetch.test diff --git a/mysql-test/suite/tokudb.bugs/t/checkpoint_lock.test b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/checkpoint_lock.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock.test diff --git a/mysql-test/suite/tokudb.bugs/t/checkpoint_lock_2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/checkpoint_lock_2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_2.test diff --git a/mysql-test/suite/tokudb.bugs/t/checkpoint_lock_3.test b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_3.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/checkpoint_lock_3.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_3.test diff --git a/mysql-test/suite/tokudb.bugs/t/commit_index_end_1.test b/storage/tokudb/mysql-test/tokudb_bugs/t/commit_index_end_1.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/commit_index_end_1.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/commit_index_end_1.test diff --git a/mysql-test/suite/tokudb.bugs/t/commit_index_end_2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/commit_index_end_2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/commit_index_end_2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/commit_index_end_2.test diff --git a/mysql-test/suite/tokudb.bugs/t/db397_delete_trigger.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_delete_trigger.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db397_delete_trigger.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db397_delete_trigger.test diff --git a/mysql-test/suite/tokudb.bugs/t/db397_insert_trigger.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_insert_trigger.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db397_insert_trigger.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db397_insert_trigger.test diff --git a/mysql-test/suite/tokudb.bugs/t/db397_update_trigger.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_update_trigger.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db397_update_trigger.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db397_update_trigger.test diff --git a/mysql-test/suite/tokudb.bugs/t/db739_insert.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db739_insert.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db739_insert.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db739_insert.test diff --git a/mysql-test/suite/tokudb.bugs/t/db739_replace.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db739_replace.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db739_replace.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db739_replace.test diff --git a/mysql-test/suite/tokudb.bugs/t/db739_upsert.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db739_upsert.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db739_upsert.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db739_upsert.test diff --git a/mysql-test/suite/tokudb.bugs/t/db743.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db743.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db743.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db743.test diff --git a/mysql-test/suite/tokudb.bugs/t/db756_card_part_hash.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db756_card_part_hash.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash.test diff --git a/mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_1.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_1.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_1.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_1.test diff --git a/mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_1_pick.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_1_pick.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_1_pick.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_1_pick.test diff --git a/mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_2.test diff --git a/mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_2_pick.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_2_pick.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db756_card_part_hash_2_pick.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db756_card_part_hash_2_pick.test diff --git a/mysql-test/suite/tokudb.bugs/t/db757_part_alter_analyze.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db757_part_alter_analyze.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db757_part_alter_analyze.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db757_part_alter_analyze.test diff --git a/mysql-test/suite/tokudb.bugs/t/db762.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db762.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db762.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db762.test diff --git a/mysql-test/suite/tokudb.bugs/t/db766.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db766.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db766.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db766.test diff --git a/mysql-test/suite/tokudb.bugs/t/db768.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db768.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db768.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db768.test diff --git a/mysql-test/suite/tokudb.bugs/t/db771.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db771.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db771.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db771.test diff --git a/mysql-test/suite/tokudb.bugs/t/db788-optimize-index-name.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db788-optimize-index-name.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db788-optimize-index-name.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db788-optimize-index-name.test diff --git a/mysql-test/suite/tokudb.bugs/t/db801.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db801.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db801.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db801.test diff --git a/mysql-test/suite/tokudb.bugs/t/db805.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db805.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db805.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db805.test diff --git a/mysql-test/suite/tokudb.bugs/t/db806.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db806.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db806.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db806.test diff --git a/mysql-test/suite/tokudb.bugs/t/db811.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db811.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db811.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db811.test diff --git a/mysql-test/suite/tokudb.bugs/t/db811s.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db811s.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db811s.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db811s.test diff --git a/mysql-test/suite/tokudb.bugs/t/db817.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db817.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db817.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db817.test diff --git a/mysql-test/suite/tokudb.bugs/t/db823.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db823.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/db823.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/db823.test diff --git a/mysql-test/suite/tokudb.bugs/t/dict_leak_3518.test b/storage/tokudb/mysql-test/tokudb_bugs/t/dict_leak_3518.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/dict_leak_3518.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/dict_leak_3518.test diff --git a/mysql-test/suite/tokudb.bugs/t/disabled.def b/storage/tokudb/mysql-test/tokudb_bugs/t/disabled.def similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/disabled.def rename to storage/tokudb/mysql-test/tokudb_bugs/t/disabled.def diff --git a/mysql-test/suite/tokudb.bugs/t/expand_tinytext_text.test b/storage/tokudb/mysql-test/tokudb_bugs/t/expand_tinytext_text.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/expand_tinytext_text.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/expand_tinytext_text.test diff --git a/mysql-test/suite/tokudb.bugs/t/fileops-2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/fileops-2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/fileops-2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/fileops-2.test diff --git a/mysql-test/suite/tokudb.bugs/t/fileops-3.test b/storage/tokudb/mysql-test/tokudb_bugs/t/fileops-3.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/fileops-3.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/fileops-3.test diff --git a/mysql-test/suite/tokudb.bugs/t/fileops-4.test b/storage/tokudb/mysql-test/tokudb_bugs/t/fileops-4.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/fileops-4.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/fileops-4.test diff --git a/mysql-test/suite/tokudb.bugs/t/fileops.test b/storage/tokudb/mysql-test/tokudb_bugs/t/fileops.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/fileops.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/fileops.test diff --git a/mysql-test/suite/tokudb.bugs/t/frm_store.test b/storage/tokudb/mysql-test/tokudb_bugs/t/frm_store.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/frm_store.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/frm_store.test diff --git a/mysql-test/suite/tokudb.bugs/t/frm_store2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/frm_store2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/frm_store2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/frm_store2.test diff --git a/mysql-test/suite/tokudb.bugs/t/frm_store3.test b/storage/tokudb/mysql-test/tokudb_bugs/t/frm_store3.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/frm_store3.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/frm_store3.test diff --git a/mysql-test/suite/tokudb.bugs/t/ft-index-40.test b/storage/tokudb/mysql-test/tokudb_bugs/t/ft-index-40.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/ft-index-40.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/ft-index-40.test diff --git a/mysql-test/suite/tokudb.bugs/t/index_read.test b/storage/tokudb/mysql-test/tokudb_bugs/t/index_read.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/index_read.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/index_read.test diff --git a/mysql-test/suite/tokudb.bugs/t/leak172.test b/storage/tokudb/mysql-test/tokudb_bugs/t/leak172.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/leak172.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/leak172.test diff --git a/mysql-test/suite/tokudb.bugs/t/lock_uniq_key_empty.test b/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/lock_uniq_key_empty.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_empty.test diff --git a/mysql-test/suite/tokudb.bugs/t/lock_uniq_key_left.test b/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_left.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/lock_uniq_key_left.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_left.test diff --git a/mysql-test/suite/tokudb.bugs/t/lock_uniq_key_middle.test b/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_middle.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/lock_uniq_key_middle.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_middle.test diff --git a/mysql-test/suite/tokudb.bugs/t/lock_uniq_key_right.test b/storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_right.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/lock_uniq_key_right.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/lock_uniq_key_right.test diff --git a/mysql-test/suite/tokudb.bugs/t/mdev4533.test b/storage/tokudb/mysql-test/tokudb_bugs/t/mdev4533.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/mdev4533.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/mdev4533.test diff --git a/mysql-test/suite/tokudb.bugs/t/mdev5932.test b/storage/tokudb/mysql-test/tokudb_bugs/t/mdev5932.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/mdev5932.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/mdev5932.test diff --git a/mysql-test/suite/tokudb.bugs/t/optimize_temp_table_tokudb.test b/storage/tokudb/mysql-test/tokudb_bugs/t/optimize_temp_table_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/optimize_temp_table_tokudb.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/optimize_temp_table_tokudb.test diff --git a/mysql-test/suite/tokudb.bugs/t/rpl_mixed_replace_into.test b/storage/tokudb/mysql-test/tokudb_bugs/t/rpl_mixed_replace_into.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/rpl_mixed_replace_into.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/rpl_mixed_replace_into.test diff --git a/mysql-test/suite/tokudb.bugs/t/rpl_row_replace_into.test b/storage/tokudb/mysql-test/tokudb_bugs/t/rpl_row_replace_into.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/rpl_row_replace_into.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/rpl_row_replace_into.test diff --git a/mysql-test/suite/tokudb.bugs/t/rpl_stmt_replace_into.test b/storage/tokudb/mysql-test/tokudb_bugs/t/rpl_stmt_replace_into.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/rpl_stmt_replace_into.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/rpl_stmt_replace_into.test diff --git a/mysql-test/suite/tokudb.bugs/t/simple_icp.test b/storage/tokudb/mysql-test/tokudb_bugs/t/simple_icp.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/simple_icp.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/simple_icp.test diff --git a/mysql-test/suite/tokudb.bugs/t/subselect_index_next_same_bug_157.test b/storage/tokudb/mysql-test/tokudb_bugs/t/subselect_index_next_same_bug_157.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/subselect_index_next_same_bug_157.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/subselect_index_next_same_bug_157.test diff --git a/mysql-test/suite/tokudb.parts/t/suite.opt b/storage/tokudb/mysql-test/tokudb_bugs/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_bugs/t/suite.opt diff --git a/mysql-test/suite/tokudb.bugs/t/tokudb718.test b/storage/tokudb/mysql-test/tokudb_bugs/t/tokudb718.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/tokudb718.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/tokudb718.test diff --git a/mysql-test/suite/tokudb.bugs/t/tokudb_drop_part_table_668.test b/storage/tokudb/mysql-test/tokudb_bugs/t/tokudb_drop_part_table_668.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/tokudb_drop_part_table_668.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/tokudb_drop_part_table_668.test diff --git a/mysql-test/suite/tokudb.bugs/t/tokudb_drop_simple_table_668.test b/storage/tokudb/mysql-test/tokudb_bugs/t/tokudb_drop_simple_table_668.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/tokudb_drop_simple_table_668.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/tokudb_drop_simple_table_668.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa-1.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-1.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa-1.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa-1.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa-2.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-2.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa-2.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa-2.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa-3.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-3.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa-3.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa-3.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa-4.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-4.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa-4.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa-4.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa-5.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-5.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa-5.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa-5.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa-6.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-6.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa-6.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa-6.test diff --git a/mysql-test/suite/tokudb.bugs/t/xa.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa.test similarity index 100% rename from mysql-test/suite/tokudb.bugs/t/xa.test rename to storage/tokudb/mysql-test/tokudb_bugs/t/xa.test diff --git a/mysql-test/suite/tokudb.parts/r/part_blocked_sql_func_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/part_blocked_sql_func_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/part_blocked_sql_func_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/part_blocked_sql_func_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/part_supported_sql_func_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/part_supported_sql_func_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/part_supported_sql_func_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/part_supported_sql_func_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter1_1_2_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter1_1_2_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter1_1_2_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter1_1_2_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter1_1_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter1_1_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter1_1_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter1_1_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter1_2_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter1_2_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter1_2_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter1_2_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter2_1_1_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_1_1_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter2_1_1_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_1_1_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter2_1_2_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_1_2_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter2_1_2_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_1_2_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter2_2_1_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_2_1_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter2_2_1_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_2_1_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter2_2_2_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_2_2_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter2_2_2_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter2_2_2_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter3_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter3_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter3_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter3_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_alter4_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_alter4_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_alter4_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_alter4_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_auto_increment_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_auto_increment_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_auto_increment_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_basic_symlink_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_basic_symlink_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_basic_symlink_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_basic_symlink_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_basic_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_basic_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_basic_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_basic_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_bit_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_bit_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_bit_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_bit_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_char_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_char_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_char_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_char_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_datetime_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_datetime_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_datetime_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_datetime_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_debug_sync_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_debug_sync_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_debug_sync_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_debug_sync_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_debug_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_debug_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_debug_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_debug_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_decimal_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_decimal_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_decimal_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_decimal_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_engine_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_engine_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_engine_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_engine_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_myisam_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_myisam_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_myisam_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_myisam_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_qa_1_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_1_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_qa_1_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_1_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_qa_4_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_4_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_qa_4_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_4_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_qa_5_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_5_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_qa_5_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_5_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_qa_7_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_7_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_qa_7_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_7_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_qa_8_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_8_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_qa_8_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_qa_8_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exch_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exch_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exch_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_exchange_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_exchange_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_exchange_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_exchange_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_float_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_float_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_float_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_float_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_int_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_int_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_int_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_int_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_parts_hash_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_hash_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_parts_hash_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_hash_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_parts_inv_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_inv_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_parts_inv_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_inv_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_parts_key_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_key_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_parts_key_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_key_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_parts_list_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_list_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_parts_list_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_list_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_parts_range_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_range_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_parts_range_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_parts_range_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_key_list_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_key_list_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_key_list_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_key_list_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_key_range_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_key_range_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_key_range_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_key_range_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_list_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_list_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_list_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_list_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_range_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_range_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_max_sub_parts_range_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_max_sub_parts_range_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_mgm_lc0_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc0_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_mgm_lc0_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc0_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_mgm_lc10_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc10_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_mgm_lc10_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc10_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_mgm_lc1_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc1_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_mgm_lc1_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc1_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_mgm_lc2_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc2_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_mgm_lc2_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_mgm_lc2_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_reorganize_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_reorganize_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_reorganize_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_reorganize_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_special_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_special_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_special_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_special_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_syntax_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_syntax_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_syntax_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/r/partition_value_tokudb.result b/storage/tokudb/mysql-test/tokudb_parts/r/partition_value_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.parts/r/partition_value_tokudb.result rename to storage/tokudb/mysql-test/tokudb_parts/r/partition_value_tokudb.result diff --git a/mysql-test/suite/tokudb.parts/t/disabled.def b/storage/tokudb/mysql-test/tokudb_parts/t/disabled.def similarity index 100% rename from mysql-test/suite/tokudb.parts/t/disabled.def rename to storage/tokudb/mysql-test/tokudb_parts/t/disabled.def diff --git a/mysql-test/suite/tokudb.parts/t/part_blocked_sql_func_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/part_blocked_sql_func_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/part_blocked_sql_func_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/part_blocked_sql_func_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/part_supported_sql_func_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/part_supported_sql_func_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/part_supported_sql_func_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/part_supported_sql_func_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter1_1_2_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter1_1_2_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter1_1_2_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter1_1_2_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter1_1_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter1_1_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter1_1_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter1_1_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter1_2_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter1_2_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter1_2_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter1_2_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter2_1_1_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_1_1_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter2_1_1_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_1_1_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter2_1_2_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_1_2_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter2_1_2_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_1_2_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter2_2_1_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_2_1_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter2_2_1_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_2_1_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter2_2_2_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_2_2_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter2_2_2_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter2_2_2_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter3_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter3_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter3_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter3_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_alter4_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_alter4_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_alter4_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_alter4_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_auto_increment_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_auto_increment_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_auto_increment_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_basic_symlink_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_basic_symlink_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_basic_symlink_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_basic_symlink_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_basic_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_basic_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_basic_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_basic_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_bit_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_bit_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_bit_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_bit_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_char_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_char_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_char_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_char_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_datetime_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_datetime_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_datetime_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_datetime_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_debug_sync_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_sync_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_debug_sync_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_sync_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_debug_sync_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_sync_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_debug_sync_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_sync_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_debug_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_debug_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_debug_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_debug_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_debug_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_decimal_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_decimal_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_decimal_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_decimal_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_engine_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_engine_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_engine_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_engine_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_myisam_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_myisam_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_myisam_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_myisam_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_qa_1_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_1_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_qa_1_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_1_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_qa_4_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_4_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_qa_4_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_4_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_qa_5_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_5_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_qa_5_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_5_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_qa_7_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_7_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_qa_7_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_7_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_qa_8_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_8_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_qa_8_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_qa_8_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exch_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exch_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exch_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_exchange_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_exchange_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_exchange_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_exchange_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_float_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_float_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_float_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_float_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_int_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_int_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_int_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_int_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_hash_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_hash_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_hash_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_hash_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_hash_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_hash_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_hash_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_hash_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_inv_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_inv_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_inv_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_inv_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_inv_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_inv_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_inv_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_inv_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_key_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_key_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_key_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_key_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_key_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_key_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_key_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_key_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_list_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_list_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_list_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_list_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_list_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_list_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_list_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_list_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_range_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_range_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_range_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_range_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_parts_range_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_range_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_parts_range_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_parts_range_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_list_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_list_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_list_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_list_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_list_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_list_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_list_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_list_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_range_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_range_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_range_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_range_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_range_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_range_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_key_range_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_key_range_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_list_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_list_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_list_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_list_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_list_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_list_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_list_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_list_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_range_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_range_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_range_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_range_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_range_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_range_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_max_sub_parts_range_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_max_sub_parts_range_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_mgm_lc0_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc0_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_mgm_lc0_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc0_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_mgm_lc10_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc10_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_mgm_lc10_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc10_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_mgm_lc1_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc1_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_mgm_lc1_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc1_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_mgm_lc1_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc1_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_mgm_lc1_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc1_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_mgm_lc2_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc2_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_mgm_lc2_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc2_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_mgm_lc2_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc2_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_mgm_lc2_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_mgm_lc2_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_reorganize_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_reorganize_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_reorganize_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_reorganize_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_special_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_special_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_special_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_special_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_special_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_special_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_special_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_special_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_syntax_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_syntax_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_syntax_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_syntax_tokudb.test diff --git a/mysql-test/suite/tokudb.parts/t/partition_tokudb_status_file-master.opt b/storage/tokudb/mysql-test/tokudb_parts/t/partition_tokudb_status_file-master.opt similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_tokudb_status_file-master.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_tokudb_status_file-master.opt diff --git a/mysql-test/suite/tokudb.parts/t/partition_value_tokudb.test b/storage/tokudb/mysql-test/tokudb_parts/t/partition_value_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.parts/t/partition_value_tokudb.test rename to storage/tokudb/mysql-test/tokudb_parts/t/partition_value_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/suite.opt b/storage/tokudb/mysql-test/tokudb_parts/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_parts/t/suite.opt diff --git a/mysql-test/suite/tokudb.rpl/combinations b/storage/tokudb/mysql-test/tokudb_rpl/combinations similarity index 100% rename from mysql-test/suite/tokudb.rpl/combinations rename to storage/tokudb/mysql-test/tokudb_rpl/combinations diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_deadlock_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_deadlock_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_deadlock_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_deadlock_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_extra_col_master_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_extra_col_master_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_extra_col_master_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_extra_col_master_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_extra_col_slave_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_extra_col_slave_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_extra_col_slave_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_extra_col_slave_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_foreign_key_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_foreign_key_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_foreign_key_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_foreign_key_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_mixed_row_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_mixed_row_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_mixed_row_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_mixed_row_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_not_null_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_not_null_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_not_null_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_not_null_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_delete_pk.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb_delete_pk.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_delete_pk.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb_delete_pk.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb_update_pk_uc0_lookup0.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_write_pk.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb_write_pk.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_parallel_tokudb_write_pk.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_parallel_tokudb_write_pk.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_partition_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_partition_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_partition_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_partition_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_relay_space_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_relay_space_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_relay_space_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_relay_space_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_basic_3tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_basic_3tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_basic_3tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_basic_3tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_blob_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_blob_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_blob_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_blob_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_log_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_log_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_log_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_log_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_rec_comp_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_rec_comp_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_rec_comp_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_rec_comp_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_sp002_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_sp002_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_sp002_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_sp002_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_sp007_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_sp007_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_sp007_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_sp007_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_row_tabledefs_3tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_tabledefs_3tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_row_tabledefs_3tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_row_tabledefs_3tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_set_null_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_set_null_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_set_null_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_set_null_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_stm_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_stm_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_stm_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_stm_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_bug28430.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_bug28430.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_bug28430.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_bug28430.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_bug30888.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_bug30888.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_bug30888.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_bug30888.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_delete_pk.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_delete_pk.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk_lookup1.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_delete_pk_lookup1.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_delete_pk_lookup1.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_delete_pk_lookup1.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_ddl.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_ddl.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_ddl.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_ddl.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_dml.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_dml.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_mixed_dml.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_dml.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ff.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_ff.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ff.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_ff.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ft.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_ft.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_ft.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_ft.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tf.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_tf.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tf.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_tf.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tt.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_tt.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_read_only_tt.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_read_only_tt.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc0_lookup0.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc0_lookup1.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc1_lookup0.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_pk_uc1_lookup1.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_unique_uc0_lookup0.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_update_unique_uc0_lookup1.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_pk.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_pk.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk_uc1.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_pk_uc1.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_pk_uc1.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_pk_uc1.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_unique.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_unique.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique_uc1.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_unique_uc1.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_tokudb_write_unique_uc1.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_write_unique_uc1.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_truncate_3tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_truncate_3tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_truncate_3tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_truncate_3tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/rpl_typeconv_tokudb.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_typeconv_tokudb.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/rpl_typeconv_tokudb.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/rpl_typeconv_tokudb.result diff --git a/mysql-test/suite/tokudb.rpl/r/tokudb_innodb_xa_crash.result b/storage/tokudb/mysql-test/tokudb_rpl/r/tokudb_innodb_xa_crash.result similarity index 100% rename from mysql-test/suite/tokudb.rpl/r/tokudb_innodb_xa_crash.result rename to storage/tokudb/mysql-test/tokudb_rpl/r/tokudb_innodb_xa_crash.result diff --git a/mysql-test/suite/tokudb.rpl/t/disabled.def b/storage/tokudb/mysql-test/tokudb_rpl/t/disabled.def similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/disabled.def rename to storage/tokudb/mysql-test/tokudb_rpl/t/disabled.def diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_deadlock_tokudb-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_deadlock_tokudb-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_deadlock_tokudb-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_deadlock_tokudb-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_deadlock_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_deadlock_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_deadlock_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_deadlock_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_extra_col_master_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_extra_col_master_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_extra_col_master_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_extra_col_master_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_extra_col_slave_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_extra_col_slave_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_extra_col_slave_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_extra_col_slave_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_foreign_key_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_foreign_key_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_foreign_key_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_foreign_key_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_mixed_row_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_mixed_row_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_mixed_row_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_mixed_row_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_not_null_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_not_null_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_not_null_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_not_null_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_delete_pk-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_delete_pk.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_delete_pk.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_delete_pk.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_update_pk_uc0_lookup0.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_write_pk-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_write_pk-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_write_pk.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_parallel_tokudb_write_pk.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_parallel_tokudb_write_pk.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_partition_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_partition_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_partition_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_partition_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_partition_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_partition_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_partition_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_partition_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_relay_space_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_relay_space_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_relay_space_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_relay_space_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_basic_3tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_basic_3tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_basic_3tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_basic_3tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_blob_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_blob_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_blob_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_blob_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_log_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_log_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_log_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_log_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_log_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_log_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_log_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_log_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_rec_comp_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_rec_comp_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_rec_comp_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_rec_comp_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_sp002_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_sp002_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_sp002_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_sp002_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_sp007_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_sp007_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_sp007_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_sp007_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_row_tabledefs_3tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_tabledefs_3tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_row_tabledefs_3tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_row_tabledefs_3tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_set_null_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_set_null_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_set_null_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_set_null_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_stm_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_stm_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_stm_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_stm_tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb-master.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb-master.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb-master.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb-master.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug28430-master.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug28430-master.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug28430-master.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug28430-master.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug28430-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug28430-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug28430-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug28430-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug28430.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug28430.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug28430.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug28430.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug30888.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug30888.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_bug30888.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_bug30888.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk_lookup1-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk_lookup1.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_delete_pk_lookup1.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_delete_pk_lookup1.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_ddl.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_mixed_ddl.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_ddl.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_mixed_ddl.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_mixed_dml.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_mixed_dml.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_mixed_dml.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ff-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ff-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ff.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ff.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ff.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ft-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ft-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ft.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_ft.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_ft.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tf-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tf-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tf.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tf.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tf.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tt-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tt-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tt.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_read_only_tt.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_read_only_tt.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup0-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup0.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup1-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc0_lookup1.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup0-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup0.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup1-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_pk_uc1_lookup1.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup0-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup0.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup1-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_update_unique_uc0_lookup1.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk_uc1-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk_uc1-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk_uc1.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_pk_uc1.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_pk_uc1.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique_uc1-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique_uc1-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique_uc1.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_tokudb_write_unique_uc1.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_tokudb_write_unique_uc1.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_truncate_3tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_truncate_3tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_truncate_3tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_truncate_3tokudb.test diff --git a/mysql-test/suite/tokudb.rpl/t/rpl_typeconv_tokudb.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_typeconv_tokudb.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/rpl_typeconv_tokudb.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/rpl_typeconv_tokudb.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/suite.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/suite.opt diff --git a/mysql-test/suite/tokudb.rpl/t/tokudb_innodb_xa_crash-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/tokudb_innodb_xa_crash-slave.opt similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/tokudb_innodb_xa_crash-slave.opt rename to storage/tokudb/mysql-test/tokudb_rpl/t/tokudb_innodb_xa_crash-slave.opt diff --git a/mysql-test/suite/tokudb.rpl/t/tokudb_innodb_xa_crash.test b/storage/tokudb/mysql-test/tokudb_rpl/t/tokudb_innodb_xa_crash.test similarity index 100% rename from mysql-test/suite/tokudb.rpl/t/tokudb_innodb_xa_crash.test rename to storage/tokudb/mysql-test/tokudb_rpl/t/tokudb_innodb_xa_crash.test diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_delete_fraction.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_delete_fraction.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_delete_fraction.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_delete_fraction.result diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_in_background_basic.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_in_background_basic.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_in_background_basic.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_in_background_basic.result diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_mode_basic.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_mode_basic.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_mode_basic.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_mode_basic.result diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_throttle_basic.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_throttle_basic.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_throttle_basic.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_throttle_basic.result diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_time_basic.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_time_basic.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_analyze_time_basic.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_analyze_time_basic.result diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_auto_analyze.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_auto_analyze.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_auto_analyze.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_auto_analyze.result diff --git a/mysql-test/suite/tokudb.sys_vars/r/tokudb_cardinality_scale_percent_basic.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_cardinality_scale_percent_basic.result similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/r/tokudb_cardinality_scale_percent_basic.result rename to storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_cardinality_scale_percent_basic.result diff --git a/mysql-test/suite/tokudb/t/suite.opt b/storage/tokudb/mysql-test/tokudb_sys_vars/t/suite.opt similarity index 100% rename from mysql-test/suite/tokudb/t/suite.opt rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/suite.opt diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_delete_fraction.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_delete_fraction.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_delete_fraction.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_delete_fraction.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_in_background_basic.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_in_background_basic.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_in_background_basic.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_in_background_basic.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_mode_basic.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_mode_basic.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_mode_basic.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_mode_basic.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_throttle_basic.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_throttle_basic.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_throttle_basic.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_throttle_basic.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_time_basic.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_time_basic.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_analyze_time_basic.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_analyze_time_basic.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_auto_analyze.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_auto_analyze.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_auto_analyze.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_auto_analyze.test diff --git a/mysql-test/suite/tokudb.sys_vars/t/tokudb_cardinality_scale_percent_basic.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_cardinality_scale_percent_basic.test similarity index 100% rename from mysql-test/suite/tokudb.sys_vars/t/tokudb_cardinality_scale_percent_basic.test rename to storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_cardinality_scale_percent_basic.test From 30d9d4e26d2e0f8cbbd1220df077fe809c8bbfe4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 26 Apr 2016 20:58:29 +0200 Subject: [PATCH 019/112] 5.6.29-76.2 --- storage/tokudb/CMakeLists.txt | 2 +- storage/tokudb/ha_tokudb.cc | 275 +++++++++++------- storage/tokudb/ha_tokudb.h | 37 ++- storage/tokudb/ha_tokudb_admin.cc | 6 +- storage/tokudb/ha_tokudb_alter_56.cc | 4 +- storage/tokudb/ha_tokudb_alter_common.cc | 17 +- storage/tokudb/ha_tokudb_update.cc | 4 +- storage/tokudb/hatoku_cmp.cc | 14 +- storage/tokudb/hatoku_defines.h | 4 +- storage/tokudb/hatoku_hton.cc | 24 +- storage/tokudb/hatoku_hton.h | 10 - .../tokudb/r/background_job_manager.result | Bin 6893 -> 6874 bytes .../tokudb/r/truncate_row_count.result | 2 +- .../r/db756_card_part_hash_1_pick.result | 2 +- .../r/db757_part_alter_analyze.result | 6 +- .../mysql-test/tokudb_bugs/r/db917.result | 14 + .../mysql-test/tokudb_bugs/r/db938.result | 34 +++ .../mysql-test/tokudb_bugs/t/db917.test | 22 ++ .../mysql-test/tokudb_bugs/t/db938.test | 76 +++++ .../tokudb/mysql-test/tokudb_bugs/t/xa-3.test | 6 + .../tokudb/mysql-test/tokudb_bugs/t/xa-4.test | 6 + .../tokudb/mysql-test/tokudb_bugs/t/xa-6.test | 6 + storage/tokudb/tokudb_card.h | 7 +- storage/tokudb/tokudb_debug.h | 58 +++- storage/tokudb/tokudb_information_schema.cc | 4 +- 25 files changed, 487 insertions(+), 153 deletions(-) create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/r/db917.result create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/r/db938.result create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/t/db917.test create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/t/db938.test diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 2360c6b2c9a70..7b01c97958f48 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(TOKUDB_VERSION 5.6.28-76.1) +SET(TOKUDB_VERSION 5.6.29-76.2) # PerconaFT only supports x86-64 and cmake-2.8.9+ IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT CMAKE_VERSION VERSION_LESS "2.8.9") diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index 3979b360d8f2d..d50273dba295e 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -161,6 +161,15 @@ void TOKUDB_SHARE::static_init() { void TOKUDB_SHARE::static_destroy() { my_hash_free(&_open_tables); } +const char* TOKUDB_SHARE::get_state_string(share_state_t state) { + static const char* state_string[] = { + "CLOSED", + "OPENED", + "ERROR" + }; + assert_always(state == CLOSED || state == OPENED || state == ERROR); + return state_string[state]; +} void* TOKUDB_SHARE::operator new(size_t sz) { return tokudb::memory::malloc(sz, MYF(MY_WME|MY_ZEROFILL|MY_FAE)); } @@ -186,12 +195,24 @@ void TOKUDB_SHARE::init(const char* table_name) { _database_name, _table_name, tmp_dictionary_name); + + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count); + TOKUDB_SHARE_DBUG_VOID_RETURN(); } void TOKUDB_SHARE::destroy() { + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count); + assert_always(_use_count == 0); assert_always( _state == TOKUDB_SHARE::CLOSED || _state == TOKUDB_SHARE::ERROR); thr_lock_delete(&_thr_lock); + TOKUDB_SHARE_DBUG_VOID_RETURN(); } TOKUDB_SHARE* TOKUDB_SHARE::get_share( const char* table_name, @@ -207,6 +228,14 @@ TOKUDB_SHARE* TOKUDB_SHARE::get_share( &_open_tables, (uchar*)table_name, length); + + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_SHARE, + "existing share[%s] %s:share[%p]", + table_name, + share == NULL ? "not found" : "found", + share); + if (!share) { if (create_new == false) goto exit; @@ -237,25 +266,41 @@ TOKUDB_SHARE* TOKUDB_SHARE::get_share( return share; } void TOKUDB_SHARE::drop_share(TOKUDB_SHARE* share) { + TOKUDB_TRACE_FOR_FLAGS( + TOKUDB_DEBUG_SHARE, + "share[%p]:file[%s]:state[%s]:use_count[%d]", + share, + share->_full_table_name.ptr(), + get_state_string(share->_state), + share->_use_count); + _open_tables_mutex.lock(); my_hash_delete(&_open_tables, (uchar*)share); _open_tables_mutex.unlock(); } TOKUDB_SHARE::share_state_t TOKUDB_SHARE::addref() { + TOKUDB_SHARE_TRACE_FOR_FLAGS((TOKUDB_DEBUG_ENTER & TOKUDB_DEBUG_SHARE), + "file[%s]:state[%s]:use_count[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count); + lock(); _use_count++; - DBUG_PRINT("info", ("0x%p share->_use_count %u", this, _use_count)); - return _state; } int TOKUDB_SHARE::release() { + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count); + int error, result = 0; _mutex.lock(); assert_always(_use_count != 0); _use_count--; - DBUG_PRINT("info", ("0x%p share->_use_count %u", this, _use_count)); if (_use_count == 0 && _state == TOKUDB_SHARE::OPENED) { // number of open DB's may not be equal to number of keys we have // because add_index may have added some. So, we loop through entire @@ -299,7 +344,7 @@ int TOKUDB_SHARE::release() { } _mutex.unlock(); - return result; + TOKUDB_SHARE_DBUG_RETURN(result); } void TOKUDB_SHARE::update_row_count( THD* thd, @@ -350,34 +395,32 @@ void TOKUDB_SHARE::update_row_count( unlock(); } void TOKUDB_SHARE::set_cardinality_counts_in_table(TABLE* table) { - // if there is nothing new to report, just skip it. - if (_card_changed) { - lock(); - uint32_t next_key_part = 0; - for (uint32_t i = 0; i < table->s->keys; i++) { - bool is_unique_key = - (i == table->s->primary_key) || - (table->key_info[i].flags & HA_NOSAME); - - uint32_t num_key_parts = get_key_parts(&table->key_info[i]); - for (uint32_t j = 0; j < num_key_parts; j++) { - assert_always(next_key_part < _rec_per_keys); - ulong val = _rec_per_key[next_key_part++]; - if (is_unique_key && j == num_key_parts-1) { - val = 1; - } else { - val = - (val*tokudb::sysvars::cardinality_scale_percent)/100; - if (val == 0) - val = 1; - } + lock(); + uint32_t next_key_part = 0; + for (uint32_t i = 0; i < table->s->keys; i++) { + KEY* key = &table->key_info[i]; + bool is_unique_key = + (i == table->s->primary_key) || (key->flags & HA_NOSAME); + + for (uint32_t j = 0; j < key->actual_key_parts; j++) { + if (j >= key->user_defined_key_parts) { + // MySQL 'hidden' keys, really needs deeper investigation + // into MySQL hidden keys vs TokuDB hidden keys + key->rec_per_key[j] = 1; + continue; + } - table->key_info[i].rec_per_key[j] = val; + assert_always(next_key_part < _rec_per_keys); + ulong val = _rec_per_key[next_key_part++]; + val = (val * tokudb::sysvars::cardinality_scale_percent) / 100; + if (val == 0 || _rows == 0 || + (is_unique_key && j == key->actual_key_parts - 1)) { + val = 1; } + key->rec_per_key[j] = val; } - _card_changed = false; - unlock(); } + unlock(); } #define HANDLE_INVALID_CURSOR() \ @@ -771,29 +814,36 @@ static int filter_key_part_compare (const void* left, const void* right) { // if key, table have proper info set. I had to verify by checking // in the debugger. // -void set_key_filter(MY_BITMAP* key_filter, KEY* key, TABLE* table, bool get_offset_from_keypart) { +void set_key_filter( + MY_BITMAP* key_filter, + KEY* key, + TABLE* table, + bool get_offset_from_keypart) { + FILTER_KEY_PART_INFO parts[MAX_REF_PARTS]; uint curr_skip_index = 0; - for (uint i = 0; i < get_key_parts(key); i++) { + for (uint i = 0; i < key->user_defined_key_parts; i++) { // // horrendous hack due to bugs in mysql, basically // we cannot always reliably get the offset from the same source // - parts[i].offset = get_offset_from_keypart ? key->key_part[i].offset : field_offset(key->key_part[i].field, table); + parts[i].offset = + get_offset_from_keypart ? + key->key_part[i].offset : + field_offset(key->key_part[i].field, table); parts[i].part_index = i; } qsort( parts, // start of array - get_key_parts(key), //num elements + key->user_defined_key_parts, //num elements sizeof(*parts), //size of each element - filter_key_part_compare - ); + filter_key_part_compare); for (uint i = 0; i < table->s->fields; i++) { Field* field = table->field[i]; uint curr_field_offset = field_offset(field, table); - if (curr_skip_index < get_key_parts(key)) { + if (curr_skip_index < key->user_defined_key_parts) { uint curr_skip_offset = 0; curr_skip_offset = parts[curr_skip_index].offset; if (curr_skip_offset == curr_field_offset) { @@ -1595,7 +1645,11 @@ static int initialize_key_and_col_info( return error; } -bool ha_tokudb::can_replace_into_be_fast(TABLE_SHARE* table_share, KEY_AND_COL_INFO* kc_info, uint pk) { +bool ha_tokudb::can_replace_into_be_fast( + TABLE_SHARE* table_share, + KEY_AND_COL_INFO* kc_info, + uint pk) { + uint curr_num_DBs = table_share->keys + tokudb_test(hidden_primary_key); bool ret_val; if (curr_num_DBs == 1) { @@ -1606,7 +1660,7 @@ bool ha_tokudb::can_replace_into_be_fast(TABLE_SHARE* table_share, KEY_AND_COL_I for (uint curr_index = 0; curr_index < table_share->keys; curr_index++) { if (curr_index == pk) continue; KEY* curr_key_info = &table_share->key_info[curr_index]; - for (uint i = 0; i < get_key_parts(curr_key_info); i++) { + for (uint i = 0; i < curr_key_info->user_defined_key_parts; i++) { uint16 curr_field_index = curr_key_info->key_part[i].field->field_index; if (!bitmap_is_set(&kc_info->key_filters[curr_index],curr_field_index)) { ret_val = false; @@ -1692,7 +1746,8 @@ int ha_tokudb::initialize_share(const char* name, int mode) { /* Open other keys; These are part of the share structure */ for (uint i = 0; i < table_share->keys; i++) { - share->_key_descriptors[i]._parts = get_key_parts(&table_share->key_info[i]); + share->_key_descriptors[i]._parts = + table_share->key_info[i].user_defined_key_parts; if (i == primary_key) { share->_key_descriptors[i]._is_unique = true; share->_key_descriptors[i]._name = tokudb::memory::strdup("primary", 0); @@ -1732,8 +1787,9 @@ int ha_tokudb::initialize_share(const char* name, int mode) { // the "infinity byte" in keys, and for placing the DBT size in the first four bytes // ref_length = sizeof(uint32_t) + sizeof(uchar); - KEY_PART_INFO *key_part = table->key_info[primary_key].key_part; - KEY_PART_INFO *end = key_part + get_key_parts(&table->key_info[primary_key]); + KEY_PART_INFO* key_part = table->key_info[primary_key].key_part; + KEY_PART_INFO* end = + key_part + table->key_info[primary_key].user_defined_key_parts; for (; key_part != end; key_part++) { ref_length += key_part->field->max_packed_col_length(key_part->length); TOKU_TYPE toku_type = mysql_to_toku_type(key_part->field); @@ -1901,6 +1957,7 @@ int ha_tokudb::open(const char *name, int mode, uint test_if_locked) { if (ret_val == 0) { share->set_state(TOKUDB_SHARE::OPENED); } else { + free_key_and_col_info(&share->kc_info); share->set_state(TOKUDB_SHARE::ERROR); } share->unlock(); @@ -2616,13 +2673,13 @@ int ha_tokudb::unpack_row( } uint32_t ha_tokudb::place_key_into_mysql_buff( - KEY* key_info, - uchar * record, - uchar* data - ) -{ - KEY_PART_INFO *key_part = key_info->key_part, *end = key_part + get_key_parts(key_info); - uchar *pos = data; + KEY* key_info, + uchar* record, + uchar* data) { + + KEY_PART_INFO* key_part = key_info->key_part; + KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; + uchar* pos = data; for (; key_part != end; key_part++) { if (key_part->field->null_bit) { @@ -2682,15 +2739,14 @@ void ha_tokudb::unpack_key(uchar * record, DBT const *key, uint index) { } uint32_t ha_tokudb::place_key_into_dbt_buff( - KEY* key_info, - uchar * buff, - const uchar * record, - bool* has_null, - int key_length - ) -{ - KEY_PART_INFO *key_part = key_info->key_part; - KEY_PART_INFO *end = key_part + get_key_parts(key_info); + KEY* key_info, + uchar* buff, + const uchar* record, + bool* has_null, + int key_length) { + + KEY_PART_INFO* key_part = key_info->key_part; + KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; uchar* curr_buff = buff; *has_null = false; for (; key_part != end && key_length > 0; key_part++) { @@ -2870,25 +2926,29 @@ DBT* ha_tokudb::create_dbt_key_for_lookup( // Returns: // the parameter key // -DBT *ha_tokudb::pack_key( - DBT * key, - uint keynr, - uchar * buff, - const uchar * key_ptr, - uint key_length, - int8_t inf_byte - ) -{ - TOKUDB_HANDLER_DBUG_ENTER("key %p %u:%2.2x inf=%d", key_ptr, key_length, key_length > 0 ? key_ptr[0] : 0, inf_byte); +DBT* ha_tokudb::pack_key( + DBT* key, + uint keynr, + uchar* buff, + const uchar* key_ptr, + uint key_length, + int8_t inf_byte) { + + TOKUDB_HANDLER_DBUG_ENTER( + "key %p %u:%2.2x inf=%d", + key_ptr, + key_length, + key_length > 0 ? key_ptr[0] : 0, + inf_byte); #if TOKU_INCLUDE_EXTENDED_KEYS if (keynr != primary_key && !tokudb_test(hidden_primary_key)) { DBUG_RETURN(pack_ext_key(key, keynr, buff, key_ptr, key_length, inf_byte)); } #endif - KEY *key_info = &table->key_info[keynr]; - KEY_PART_INFO *key_part = key_info->key_part; - KEY_PART_INFO *end = key_part + get_key_parts(key_info); - my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set); + KEY* key_info = &table->key_info[keynr]; + KEY_PART_INFO* key_part = key_info->key_part; + KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; + my_bitmap_map* old_map = dbug_tmp_use_all_columns(table, table->write_set); memset((void *) key, 0, sizeof(*key)); key->data = buff; @@ -2930,31 +2990,30 @@ DBT *ha_tokudb::pack_key( } #if TOKU_INCLUDE_EXTENDED_KEYS -DBT *ha_tokudb::pack_ext_key( - DBT * key, - uint keynr, - uchar * buff, - const uchar * key_ptr, - uint key_length, - int8_t inf_byte - ) -{ +DBT* ha_tokudb::pack_ext_key( + DBT* key, + uint keynr, + uchar* buff, + const uchar* key_ptr, + uint key_length, + int8_t inf_byte) { + TOKUDB_HANDLER_DBUG_ENTER(""); // build a list of PK parts that are in the SK. we will use this list to build the // extended key if necessary. - KEY *pk_key_info = &table->key_info[primary_key]; - uint pk_parts = get_key_parts(pk_key_info); + KEY* pk_key_info = &table->key_info[primary_key]; + uint pk_parts = pk_key_info->user_defined_key_parts; uint pk_next = 0; struct { const uchar *key_ptr; KEY_PART_INFO *key_part; } pk_info[pk_parts]; - KEY *key_info = &table->key_info[keynr]; - KEY_PART_INFO *key_part = key_info->key_part; - KEY_PART_INFO *end = key_part + get_key_parts(key_info); - my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set); + KEY* key_info = &table->key_info[keynr]; + KEY_PART_INFO* key_part = key_info->key_part; + KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; + my_bitmap_map* old_map = dbug_tmp_use_all_columns(table, table->write_set); memset((void *) key, 0, sizeof(*key)); key->data = buff; @@ -4439,11 +4498,16 @@ int ha_tokudb::prepare_index_scan() { TOKUDB_HANDLER_DBUG_RETURN(error); } -static bool index_key_is_null(TABLE *table, uint keynr, const uchar *key, uint key_len) { +static bool index_key_is_null( + TABLE* table, + uint keynr, + const uchar* key, + uint key_len) { + bool key_can_be_null = false; - KEY *key_info = &table->key_info[keynr]; - KEY_PART_INFO *key_part = key_info->key_part; - KEY_PART_INFO *end = key_part + get_key_parts(key_info); + KEY* key_info = &table->key_info[keynr]; + KEY_PART_INFO* key_part = key_info->key_part; + KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; for (; key_part != end; key_part++) { if (key_part->null_bit) { key_can_be_null = true; @@ -5979,11 +6043,7 @@ int ha_tokudb::info(uint flag) { #endif DB_TXN* txn = NULL; if (flag & HA_STATUS_VARIABLE) { - // Just to get optimizations right stats.records = share->row_count() + share->rows_from_locked_table; - if (stats.records == 0) { - stats.records++; - } stats.deleted = 0; if (!(flag & HA_STATUS_NO_LOCK)) { uint64_t num_rows = 0; @@ -6002,9 +6062,6 @@ int ha_tokudb::info(uint flag) { if (error == 0) { share->set_row_count(num_rows, false); stats.records = num_rows; - if (stats.records == 0) { - stats.records++; - } } else { goto cleanup; } @@ -6085,6 +6142,22 @@ int ha_tokudb::info(uint flag) { stats.delete_length += frag_info.unused_bytes; } } + + /* + The following comment and logic has been taken from InnoDB and + an old hack was removed that forced to always set stats.records > 0 + --- + The MySQL optimizer seems to assume in a left join that n_rows + is an accurate estimate if it is zero. Of course, it is not, + since we do not have any locks on the rows yet at this phase. + Since SHOW TABLE STATUS seems to call this function with the + HA_STATUS_TIME flag set, while the left join optimizer does not + set that flag, we add one to a zero value if the flag is not + set. That way SHOW TABLE STATUS will show the best estimate, + while the optimizer never sees the table empty. */ + if (stats.records == 0 && !(flag & HA_STATUS_TIME)) { + stats.records++; + } } if ((flag & HA_STATUS_CONST)) { stats.max_data_file_length = 9223372036854775807ULL; @@ -6785,9 +6858,9 @@ void ha_tokudb::trace_create_table_info(const char *name, TABLE * form) { "key:%d:%s:%d", i, key->name, - get_key_parts(key)); + key->user_defined_key_parts); uint p; - for (p = 0; p < get_key_parts(key); p++) { + for (p = 0; p < key->user_defined_key_parts; p++) { KEY_PART_INFO* key_part = &key->key_part[p]; Field* field = key_part->field; TOKUDB_HANDLER_TRACE( @@ -8565,6 +8638,10 @@ int ha_tokudb::delete_all_rows_internal() { uint curr_num_DBs = 0; DB_TXN* txn = NULL; + // this should be enough to handle locking as the higher level MDL + // on this table should prevent any new analyze tasks. + share->cancel_background_jobs(); + error = txn_begin(db_env, 0, &txn, 0, ha_thd()); if (error) { goto cleanup; @@ -8592,6 +8669,8 @@ int ha_tokudb::delete_all_rows_internal() { } } + DEBUG_SYNC(ha_thd(), "tokudb_after_truncate_all_dictionarys"); + // zap the row count if (error == 0) { share->set_row_count(0, false); diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h index 93658643c9a97..91b96425ce5d0 100644 --- a/storage/tokudb/ha_tokudb.h +++ b/storage/tokudb/ha_tokudb.h @@ -61,9 +61,9 @@ typedef struct loader_context { class TOKUDB_SHARE { public: enum share_state_t { - CLOSED, - OPENED, - ERROR + CLOSED = 0, + OPENED = 1, + ERROR = 2 }; // one time, start up init @@ -88,6 +88,9 @@ class TOKUDB_SHARE { // exactly 0 _use_count static void drop_share(TOKUDB_SHARE* share); + // returns state string for logging/reporting + static const char* get_state_string(share_state_t state); + void* operator new(size_t sz); void operator delete(void* p); @@ -306,7 +309,6 @@ class TOKUDB_SHARE { // cardinality counts uint32_t _rec_per_keys; uint64_t* _rec_per_key; - bool _card_changed; void init(const char* table_name); void destroy(); @@ -315,17 +317,34 @@ inline int TOKUDB_SHARE::use_count() const { return _use_count; } inline void TOKUDB_SHARE::lock() const { + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count); _mutex.lock(); + TOKUDB_SHARE_DBUG_VOID_RETURN(); } inline void TOKUDB_SHARE::unlock() const { + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count); _mutex.unlock(); + TOKUDB_SHARE_DBUG_VOID_RETURN(); } inline TOKUDB_SHARE::share_state_t TOKUDB_SHARE::state() const { return _state; } inline void TOKUDB_SHARE::set_state(TOKUDB_SHARE::share_state_t state) { + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]:new_state[%s]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count, + get_state_string(state)); + assert_debug(_mutex.is_owned_by_me()); _state = state; + TOKUDB_SHARE_DBUG_VOID_RETURN(); } inline const char* TOKUDB_SHARE::full_table_name() const { return _full_table_name.ptr(); @@ -346,6 +365,13 @@ inline uint TOKUDB_SHARE::table_name_length() const { return _table_name.length(); } inline void TOKUDB_SHARE::set_row_count(uint64_t rows, bool locked) { + TOKUDB_SHARE_DBUG_ENTER("file[%s]:state[%s]:use_count[%d]:rows[%" PRIu64 "]:locked[%d]", + _full_table_name.ptr(), + get_state_string(_state), + _use_count, + rows, + locked); + if (!locked) { lock(); } else { @@ -358,6 +384,7 @@ inline void TOKUDB_SHARE::set_row_count(uint64_t rows, bool locked) { if (!locked) { unlock(); } + TOKUDB_SHARE_DBUG_VOID_RETURN(); } inline ha_rows TOKUDB_SHARE::row_count() const { return _rows; @@ -371,7 +398,6 @@ inline void TOKUDB_SHARE::init_cardinality_counts( assert_always(_rec_per_key == NULL && _rec_per_keys == 0); _rec_per_keys = rec_per_keys; _rec_per_key = rec_per_key; - _card_changed = true; } inline void TOKUDB_SHARE::update_cardinality_counts( uint32_t rec_per_keys, @@ -382,7 +408,6 @@ inline void TOKUDB_SHARE::update_cardinality_counts( assert_always(rec_per_keys == _rec_per_keys); assert_always(rec_per_key != NULL); memcpy(_rec_per_key, rec_per_key, _rec_per_keys * sizeof(uint64_t)); - _card_changed = true; } inline void TOKUDB_SHARE::disallow_auto_analysis() { assert_debug(_mutex.is_owned_by_me()); diff --git a/storage/tokudb/ha_tokudb_admin.cc b/storage/tokudb/ha_tokudb_admin.cc index 7fa17945f1593..dad9da8eac605 100644 --- a/storage/tokudb/ha_tokudb_admin.cc +++ b/storage/tokudb/ha_tokudb_admin.cc @@ -374,6 +374,7 @@ void standard_t::on_run() { _local_txn = false; } + assert_always(_share->key_file[0] != NULL); _result = _share->key_file[0]->stat64(_share->key_file[0], _txn, &stat64); if (_result != 0) { _result = HA_ADMIN_FAILED; @@ -575,6 +576,7 @@ int standard_t::analyze_key_progress(void) { int standard_t::analyze_key(uint64_t* rec_per_key_part) { int error = 0; DB* db = _share->key_file[_current_key]; + assert_always(db != NULL); uint64_t num_key_parts = _share->_key_descriptors[_current_key]._parts; uint64_t unique_rows[num_key_parts]; bool is_unique = _share->_key_descriptors[_current_key]._is_unique; @@ -897,6 +899,7 @@ int ha_tokudb::do_optimize(THD* thd) { } DB* db = share->key_file[i]; + assert_always(db != NULL); error = db->optimize(db); if (error) { goto cleanup; @@ -1016,7 +1019,8 @@ int ha_tokudb::check(THD* thd, HA_CHECK_OPT* check_opt) { write_status_msg); } for (uint i = 0; i < num_DBs; i++) { - DB *db = share->key_file[i]; + DB* db = share->key_file[i]; + assert_always(db != NULL); const char* kname = i == primary_key ? "primary" : table_share->key_info[i].name; snprintf( diff --git a/storage/tokudb/ha_tokudb_alter_56.cc b/storage/tokudb/ha_tokudb_alter_56.cc index d7b3bcb802a20..e005d67895381 100644 --- a/storage/tokudb/ha_tokudb_alter_56.cc +++ b/storage/tokudb/ha_tokudb_alter_56.cc @@ -680,7 +680,7 @@ int ha_tokudb::alter_table_add_index( KEY *key = &key_info[i]; *key = ha_alter_info->key_info_buffer[ha_alter_info->index_add_buffer[i]]; for (KEY_PART_INFO* key_part = key->key_part; - key_part < key->key_part + get_key_parts(key); + key_part < key->key_part + key->user_defined_key_parts; key_part++) { key_part->field = table->field[key_part->fieldnr]; } @@ -1123,7 +1123,7 @@ int ha_tokudb::alter_table_expand_varchar_offsets( // Return true if a field is part of a key static bool field_in_key(KEY *key, Field *field) { - for (uint i = 0; i < get_key_parts(key); i++) { + for (uint i = 0; i < key->user_defined_key_parts; i++) { KEY_PART_INFO *key_part = &key->key_part[i]; if (strcmp(key_part->field->field_name, field->field_name) == 0) return true; diff --git a/storage/tokudb/ha_tokudb_alter_common.cc b/storage/tokudb/ha_tokudb_alter_common.cc index c58f57b4da78b..d41a676de1f31 100644 --- a/storage/tokudb/ha_tokudb_alter_common.cc +++ b/storage/tokudb/ha_tokudb_alter_common.cc @@ -75,8 +75,8 @@ static bool tables_have_same_keys( if (print_error) { sql_print_error( "keys disagree on if they are clustering, %d, %d", - get_key_parts(curr_orig_key), - get_key_parts(curr_altered_key)); + curr_orig_key->user_defined_key_parts, + curr_altered_key->user_defined_key_parts); } retval = false; goto cleanup; @@ -86,18 +86,19 @@ static bool tables_have_same_keys( if (print_error) { sql_print_error( "keys disagree on if they are unique, %d, %d", - get_key_parts(curr_orig_key), - get_key_parts(curr_altered_key)); + curr_orig_key->user_defined_key_parts, + curr_altered_key->user_defined_key_parts); } retval = false; goto cleanup; } - if (get_key_parts(curr_orig_key) != get_key_parts(curr_altered_key)) { + if (curr_orig_key->user_defined_key_parts != + curr_altered_key->user_defined_key_parts) { if (print_error) { sql_print_error( "keys have different number of parts, %d, %d", - get_key_parts(curr_orig_key), - get_key_parts(curr_altered_key)); + curr_orig_key->user_defined_key_parts, + curr_altered_key->user_defined_key_parts); } retval = false; goto cleanup; @@ -105,7 +106,7 @@ static bool tables_have_same_keys( // // now verify that each field in the key is the same // - for (uint32_t j = 0; j < get_key_parts(curr_orig_key); j++) { + for (uint32_t j = 0; j < curr_orig_key->user_defined_key_parts; j++) { KEY_PART_INFO* curr_orig_part = &curr_orig_key->key_part[j]; KEY_PART_INFO* curr_altered_part = &curr_altered_key->key_part[j]; Field* curr_orig_field = curr_orig_part->field; diff --git a/storage/tokudb/ha_tokudb_update.cc b/storage/tokudb/ha_tokudb_update.cc index fabd1a82d0c78..23de81f3d8af1 100644 --- a/storage/tokudb/ha_tokudb_update.cc +++ b/storage/tokudb/ha_tokudb_update.cc @@ -453,7 +453,7 @@ static bool check_all_update_expressions( static bool full_field_in_key(TABLE* table, Field* field) { assert_always(table->s->primary_key < table->s->keys); KEY* key = &table->s->key_info[table->s->primary_key]; - for (uint i = 0; i < get_key_parts(key); i++) { + for (uint i = 0; i < key->user_defined_key_parts; i++) { KEY_PART_INFO* key_part = &key->key_part[i]; if (strcmp(field->field_name, key_part->field->field_name) == 0) { return key_part->length == field->field_length; @@ -519,7 +519,7 @@ static bool check_point_update(Item* conds, TABLE* table) { if (bitmap_init(&pk_fields, NULL, table->s->fields, FALSE)) // 1 -> failure return false; KEY *key = &table->s->key_info[table->s->primary_key]; - for (uint i = 0; i < get_key_parts(key); i++) + for (uint i = 0; i < key->user_defined_key_parts; i++) bitmap_set_bit(&pk_fields, key->key_part[i].field->field_index); switch (conds->type()) { diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc index a5e0874505a18..d400c3f7bd3a4 100644 --- a/storage/tokudb/hatoku_cmp.cc +++ b/storage/tokudb/hatoku_cmp.cc @@ -1010,7 +1010,7 @@ static int create_toku_key_descriptor_for_key(KEY* key, uchar* buf) { uchar* pos = buf; uint32_t num_bytes_in_field = 0; uint32_t charset_num = 0; - for (uint i = 0; i < get_key_parts(key); i++){ + for (uint i = 0; i < key->user_defined_key_parts; i++) { Field* field = key->key_part[i].field; // // The first byte states if there is a null byte @@ -1881,7 +1881,7 @@ static uint32_t pack_desc_pk_offset_info( bool is_constant_offset = true; uint32_t offset = 0; - for (uint i = 0; i < get_key_parts(prim_key); i++) { + for (uint i = 0; i < prim_key->user_defined_key_parts; i++) { KEY_PART_INFO curr = prim_key->key_part[i]; uint16 curr_field_index = curr.field->field_index; @@ -2503,8 +2503,8 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( // // store number of parts // - assert_always(get_key_parts(prim_key) < 128); - pos[0] = 2 * get_key_parts(prim_key); + assert_always(prim_key->user_defined_key_parts < 128); + pos[0] = 2 * prim_key->user_defined_key_parts; pos++; // // for each part, store if it is a fixed field or var field @@ -2514,7 +2514,7 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( // pk_info = pos; uchar* tmp = pos; - for (uint i = 0; i < get_key_parts(prim_key); i++) { + for (uint i = 0; i < prim_key->user_defined_key_parts; i++) { tmp += pack_desc_pk_info( tmp, kc_info, @@ -2525,11 +2525,11 @@ static uint32_t create_toku_secondary_key_pack_descriptor ( // // asserting that we moved forward as much as we think we have // - assert_always(tmp - pos == (2 * get_key_parts(prim_key))); + assert_always(tmp - pos == (2 * prim_key->user_defined_key_parts)); pos = tmp; } - for (uint i = 0; i < get_key_parts(key_info); i++) { + for (uint i = 0; i < key_info->user_defined_key_parts; i++) { KEY_PART_INFO curr_kpi = key_info->key_part[i]; uint16 field_index = curr_kpi.field->field_index; Field* field = table_share->field[field_index]; diff --git a/storage/tokudb/hatoku_defines.h b/storage/tokudb/hatoku_defines.h index 27b4493c804ed..174a885d36fb0 100644 --- a/storage/tokudb/hatoku_defines.h +++ b/storage/tokudb/hatoku_defines.h @@ -36,10 +36,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #include "sql_class.h" #include "sql_show.h" #include "discover.h" - -#if (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) #include -#endif +#include "debug_sync.h" #undef PACKAGE #undef VERSION diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 086280a76dfdb..67151fa67df10 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -674,6 +674,7 @@ int tokudb_end(handlerton* hton, ha_panic_function type) { // count the total number of prepared txn's that we discard long total_prepared = 0; #if TOKU_INCLUDE_XA + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "begin XA cleanup"); while (1) { // get xid's const long n_xid = 1; @@ -698,6 +699,7 @@ int tokudb_end(handlerton* hton, ha_panic_function type) { } total_prepared += n_prepared; } + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "end XA cleanup"); #endif error = db_env->close( db_env, @@ -922,19 +924,25 @@ static int tokudb_rollback(handlerton * hton, THD * thd, bool all) { #if TOKU_INCLUDE_XA static bool tokudb_sync_on_prepare(void) { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter"); // skip sync of log if fsync log period > 0 - if (tokudb::sysvars::fsync_log_period > 0) + if (tokudb::sysvars::fsync_log_period > 0) { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit"); return false; - else + } else { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit"); return true; + } } static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) { TOKUDB_DBUG_ENTER(""); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter"); int r = 0; // if tokudb_support_xa is disable, just return if (!tokudb::sysvars::support_xa(thd)) { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit %d", r); TOKUDB_DBUG_RETURN(r); } @@ -944,7 +952,7 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) { if (txn) { uint32_t syncflag = tokudb_sync_on_prepare() ? 0 : DB_TXN_NOSYNC; TOKUDB_TRACE_FOR_FLAGS( - TOKUDB_DEBUG_TXN, + TOKUDB_DEBUG_XA, "doing txn prepare:%d:%p", all, txn); @@ -957,15 +965,18 @@ static int tokudb_xa_prepare(handlerton* hton, THD* thd, bool all) { // test hook to induce a crash on a debug build DBUG_EXECUTE_IF("tokudb_crash_prepare_after", DBUG_SUICIDE();); } else { - TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_TXN, "nothing to prepare %d", all); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "nothing to prepare %d", all); } + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit %d", r); TOKUDB_DBUG_RETURN(r); } static int tokudb_xa_recover(handlerton* hton, XID* xid_list, uint len) { TOKUDB_DBUG_ENTER(""); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter"); int r = 0; if (len == 0 || xid_list == NULL) { + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit %d", 0); TOKUDB_DBUG_RETURN(0); } long num_returned = 0; @@ -976,11 +987,13 @@ static int tokudb_xa_recover(handlerton* hton, XID* xid_list, uint len) { &num_returned, DB_NEXT); assert_always(r == 0); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit %ld", num_returned); TOKUDB_DBUG_RETURN((int)num_returned); } static int tokudb_commit_by_xid(handlerton* hton, XID* xid) { TOKUDB_DBUG_ENTER(""); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter"); int r = 0; DB_TXN* txn = NULL; TOKU_XA_XID* toku_xid = (TOKU_XA_XID*)xid; @@ -993,11 +1006,13 @@ static int tokudb_commit_by_xid(handlerton* hton, XID* xid) { r = 0; cleanup: + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit %d", r); TOKUDB_DBUG_RETURN(r); } static int tokudb_rollback_by_xid(handlerton* hton, XID* xid) { TOKUDB_DBUG_ENTER(""); + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "enter"); int r = 0; DB_TXN* txn = NULL; TOKU_XA_XID* toku_xid = (TOKU_XA_XID*)xid; @@ -1010,6 +1025,7 @@ static int tokudb_rollback_by_xid(handlerton* hton, XID* xid) { r = 0; cleanup: + TOKUDB_TRACE_FOR_FLAGS(TOKUDB_DEBUG_XA, "exit %d", r); TOKUDB_DBUG_RETURN(r); } diff --git a/storage/tokudb/hatoku_hton.h b/storage/tokudb/hatoku_hton.h index 37c61be849d0c..ade7be128a506 100644 --- a/storage/tokudb/hatoku_hton.h +++ b/storage/tokudb/hatoku_hton.h @@ -199,14 +199,4 @@ void tokudb_pretty_left_key(const DB* db, const DBT* key, String* out); void tokudb_pretty_right_key(const DB* db, const DBT* key, String* out); const char *tokudb_get_index_name(DB* db); -inline uint get_key_parts(const KEY *key) { -#if (50609 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) || \ - (50700 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50799) || \ - (100009 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 100099) - return key->user_defined_key_parts; -#else - return key->key_parts; -#endif -} - #endif //#ifdef _HATOKU_HTON diff --git a/storage/tokudb/mysql-test/tokudb/r/background_job_manager.result b/storage/tokudb/mysql-test/tokudb/r/background_job_manager.result index c66872d7b0f088068bc403113e9c87abd416d33f..5282f0ec9ae9075ede6471fe396ad75a9973bede 100644 GIT binary patch delta 102 zcmaEBddqafefG@{*jF-5?&4~lEWq75`2&CJcp_info[keynr] == NULL in tokudb/ha_tokudb.cc initialize_col_pack_info +--error ER_TABLE_EXISTS_ERROR +create table t1(c1 binary (1), c2 varbinary(1)); +unlock tables; +drop table t1; +set @@global.table_open_cache = @orig_table_open_cache; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test new file mode 100644 index 0000000000000..f1912faad0260 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test @@ -0,0 +1,76 @@ +# This test for DB-938 tests a race condition where a scheduled background job +# (analyze) ends up operating on a set of DB* key_file[] in TOKUDB_SHARE that +# were set to NULL during a TRUNCATE TABLE operation. + +-- source include/have_tokudb.inc +-- source include/have_debug.inc +-- source include/have_debug_sync.inc + +-- enable_query_log + +set @orig_auto_analyze = @@session.tokudb_auto_analyze; +set @orig_in_background = @@session.tokudb_analyze_in_background; +set @orig_mode = @@session.tokudb_analyze_mode; +set @orig_throttle = @@session.tokudb_analyze_throttle; +set @orig_time = @@session.tokudb_analyze_time; +set @orig_scale_percent = @@global.tokudb_cardinality_scale_percent; +set @orig_default_storage_engine = @@session.default_storage_engine; +set @orig_pause_background_job_manager = @@global.tokudb_debug_pause_background_job_manager; + +# first, lets set up to auto analyze in the background with about any activity +set session default_storage_engine = 'tokudb'; +set session tokudb_auto_analyze = 1; +set session tokudb_analyze_in_background = 1; +set session tokudb_analyze_mode = tokudb_analyze_standard; +set session tokudb_analyze_throttle = 0; +set session tokudb_analyze_time = 0; +set global tokudb_cardinality_scale_percent = DEFAULT; + +# in debug build, we can prevent the background job manager from running, +# let's do it to hold a job from running until we get the TRUNCATE TABLE +# in action +set global tokudb_debug_pause_background_job_manager = TRUE; + +create table t1 (a int not null auto_increment, b int, c int, primary key(a), key kb(b), key kc(c), key kabc(a,b,c), key kab(a,b), key kbc(b,c)); + +insert into t1(b,c) values(0,0), (1,1), (2,2), (3,3); + +# insert above should have triggered an analyze, but since the bjm is paused, +# we will see it sitting in the queue +select database_name, table_name, job_type, job_params, scheduler from information_schema.tokudb_background_job_status; + +# lets flip to another connection +connect(conn1, localhost, root); + +# set up the DEBUG_SYNC point +set DEBUG_SYNC = 'tokudb_after_truncate_all_dictionarys SIGNAL closed WAIT_FOR done'; + +# send the truncat table +send TRUNCATE TABLE t1; + +# back to default connection +connection default; + +# release the bjm +set global tokudb_debug_pause_background_job_manager = FALSE; + +# if the bug is present, the bjm should crash here within 1/4 of a second +sleep 5; + +# lets release and clean up +set DEBUG_SYNC = 'now SIGNAL done'; + +connection conn1; +reap; +connection default; +disconnect conn1; +drop table t1; + +set session tokudb_auto_analyze = @orig_auto_analyze; +set session tokudb_analyze_in_background = @orig_in_background; +set session tokudb_analyze_mode = @orig_mode; +set session tokudb_analyze_throttle = @orig_throttle; +set session tokudb_analyze_time = @orig_time; +set global tokudb_cardinality_scale_percent = @orig_scale_percent; +set session default_storage_engine = @orig_default_storage_engine; +set global tokudb_debug_pause_background_job_manager = @orig_pause_background_job_manager; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/xa-3.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-3.test index 4bca18ad1090a..806684f3accb1 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/xa-3.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-3.test @@ -1,6 +1,12 @@ -- source include/have_innodb.inc -- source include/have_tokudb.inc -- source include/have_debug.inc +# Valgrind would report memory leaks on the intentional crashes +-- source include/not_valgrind.inc +# Embedded server does not support crashing +-- source include/not_embedded.inc +# Avoid CrashReporter popup on Mac +-- source include/not_crashrep.inc --disable_warnings drop table if exists t1, t2; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/xa-4.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-4.test index 5e4071c7b931d..cb7ef4d1495cb 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/xa-4.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-4.test @@ -1,6 +1,12 @@ -- source include/have_innodb.inc -- source include/have_tokudb.inc -- source include/have_debug.inc +# Valgrind would report memory leaks on the intentional crashes +-- source include/not_valgrind.inc +# Embedded server does not support crashing +-- source include/not_embedded.inc +# Avoid CrashReporter popup on Mac +-- source include/not_crashrep.inc --disable_warnings drop table if exists t1, t2; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/xa-6.test b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-6.test index b6f770f0a68ec..5ce94c88f6c67 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/xa-6.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/xa-6.test @@ -1,5 +1,11 @@ --source include/have_tokudb.inc --source include/have_debug.inc +# Valgrind would report memory leaks on the intentional crashes +-- source include/not_valgrind.inc +# Embedded server does not support crashing +-- source include/not_embedded.inc +# Avoid CrashReporter popup on Mac +-- source include/not_crashrep.inc --disable_warnings drop table if exists t1; diff --git a/storage/tokudb/tokudb_card.h b/storage/tokudb/tokudb_card.h index fdf18d4ab129f..f649c2d887fa9 100644 --- a/storage/tokudb/tokudb_card.h +++ b/storage/tokudb/tokudb_card.h @@ -27,7 +27,7 @@ namespace tokudb { uint compute_total_key_parts(TABLE_SHARE *table_share) { uint total_key_parts = 0; for (uint i = 0; i < table_share->keys; i++) { - total_key_parts += get_key_parts(&table_share->key_info[i]); + total_key_parts += table_share->key_info[i].user_defined_key_parts; } return total_key_parts; } @@ -156,13 +156,14 @@ namespace tokudb { uint orig_key_parts = 0; for (uint i = 0; i < table_share->keys; i++) { orig_key_offset[i] = orig_key_parts; - orig_key_parts += get_key_parts(&table_share->key_info[i]); + orig_key_parts += table_share->key_info[i].user_defined_key_parts; } // if orig card data exists, then use it to compute new card data if (error == 0) { uint next_key_parts = 0; for (uint i = 0; error == 0 && i < altered_table_share->keys; i++) { - uint ith_key_parts = get_key_parts(&altered_table_share->key_info[i]); + uint ith_key_parts = + altered_table_share->key_info[i].user_defined_key_parts; uint orig_key_index; if (find_index_of_key( altered_table_share->key_info[i].name, diff --git a/storage/tokudb/tokudb_debug.h b/storage/tokudb/tokudb_debug.h index db66cab050cbf..46bd65c605a28 100644 --- a/storage/tokudb/tokudb_debug.h +++ b/storage/tokudb/tokudb_debug.h @@ -50,6 +50,8 @@ static void tokudb_backtrace(void); #define TOKUDB_DEBUG_UPSERT (1<<12) #define TOKUDB_DEBUG_CHECK (1<<13) #define TOKUDB_DEBUG_ANALYZE (1<<14) +#define TOKUDB_DEBUG_XA (1<<15) +#define TOKUDB_DEBUG_SHARE (1<<16) #define TOKUDB_TRACE(_fmt, ...) { \ fprintf(stderr, "%u %s:%u %s " _fmt "\n", tokudb::thread::my_tid(), \ @@ -124,7 +126,6 @@ static void tokudb_backtrace(void); DBUG_RETURN(r); \ } - #define TOKUDB_HANDLER_DBUG_VOID_RETURN { \ if (TOKUDB_UNLIKELY(tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN)) { \ TOKUDB_HANDLER_TRACE("return"); \ @@ -132,6 +133,61 @@ static void tokudb_backtrace(void); DBUG_VOID_RETURN; \ } +#define TOKUDB_SHARE_TRACE(_fmt, ...) \ + fprintf(stderr, "%u %p %s:%u TOUDB_SHARE::%s " _fmt "\n", \ + tokudb::thread::my_tid(), this, __FILE__, __LINE__, \ + __FUNCTION__, ##__VA_ARGS__); + +#define TOKUDB_SHARE_TRACE_FOR_FLAGS(_flags, _fmt, ...) { \ + if (TOKUDB_UNLIKELY(TOKUDB_DEBUG_FLAGS(_flags))) { \ + TOKUDB_SHARE_TRACE(_fmt, ##__VA_ARGS__); \ + } \ +} + +#define TOKUDB_SHARE_DBUG_ENTER(_fmt, ...) { \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_ENTER) || \ + (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ + TOKUDB_SHARE_TRACE(_fmt, ##__VA_ARGS__); \ + } \ +} \ + DBUG_ENTER(__FUNCTION__); + +#define TOKUDB_SHARE_DBUG_RETURN(r) { \ + int rr = (r); \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ + (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE) || \ + (rr != 0 && (tokudb::sysvars::debug & TOKUDB_DEBUG_ERROR)))) { \ + TOKUDB_SHARE_TRACE("return %d", rr); \ + } \ + DBUG_RETURN(rr); \ +} + +#define TOKUDB_SHARE_DBUG_RETURN_DOUBLE(r) { \ + double rr = (r); \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ + (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ + TOKUDB_SHARE_TRACE("return %f", rr); \ + } \ + DBUG_RETURN(rr); \ +} + +#define TOKUDB_SHARE_DBUG_RETURN_PTR(r) { \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ + (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ + TOKUDB_SHARE_TRACE("return 0x%p", r); \ + } \ + DBUG_RETURN(r); \ +} + +#define TOKUDB_SHARE_DBUG_VOID_RETURN() { \ + if (TOKUDB_UNLIKELY((tokudb::sysvars::debug & TOKUDB_DEBUG_RETURN) || \ + (tokudb::sysvars::debug & TOKUDB_DEBUG_SHARE))) { \ + TOKUDB_SHARE_TRACE("return"); \ + } \ + DBUG_VOID_RETURN; \ +} + + #define TOKUDB_DBUG_DUMP(s, p, len) \ { \ TOKUDB_TRACE("%s", s); \ diff --git a/storage/tokudb/tokudb_information_schema.cc b/storage/tokudb/tokudb_information_schema.cc index 7ea3b8abbdd54..1d4ca2e018132 100644 --- a/storage/tokudb/tokudb_information_schema.cc +++ b/storage/tokudb/tokudb_information_schema.cc @@ -1119,9 +1119,9 @@ void background_job_status_callback( table->field[3]->store(type, strlen(type), system_charset_info); table->field[4]->store(params, strlen(params), system_charset_info); if (user_scheduled) - table->field[5]->store("USER", sizeof("USER"), system_charset_info); + table->field[5]->store("USER", strlen("USER"), system_charset_info); else - table->field[5]->store("AUTO", sizeof("AUTO"), system_charset_info); + table->field[5]->store("AUTO", strlen("AUTO"), system_charset_info); field_store_time_t(table->field[6], scheduled_time); field_store_time_t(table->field[7], started_time); From 672bbcd7411b20e87eca7845aceed81f361d6424 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 27 Apr 2016 16:13:14 +0200 Subject: [PATCH 020/112] MDEV-9973 : Do not set permissions for serviceaccount user (Win7 and later) This appears to break some installation, and it did not do anything useful anyway. --- win/packaging/extra.wxs.in | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in index 48d15cbf91cc7..8ee2909511b96 100644 --- a/win/packaging/extra.wxs.in +++ b/win/packaging/extra.wxs.in @@ -542,17 +542,6 @@ Value="utf8" /> - - - 600)]]> - - - - - - From 6768f80c0b1f0b82c5addbe47ce712ded14d0d8c Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Fri, 29 Apr 2016 11:06:41 +0530 Subject: [PATCH 021/112] Bug#21973610 Post push fix : Fixing i_main.mysqlshow failure. --- client/mysqlshow.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/mysqlshow.c b/client/mysqlshow.c index 4d1df00c8fde8..f1f8bdaf54beb 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -655,7 +655,7 @@ list_table_status(MYSQL *mysql,const char *db,const char *wild) len= sizeof(query); len-= my_snprintf(query, len, "show table status from `%s`", db); if (wild && wild[0] && len) - strxnmov(query + strlen(query), len, " like '", wild, "'", NullS); + strxnmov(query + strlen(query), len - 1, " like '", wild, "'", NullS); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot get status for db: %s, table: %s: %s\n", @@ -688,7 +688,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, const char *wild) { char query[NAME_LEN + 100]; - int len; + size_t len; MYSQL_RES *result; MYSQL_ROW row; ulong UNINIT_VAR(rows); @@ -718,7 +718,7 @@ list_fields(MYSQL *mysql,const char *db,const char *table, len-= my_snprintf(query, len, "show /*!32332 FULL */ columns from `%s`", table); if (wild && wild[0] && len) - strxnmov(query + strlen(query), len, " like '", wild, "'", NullS); + strxnmov(query + strlen(query), len - 1, " like '", wild, "'", NullS); if (mysql_query(mysql,query) || !(result=mysql_store_result(mysql))) { fprintf(stderr,"%s: Cannot list columns in db: %s, table: %s: %s\n", From 964c4f070a7e96bf45979d8755beb10aa6e6617b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 10 May 2016 19:13:06 +0400 Subject: [PATCH 022/112] MDEV-10052 Illegal mix of collations with DAYNAME(date_field)<>varchar_field --- mysql-test/r/locale.result | 28 ++++++++++++++++++++++++++++ mysql-test/t/locale.test | 19 +++++++++++++++++++ sql/item_timefunc.cc | 6 ++---- sql/sql_locale.h | 2 ++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/locale.result b/mysql-test/r/locale.result index 195468c4c1241..6de1d0708cac0 100644 --- a/mysql-test/r/locale.result +++ b/mysql-test/r/locale.result @@ -101,3 +101,31 @@ Februar SELECT monthname('2001-03-01'); monthname('2001-03-01') März +# +# MDEV-10052 Illegal mix of collations with DAYNAME(date_field)<>varchar_field +# +SET NAMES utf8; +CREATE TABLE t1 (c VARCHAR(8) CHARACTER SET latin1, d DATE); +INSERT INTO t1 VALUES ('test',now()); +Warnings: +Note 1265 Data truncated for column 'd' at row 1 +SET lc_time_names=ru_RU; +SELECT c FROM t1 WHERE DAYNAME(d)<>c; +ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<>' +SELECT c FROM t1 WHERE MONTHNAME(d)<>c; +ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<>' +SET lc_time_names=en_US; +SELECT c FROM t1 WHERE DAYNAME(d)<>c; +c +test +SELECT c FROM t1 WHERE MONTHNAME(d)<>c; +c +test +SET NAMES latin1; +SELECT c FROM t1 WHERE DAYNAME(d)<>c; +c +test +SELECT c FROM t1 WHERE MONTHNAME(d)<>c; +c +test +DROP TABLE t1; diff --git a/mysql-test/t/locale.test b/mysql-test/t/locale.test index 899d293545d43..4944dc7a228e6 100644 --- a/mysql-test/t/locale.test +++ b/mysql-test/t/locale.test @@ -63,3 +63,22 @@ SET lc_time_names=de_AT; SELECT monthname('2001-01-01'); SELECT monthname('2001-02-01'); SELECT monthname('2001-03-01'); + +--echo # +--echo # MDEV-10052 Illegal mix of collations with DAYNAME(date_field)<>varchar_field +--echo # +SET NAMES utf8; +CREATE TABLE t1 (c VARCHAR(8) CHARACTER SET latin1, d DATE); +INSERT INTO t1 VALUES ('test',now()); +SET lc_time_names=ru_RU; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM t1 WHERE DAYNAME(d)<>c; +--error ER_CANT_AGGREGATE_2COLLATIONS +SELECT c FROM t1 WHERE MONTHNAME(d)<>c; +SET lc_time_names=en_US; +SELECT c FROM t1 WHERE DAYNAME(d)<>c; +SELECT c FROM t1 WHERE MONTHNAME(d)<>c; +SET NAMES latin1; +SELECT c FROM t1 WHERE DAYNAME(d)<>c; +SELECT c FROM t1 WHERE MONTHNAME(d)<>c; +DROP TABLE t1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 873dcdac4b981..28e93683422bf 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -935,9 +935,8 @@ void Item_func_monthname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; - uint32 repertoire= my_charset_repertoire(cs); locale= thd->variables.lc_time_names; - collation.set(cs, DERIVATION_COERCIBLE, repertoire); + collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_month_name_length * collation.collation->mbmaxlen; maybe_null=1; @@ -1082,9 +1081,8 @@ void Item_func_dayname::fix_length_and_dec() { THD* thd= current_thd; CHARSET_INFO *cs= thd->variables.collation_connection; - uint32 repertoire= my_charset_repertoire(cs); locale= thd->variables.lc_time_names; - collation.set(cs, DERIVATION_COERCIBLE, repertoire); + collation.set(cs, DERIVATION_COERCIBLE, locale->repertoire()); decimals=0; max_length= locale->max_day_name_length * collation.collation->mbmaxlen; maybe_null=1; diff --git a/sql/sql_locale.h b/sql/sql_locale.h index 8357a9ecba4a3..8559bb55cd9e1 100644 --- a/sql/sql_locale.h +++ b/sql/sql_locale.h @@ -61,6 +61,8 @@ class MY_LOCALE grouping(grouping_par), errmsgs(errmsgs_par) {} + uint repertoire() const + { return is_ascii ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_EXTENDED; } }; /* Exported variables */ From 5af076e564602559158db38a69a9cb4a09537986 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 12 May 2016 23:08:22 +0200 Subject: [PATCH 023/112] Add all changes made on 10.1 --- storage/connect/CMakeLists.txt | 28 +- storage/connect/JdbcInterface.class | Bin 0 -> 15117 bytes storage/connect/JdbcInterface.java | 639 ++++++++ storage/connect/ha_connect.cc | 282 ++-- storage/connect/inihandl.c | 7 +- storage/connect/jdbccat.h | 29 + storage/connect/jdbconn.cpp | 2151 +++++++++++++++++++++++++++ storage/connect/jdbconn.h | 171 +++ storage/connect/jsonudf.cpp | 155 +- storage/connect/jsonudf.h | 4 + storage/connect/plgdbutl.cpp | 34 +- storage/connect/reldef.cpp | 7 +- storage/connect/tabjdbc.cpp | 1707 +++++++++++++++++++++ storage/connect/tabjdbc.h | 343 +++++ 14 files changed, 5398 insertions(+), 159 deletions(-) create mode 100644 storage/connect/JdbcInterface.class create mode 100644 storage/connect/JdbcInterface.java create mode 100644 storage/connect/jdbccat.h create mode 100644 storage/connect/jdbconn.cpp create mode 100644 storage/connect/jdbconn.h create mode 100644 storage/connect/tabjdbc.cpp create mode 100644 storage/connect/tabjdbc.h diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index 7ff2ca7753c09..fa2fb7b4ddd90 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -257,6 +257,32 @@ int main() { ENDIF(UNIX) ENDIF(CONNECT_WITH_ODBC) +# +# JDBC +# + +OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) + +IF(CONNECT_WITH_JDBC) + # TODO: detect Java SDK and the presence of JDBC connectors + # TODO: Find how to compile and install the JdbcInterface.java class + # Find required libraries and include directories + + FIND_PACKAGE(Java) + FIND_PACKAGE(JNI) + IF (JAVA_FOUND AND JNI_FOUND) + INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH}) + INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH2}) + # SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) + SET(CONNECT_SOURCES ${CONNECT_SOURCES} + JdbcInterface.java JdbcInterface.class + jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) + add_definitions(-DJDBC_SUPPORT) + ELSE() + SET(JDBC_LIBRARY "") + ENDIF() +ENDIF(CONNECT_WITH_JDBC) + # # XMAP @@ -277,5 +303,5 @@ MYSQL_ADD_PLUGIN(connect ${CONNECT_SOURCES} COMPONENT connect-engine RECOMPILE_FOR_EMBEDDED LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY} - ${ODBC_LIBRARY} ${IPHLPAPI_LIBRARY}) + ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY}) diff --git a/storage/connect/JdbcInterface.class b/storage/connect/JdbcInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..816f575212b2313bbde48e6b8831a0267f8ffef7 GIT binary patch literal 15117 zcmbta3w%_?)jwx;lih4?LP&rRLST7>ym*O-LI4p$Ff<8BAS&Qv*(|WQ*^Rp!9#-3G zwOVaUZLw8rwNjND z7mF~JwkE=%SZ631m1n!ro8A}&M?+fsiL^059vUMP4lBUaL5uPzU+%_RzE2<5nJ#~BWu?fS!u0xq?6J3hQ^lF zbu9&S6dmoO8U3`{u`LBzTQrl70rW&KG+}EqnwYj6W7C)+66$XB(XkLl#vIJV3wxun zu1L~PvzaPd;=z7!=LEZw(an+Mya3IjMu9ySv)2yhuC7xk=38_;EnvzI_4GvI(Abn* zq=QD=EI_uiXrV=msENs+P8j}R6t#7OhJd!2PV^D1xJ)DJkJX|U;nde7@MCd5eTvBf zxO8$`a9u1BJ}W?Nw9H5C{Uxa-ZP9W%31g$F#oayWZQ7hx`>BH|ur3%)VUFI&xB#u9 zlYJ!Slo9BnSSXdU=oC5?!`CO0?V)a1SM^88K#ywl(;8UlsuivC{B#;BO`v|r&!u8Z9t(&$`JhUN_w5W@)TG56`I^)4iZ8=sSEX~0!w#Wwr1mR+X zthAA-F2~HdNBL7SgBb zJRhBlfZ?jZC9>!<^jTOFxN~FEN{rLy(;}9AzBtDPh+?(Qs#)&sxPYH71gpVtA|CEd zCL{6iHhbYOSah*0P@cU2MCy?F>5K5prpWpbqGoV?Bpu!uOhwOe_`b}dFUfEV!<(hE z1APMMD;901uc9NB)giI6rLNOYUxOUlBU}2mP(KX`w0j=Rw3Rdl>Ynh5WPHGKiX7tl{m*cj?1u4|c>8q z&YHtz4a15c)9_hsp&p$$eY6i6TcmwW(tL+54RWT8)#9FySoA1823hu)n!t4^rs;N*SQ=k!Y-{eo$fYfgh!vglXzB+Laq z<0L7LLekJs0L!2NGi&5Ygwa#}&Z6Jb)5we%f^N{F=(2>RjfrH2y2DWa$)e}!4@iQt zfDnMb!$4RV-GG$lPQTO)c+sN2(O-~tFrYON-vIihX8z__B9tL-Hsr5b^bdN)%&!SR zzaD?hW{svqFX|w7jV3eb-xj?|uN%~c0wcQc2k$BYl9kbJiRIlrW+0+##+2MXn7K&! zU5oxpZ=0y&_F*aj&8i~Z9#~o7;;oTzZ#p8nkQqL-=%6@fQN*;b>ghss$Md3CBBiOs z@<7STVh;_2mxQGU#wis}Q#6GbD|N1)^ReinP&^!o#ZYJkfx*9 z8TD)6gjg)7K|tz-OOOUbTRTIsUSN`N-BQS-d5n*%5QSXR9hed=9xGBCCLuPobx|VL z+Z|7}#I@_n_;D7G7XnE$LVyB4me?SLOlu^*A-z#(CR$uAG$Ra6M|fkTJJg?~#^PEb z8E#1Q^!+L7EpEt~#Bh=!fi1vC152cs(L9R7<_LZU^>mAmVpPSFIb8bFbA*q<9)Bb) zSw(`Y)J9SHOw=Tds(Va!)OSgoDg~s+@@yX;mmO0EQCU1kM_mM; zK3n>YbPT65<0^|g`D8>FNXO-03@E1}{fu&bh@lf-4sHykf_`2Db3z>^##fuF!(=vW z&5@r^hfA9l!Km2?YKUiA9Fi@aW%H`(u>;JZokOq#?=H_k4W@d-VU#NCdt)&mEwb4# zlJYY`{m2X-y*dhJvlB&}msmtdtOsS=g!s$c}4s=i_hmppkE)2cNtz}-p^ZnA&-KEf6PMOI*47FQ#Tu?!e1<%_A9 z4vV)*@ZN9n1N=jy2dB!C?5;Z>l+GU?BJiRN3+Q6*u!}UyA`e@T8YmF0g^5Hg5{e&o6&*32viRo`F(fP7gJkhvqFHi40cw+oJ39i?3xMl7D)AZgzO2aX72@y|IAW{ zgFR^+$ev61q7eS=BiYmRK7KiyJu`2yTy(i@^H}#0B6R6BqyMn@HU6iGL~f4`URg=W z?a)JBmmzO_WG2fD^6{I%?~2v!fJH2U_VnQuc1-2D>N=FOIBVj!Eq;gJH74W^aQE1~ z>1b@);&^X&BpK4@)d7Bw5BT_fSg&4I6Cl{f%y~9a*a!R}!ZwbZkm9D=rZH$5TLilO zgk&EIDGmuXWagG_a$!fvj2u%&ORH-U6Zmf6pI3RFp9KEnPTEtnU z8g8i(attDdDVe%Z6|0e!su0G9psg*mDUs}qBqbr?Y*bZRYP6&SAJR>4WZ8PZ8iN{c zstgNSYMeVP8h3|D-vmodlp>;NlRnSx?ukW1@w8t}0>V=xDZi>k?rKkn9JWIBK6AQ^ zyAl&PwaB%!ku^*w>a0vPYHR@UbVUCndt`E52E(BSOf+}U;Q1IH=t%S?!*FkX{NL}$ zd#Wgx#u0eLixnUKaKevYx%cZUPWSZ{XZ!k!lYM=~xxT*QR3F!gm;rAI@H-q&GfCl& zD8Jr&4~@73cZw?T8^D$D9v}~6M&ZsfR8&c$@gy^hv}d>oltMeD{vN8T_uNfm>-laP zCqEP9r&@k$Ecj;0*qH8}@YJ%3QsZ^R*nC5-7^5g+?t(LjGnYkMBFt`Q3dkKRV80tyR%4>yM z`sS6Mj-Q77%)olgf-W@eqcb79T~s7Z`)IugQUjRiOcTX4Xd1Vd&XTEO86?u$NAO|@ zzUnHfsF#MJp4WzYUhku{2hG*HXoTJRkE~X+!VG7Ht!9PlK01eKFMY1`^H>8kXt+o> zWJ_+GGwKp|)TLQOqpzZ0%Fxk$^kqe6p$DBIm**U^i>{lKcPD*atLqyesmR+)SGq90 zv%I_LJfWCg`faFY7oFnFcb!dqy-V!$++_EBZ&1(o?Veiz)ZmikZkv-=k@v{K@8`*4 zC3-PwzB7N8cer;q9B@3}#rNOL`fg z>G8CHCeVp+!ey}PPO7Ci)zf*@Ko`Qocfp45ffe72@js;*^fNk|Uc(9fe`z*-Kyz5$ za!sQ7JO#Ug#dx1}Dz0m3A%|%ZpHGYVBD{9mPA&WmTFQ6f9a0}H<6qNqaCj0wM=SWR zw2EJ%PI&9dY80KKX3}cah#U4Y!clXdf_?Wcy zflEw;yZhjO9z^{Px*u&`tXf46&<`mOYi^_;(SwwSnG4bOWBBDyAemWIdH^CTt{QV( zX+h1T(qks}`sk{Vk9Hm)3%~Ev%7YMGo{!i^4>2+uu6Iia`YAnZe4L)ZnqJH`*)va@ zbVDEQSI|JsE*jMiy-$Ig!Z!#9%De= z4T?BIZUTDhfu2%YDl>rs>pD`w-Q&;{@&_m+7AcG_(6~JqTcB}!H13h)If%tQ8dsY} zwX+q-f6B$xTD|F(>b|;A3t+M+?)??F2MYs2RC2% zNN%3h#&k$-o})h;ikm+k5jU5Do6Eq>m%z>TBjDzR!^!5)^cS0(3m{;zg$k{yU?2U} z3r!Wx@xuNpyfDB+>FVp?X9o=J3Z%I!v-qiSbyeZ&s)C-Sm%vX6oKalJt4+z)l~~Tp z^h!?YOzfk-ACYvf0XN@|2&*@{zb3nlum6Qy>W!nxe@%_1iZT- zotv}x$t|6?=>HBUo&V6=Ii&-?dgq9wa~rtX1L@oj>HHvzo7~cQkKR9=bPmvGZEhX~ znG|wIm3%N)%x6E<%B7D!V4Ay&D%)T~lVL&%55>+y$%k_*C5QzOV#*Q3hx2dElBc`^diG+0n3J{)D+oCnEA{1E4McKA{l5zscLw9O5d z@KsI<0U{H-r-Let{JG>nv-Tc0RG{OWg@+m1aeX{u0IgrISdM;3)eD@JGzL?LDvG;wfbpWyM1G&gKqpa!l}tKSnA>T)(!G;{B1ry&fS9q&z#5bh1@aR(Q+}Yx z3La&Q6fe${&Ws7qyvmy~`V9O@R+Laa4u4be*NDFp@wW;RpU}sZOsFM}HxEJmFvC1d z&=1w-0ozHCjWiE+`oYcHs6M1dSVs}pu;<7IjZraxrHNcfQ`w@UxR@Gw2&%lHbRw7H z1EFE4+J@69T#k=yDrr5B#`h^>vy41pi;hsI7zb9Mn5DdYeavhc59p~>_- zg{K;^&@-TwimDS8l{Q>UF4|tD!kU0xk-Jan<7s(-QD+FNr5}_>%icpgzM+q2DD?TAob-oT{zBCAi%_>W(Q00TPpwX* z4g4uB2UB}SU5!UwIc%`y;Kj#QCm;cMVAg&u5mPV>A@2uR0`>HeE#e!H%0eunPXTxx z6fdgZp;eFlau5+jHehAkgbh*ywoPT+>~5YQrfR78L`CzfuEwTc_J)iv*#_H<-n$;} zPS);Dwj7gex9d0VAg0v<1 zZ$>IH(pxF6W4lu*w_!=5fNB=G(mVyyM4NFo$g+%AyDIvq3PRDTv=$PTYt)sf2}ox_ zqH&mH4~^inX#yu{3a4o%_u~7(ZTJZA9O~jvQHPS)jkfV|}kc!3?vd*G_(NLN^r z;4;RrB-Kb=WgjOM?RLs-kHd=`2|ER#;pJiQ@(5Drqg2L^fuF}|G(V+z37T15a~p$z zAkJOpI=7T!*qE-cS=!87Y?gM|EXfw9;Sm}Fk(BXP)TeSFi6*djj-uNg_MkSIwn|s6 zraB#ii3x{UKK>1r@NdD~(=>*kp|Sis=;paB25VggYwdDqEXGP{U}BD+JY`G4q0|NE zA$A#|?YB*S$zTqTsl1wsMTnF8__K;63=6{-K%V0KCQV)hL!YvjFE(e0TGM6NY)x^c zYpR{+0pJAy_%i_fh01XvH=h57@cI&Jzn5`>_o@bB4sMpXK$h4*2Vuo9*Z^g! zodWWf6$_?vV7d&E#9(^C#zDP%N7)hvWhYN3_c(=h+Wmm4|%$;p=#? zZ$(i~(9?=4mG9DBoO-jy{{qg}f%6Sm(wk7yTQr&f4`1^Chno3qoJPKbAonhO_Wdlp zYh1i*T)b=e8wh-gR@f>u$rd(N`We6l+A9$c4cfavCP8a9_^fkm>}qXeHI>&=i8KS_ zHA;40@&I*SHxNr1ivMXY7Grb=$)|`)6iiYnnueEZ)0LNwRlY3VXS=-5c6py|>uP#G z-is)&tfa+9Z3}E0-09ljokxb?yV(eCvaL{#J8i2Qgg_MnfdvFbKu`<>Lx7+J2+IB^ z1ce%b4m{#R-$U><8hFv>zj?3*W@c&N=4}3NQ`A0XKLy}BcOYCA-0GNC!L69J4EwOT zt~$o+!+OY z88zYDwvVNg=bp>A%ILuef}`VgoM;v>}9ec6bAq-c)=vUraMIap&80kRq( zCjn#)K-NNIbhdv(vKh5UxO7>L~C(1NmuE+cedF*4w ztlwnw|GOiIS$N;#Q!U_sDfs^s_-_UOZQy_T|HQu?v-mkj1ApW{eLMuuXCwIQksw$J z1gn6c69`TQf>VItR3KRUi4eTxAb5rU{_zmJnvLLJM}pu?AP51$Iv@xGK^G82fMDY% zLhx?~!COeE+KR9{$dky3-TVA~{GWaN-#OmV72ZBR$h1#+XXSZjbPc66jh7O)piEWo zqI|?CrvtC0J1)%U;rYY!u0Obac;0UC6IRMo2ntX59v zAxYm0sf@yTfxPp|#|zfAYO 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + System.out.println(se); + } //end try/catch + + return null; + } // end of TimestampField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + +} // end of class JdbcInterface diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 2055b93927ffe..58a761f442d93 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -21,8 +21,8 @@ based on external data. Principally they are based on plain files of many different types, but also on collections of such files, collection of tables, local or remote MySQL/MariaDB tables retrieved via MySQL API, - ODBC tables retrieving data from other DBMS having an ODBC server, and even - virtual tables. + ODBC/JDBC tables retrieving data from other DBMS having an ODBC/JDBC server, + and even virtual tables. @details ha_connect will let you create/open/delete tables, the created table can be @@ -115,9 +115,6 @@ #include "sql_parse.h" #include "sql_base.h" #include -#if defined(NEW_WAY) -#include "sql_table.h" -#endif // NEW_WAY #include "sql_partition.h" #undef OFFSET @@ -130,6 +127,10 @@ #if defined(ODBC_SUPPORT) #include "odbccat.h" #endif // ODBC_SUPPORT +#if defined(JDBC_SUPPORT) +#include "jdbccat.h" +#include "jdbconn.h" +#endif // JDBC_SUPPORT #include "xtable.h" #include "tabmysql.h" #include "filamdbf.h" @@ -169,7 +170,7 @@ #define JSONMAX 10 // JSON Default max grp size extern "C" { - char version[]= "Version 1.04.0006 March 12, 2016"; + char version[]= "Version 1.04.0006 May 08, 2016"; #if defined(__WIN__) char compver[]= "Version 1.04.0006 " __DATE__ " " __TIME__; char slash= '\\'; @@ -190,6 +191,17 @@ extern "C" { } // extern "C" #endif // XMSG +#if defined(JDBC_SUPPORT) + char *JvmPath; + char *ClassPath; +#endif // JDBC_SUPPORT + +#if defined(__WIN__) +CRITICAL_SECTION parsec; // Used calling the Flex parser +#else // !__WIN__ +pthread_mutex_t parmut = PTHREAD_MUTEX_INITIALIZER; +#endif // !__WIN__ + /***********************************************************************/ /* Utility functions. */ /***********************************************************************/ @@ -197,6 +209,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); PQRYRES VirColumns(PGLOBAL g, bool info); PQRYRES JSONColumns(PGLOBAL g, char *db, PTOS topt, bool info); PQRYRES XMLColumns(PGLOBAL g, char *db, char *tab, PTOS topt, bool info); +int TranslateJDBCType(int stp, int prec, int& len, char& v); void PushWarning(PGLOBAL g, THD *thd, int level); bool CheckSelf(PGLOBAL g, TABLE_SHARE *s, const char *host, const char *db, char *tab, const char *src, int port); @@ -633,6 +646,7 @@ static int connect_init_func(void *p) #if defined(__WIN__) sql_print_information("CONNECT: %s", compver); + InitializeCriticalSection((LPCRITICAL_SECTION)&parsec); #else // !__WIN__ sql_print_information("CONNECT: %s", version); #endif // !__WIN__ @@ -659,6 +673,9 @@ static int connect_init_func(void *p) DTVAL::SetTimeShift(); // Initialize time zone shift once for all BINCOL::SetEndian(); // Initialize host endian setting +#if defined(JDBC_SUPPORT) + JDBConn::SetJVM(); +#endif // JDBC_SUPPORT DBUG_RETURN(0); } // end of connect_init_func @@ -675,11 +692,17 @@ static int connect_done_func(void *) #ifdef LIBXML2_SUPPORT XmlCleanupParserLib(); -#endif // LIBXML2_SUPPORT +#endif // LIBXML2_SUPPORT + +#ifdef JDBC_SUPPORT + JDBConn::ResetJVM(); +#endif // JDBC_SUPPORT -#if !defined(__WIN__) -//PROFILE_End(); Causes signal 11 -#endif // !__WIN__ +#if defined(__WIN__) + DeleteCriticalSection((LPCRITICAL_SECTION)&parsec); +#else // !__WIN__ + PROFILE_End(); +#endif // !__WIN__ for (pc= user_connect::to_users; pc; pc= pn) { if (pc->g) @@ -1758,9 +1781,10 @@ int ha_connect::OpenTable(PGLOBAL g, bool del) break; } // endswitch xmode - if (xmod != MODE_INSERT || tdbp->GetAmType() == TYPE_AM_ODBC - || tdbp->GetAmType() == TYPE_AM_MYSQL) { - // Get the list of used fields (columns) + if (xmod != MODE_INSERT || tdbp->GetAmType() == TYPE_AM_MYSQL + || tdbp->GetAmType() == TYPE_AM_ODBC + || tdbp->GetAmType() == TYPE_AM_JDBC) { + // Get the list of used fields (columns) char *p; unsigned int k1, k2, n1, n2; Field* *field; @@ -2077,8 +2101,9 @@ int ha_connect::ScanRecord(PGLOBAL g, uchar *) continue; // Is a virtual column possible here ??? if ((xmod == MODE_INSERT && tdbp->GetAmType() != TYPE_AM_MYSQL - && tdbp->GetAmType() != TYPE_AM_ODBC) || - bitmap_is_set(table->write_set, fp->field_index)) { + && tdbp->GetAmType() != TYPE_AM_ODBC + && tdbp->GetAmType() != TYPE_AM_JDBC) || + bitmap_is_set(table->write_set, fp->field_index)) { for (colp= tp->GetSetCols(); colp; colp= colp->GetNext()) if (!stricmp(colp->GetName(), fp->field_name)) break; @@ -2627,7 +2652,7 @@ PFIL ha_connect::CondFilter(PGLOBAL g, Item *cond) } // end of CondFilter /***********************************************************************/ -/* Check the WHERE condition and return a MYSQL/ODBC/WQL filter. */ +/* Check the WHERE condition and return a MYSQL/ODBC/JDBC/WQL filter. */ /***********************************************************************/ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) { @@ -2635,8 +2660,8 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond) char *body= filp->Body; unsigned int i; bool ismul= false, x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC); - bool nonul= (tty == TYPE_AM_ODBC && (tdbp->GetMode() == MODE_INSERT || - tdbp->GetMode() == MODE_DELETE)); + bool nonul= ((tty == TYPE_AM_ODBC || tty == TYPE_AM_JDBC) && + (tdbp->GetMode() == MODE_INSERT || tdbp->GetMode() == MODE_DELETE)); OPVAL vop= OP_XX; if (!cond) @@ -2958,7 +2983,7 @@ const COND *ha_connect::cond_push(const COND *cond) bool x= (tty == TYPE_AM_MYX || tty == TYPE_AM_XDBC); bool b= (tty == TYPE_AM_WMI || tty == TYPE_AM_ODBC || tty == TYPE_AM_TBL || tty == TYPE_AM_MYSQL || - tty == TYPE_AM_PLG || x); + tty == TYPE_AM_PLG || tty == TYPE_AM_JDBC || x); // Save stack and allocation environment and prepare error return if (g->jump_level == MAX_JUMP) { @@ -4108,7 +4133,8 @@ bool ha_connect::check_privileges(THD *thd, PTOS options, char *dbn) /* Fall through to check FILE_ACL */ case TAB_ODBC: - case TAB_MYSQL: + case TAB_JDBC: + case TAB_MYSQL: case TAB_DIR: case TAB_MAC: case TAB_WMI: @@ -5124,11 +5150,17 @@ static int connect_assisted_discovery(handlerton *, THD* thd, int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0; int cop __attribute__((unused))= 0, lrecl= 0; #if defined(ODBC_SUPPORT) - POPARM sop = NULL; - char *ucnc = NULL; + POPARM sop= NULL; + char *ucnc= NULL; bool cnc= false; int cto= -1, qto= -1; #endif // ODBC_SUPPORT +#if defined(JDBC_SUPPORT) + PJPARM sjp= NULL; + char *driver= NULL; + char *url= NULL; + char *tabtyp = NULL; +#endif // JDBC_SUPPORT uint tm, fnc= FNC_NO, supfnc= (FNC_NO | FNC_COL); bool bif, ok= false, dbf= false; TABTYPE ttp= TAB_UNDEF; @@ -5139,15 +5171,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, PDBUSER dup= PlgGetUser(g); PCATLG cat= (dup) ? dup->Catalog : NULL; PTOS topt= table_s->option_struct; -#if defined(NEW_WAY) -//CHARSET_INFO *cs; - Alter_info alter_info; -#else // !NEW_WAY char buf[1024]; String sql(buf, sizeof(buf), system_charset_info); sql.copy(STRING_WITH_LEN("CREATE TABLE whatever ("), system_charset_info); -#endif // !NEW_WAY if (!g) return HA_ERR_INTERNAL_ERROR; @@ -5166,7 +5193,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, spc= (!sep) ? ',' : *sep; qch= topt->qchar ? *topt->qchar : (signed)topt->quoted >= 0 ? '"' : 0; hdr= (int)topt->header; - tbl= topt->tablist; + tbl= topt->tablist; col= topt->colist; if (topt->oplist) { @@ -5195,6 +5222,11 @@ static int connect_assisted_discovery(handlerton *, THD* thd, if ((ucnc= GetListOption(g, "UseDSN", topt->oplist))) cnc= (!*ucnc || *ucnc == 'y' || *ucnc == 'Y' || atoi(ucnc) != 0); #endif +#if defined(JDBC_SUPPORT) + driver= GetListOption(g, "Driver", topt->oplist, NULL); + url= GetListOption(g, "URL", topt->oplist, NULL); + tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL); +#endif // JDBC_SUPPORT mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0")); #if defined(PROMPT_OK) cop= atoi(GetListOption(g, "checkdsn", topt->oplist, "0")); @@ -5255,44 +5287,62 @@ static int connect_assisted_discovery(handlerton *, THD* thd, } else if (ttp != TAB_ODBC || !(fnc & (FNC_TABLE | FNC_COL))) tab= table_s->table_name.str; // Default value -#if defined(NEW_WAY) -// add_option(thd, create_info, "tabname", tab); -#endif // NEW_WAY } // endif tab - switch (ttp) { + switch (ttp) { #if defined(ODBC_SUPPORT) - case TAB_ODBC: - dsn= strz(g, create_info->connect_string); + case TAB_ODBC: + dsn= strz(g, create_info->connect_string); - if (fnc & (FNC_DSN | FNC_DRIVER)) { - ok= true; + if (fnc & (FNC_DSN | FNC_DRIVER)) { + ok= true; #if defined(PROMPT_OK) - } else if (!stricmp(thd->main_security_ctx.host, "localhost") - && cop == 1) { - if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) { - thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn)); - ok= true; - } // endif dsn + } else if (!stricmp(thd->main_security_ctx.host, "localhost") + && cop == 1) { + if ((dsn = ODBCCheckConnection(g, dsn, cop)) != NULL) { + thd->make_lex_string(&create_info->connect_string, dsn, strlen(dsn)); + ok= true; + } // endif dsn #endif // PROMPT_OK - } else if (!dsn) { - sprintf(g->Message, "Missing %s connection string", topt->type); - } else { - // Store ODBC additional parameters - sop= (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM)); - sop->User= (char*)user; - sop->Pwd= (char*)pwd; - sop->Cto= cto; - sop->Qto= qto; - sop->UseCnc= cnc; - ok= true; - } // endif's - - supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER); - break; + } else if (!dsn) { + sprintf(g->Message, "Missing %s connection string", topt->type); + } else { + // Store ODBC additional parameters + sop= (POPARM)PlugSubAlloc(g, NULL, sizeof(ODBCPARM)); + sop->User= (char*)user; + sop->Pwd= (char*)pwd; + sop->Cto= cto; + sop->Qto= qto; + sop->UseCnc= cnc; + ok= true; + } // endif's + + supfnc |= (FNC_TABLE | FNC_DSN | FNC_DRIVER); + break; #endif // ODBC_SUPPORT - case TAB_DBF: +#if defined(JDBC_SUPPORT) + case TAB_JDBC: + if (fnc & FNC_DRIVER) { + ok= true; + } else if (!url && !(url= strz(g, create_info->connect_string))) { + strcpy(g->Message, "Missing URL"); + } else { + // Store ODBC additional parameters + sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM)); + sjp->Driver= driver; + sjp->Url= url; + sjp->User= (char*)user; + sjp->Pwd= (char*)pwd; + sjp->Fsize= 0; + sjp->Scrollable= false; + ok= true; + } // endif's + + supfnc |= (FNC_DRIVER | FNC_TABLE); + break; +#endif // JDBC_SUPPORT + case TAB_DBF: dbf= true; // Passthru case TAB_CSV: @@ -5411,7 +5461,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, dpath= SetPath(g, table_s->db.str); - if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC) { + if (src && ttp != TAB_PIVOT && ttp != TAB_ODBC && ttp != TAB_JDBC) { qrp= SrcColumns(g, host, db, user, pwd, src, port); if (qrp && ttp == TAB_OCCUR) @@ -5453,7 +5503,37 @@ static int connect_assisted_discovery(handlerton *, THD* thd, break; #endif // ODBC_SUPPORT - case TAB_MYSQL: +#if defined(JDBC_SUPPORT) + case TAB_JDBC: + switch (fnc) { + case FNC_NO: + case FNC_COL: + if (src) { + qrp= JDBCSrcCols(g, (char*)src, sjp); + src= NULL; // for next tests + } else + qrp= JDBCColumns(g, shm, tab, NULL, mxr, fnc == FNC_COL, sjp); + + break; + case FNC_TABLE: + qrp= JDBCTables(g, shm, tab, tabtyp, mxr, true, sjp); + break; +#if 0 + case FNC_DSN: + qrp= JDBCDataSources(g, mxr, true); + break; +#endif // 0 + case FNC_DRIVER: + qrp= JDBCDrivers(g, mxr, true); + break; + default: + sprintf(g->Message, "invalid catfunc %s", fncn); + break; + } // endswitch info + + break; +#endif // JDBC_SUPPORT + case TAB_MYSQL: qrp= MyColumns(g, thd, host, db, user, pwd, tab, NULL, port, fnc == FNC_COL); break; @@ -5526,14 +5606,9 @@ static int connect_assisted_discovery(handlerton *, THD* thd, len= 256; // STRBLK's have 0 length // Now add the field -#if defined(NEW_WAY) - rc= add_fields(g, thd, &alter_info, cnm, typ, len, dec, - tm, "", flg, dbf, v); -#else // !NEW_WAY if (add_field(&sql, cnm, typ, len, dec, NULL, tm, NULL, NULL, NULL, NULL, flg, dbf, v)) rc= HA_ERR_OUT_OF_MEM; -#endif // !NEW_WAY } // endfor crp } else { @@ -5556,12 +5631,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, cnm= (char*)"noname"; dft= xtra= key= fmt= NULL; v= ' '; -#if defined(NEW_WAY) - rem= ""; -// cs= NULL; -#else // !NEW_WAY rem= NULL; -#endif // !NEW_WAY for (crp= qrp->Colresp; crp; crp= crp->Next) switch (crp->Fld) { @@ -5630,10 +5700,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, "Several %s tables found, specify DBNAME", tab); my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); goto err; - } else if (!schem) + } else if (!schem) schem= crp->Kdata->GetCharValue(i); - } // endif ttp + } // endif ttp #endif // ODBC_SUPPORT default: break; // Ignore @@ -5682,7 +5752,42 @@ static int connect_assisted_discovery(handlerton *, THD* thd, } else #endif // ODBC_SUPPORT - // Make the arguments as required by add_fields +#if defined(JDBC_SUPPORT) + if (ttp == TAB_JDBC) { + int plgtyp; + + // typ must be PLG type, not SQL type + if (!(plgtyp= TranslateJDBCType(typ, dec, prec, v))) { + if (GetTypeConv() == TPC_SKIP) { + // Skip this column + sprintf(g->Message, "Column %s skipped (unsupported type %d)", + cnm, typ); + push_warning(thd, Sql_condition::WARN_LEVEL_WARN, 0, g->Message); + continue; + } else { + sprintf(g->Message, "Unsupported SQL type %d", typ); + my_message(ER_UNKNOWN_ERROR, g->Message, MYF(0)); + goto err; + } // endif type_conv + + } else + typ= plgtyp; + + switch (typ) { + case TYPE_DOUBLE: + // Some data sources do not count dec in length (prec) + prec += (dec + 2); // To be safe + break; + case TYPE_DECIM: + prec= len; + break; + default: + dec= 0; + } // endswitch typ + + } else +#endif // ODBC_SUPPORT + // Make the arguments as required by add_fields if (typ == TYPE_DOUBLE) prec= len; @@ -5690,25 +5795,15 @@ static int connect_assisted_discovery(handlerton *, THD* thd, prec= 0; // Now add the field -#if defined(NEW_WAY) - rc= add_fields(g, thd, &alter_info, cnm, typ, prec, dec, - tm, rem, 0, dbf, v); -#else // !NEW_WAY if (add_field(&sql, cnm, typ, prec, dec, key, tm, rem, dft, xtra, fmt, 0, dbf, v)) rc= HA_ERR_OUT_OF_MEM; -#endif // !NEW_WAY } // endfor i } // endif fnc -#if defined(NEW_WAY) - rc= init_table_share(thd, table_s, create_info, &alter_info); -#else // !NEW_WAY if (!rc) rc= init_table_share(thd, table_s, create_info, &sql); -// rc= init_table_share(thd, table_s, create_info, dsn, &sql); -#endif // !NEW_WAY g->jump_level--; return rc; @@ -6750,6 +6845,21 @@ static MYSQL_SYSVAR_STR(errmsg_dir_path, msg_path, "../../../../storage/connect/"); // for testing #endif // XMSG +#if defined(JDBC_SUPPORT) +static MYSQL_SYSVAR_STR(jvm_path, JvmPath, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Path to the directory where is the JVM lib", + // check_jvm_path, update_jvm_path, + NULL, NULL, NULL); + +static MYSQL_SYSVAR_STR(class_path, ClassPath, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Java class path", + // check_class_path, update_class_path, + NULL, NULL, NULL); +#endif // JDBC_SUPPORT + + static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(xtrace), MYSQL_SYSVAR(conv_size), @@ -6767,7 +6877,11 @@ static struct st_mysql_sys_var* connect_system_variables[]= { MYSQL_SYSVAR(errmsg_dir_path), #endif // XMSG MYSQL_SYSVAR(json_grp_size), - NULL +#if defined(JDBC_SUPPORT) + MYSQL_SYSVAR(jvm_path), + MYSQL_SYSVAR(class_path), +#endif // JDBC_SUPPORT + NULL }; maria_declare_plugin(connect) diff --git a/storage/connect/inihandl.c b/storage/connect/inihandl.c index 542b807f8997a..46102557b2088 100644 --- a/storage/connect/inihandl.c +++ b/storage/connect/inihandl.c @@ -622,13 +622,16 @@ void PROFILE_End(void) if (trace) htrc("PROFILE_End: CurProfile=%p N=%d\n", CurProfile, N_CACHED_PROFILES); + if (!CurProfile) // Sergey Vojtovich + return; + /* Close all opened files and free the cache structure */ for (i = 0; i < N_CACHED_PROFILES; i++) { if (trace) htrc("MRU=%s i=%d\n", SVP(MRUProfile[i]->filename), i); - CurProfile = MRUProfile[i]; - PROFILE_ReleaseFile(); +// CurProfile = MRUProfile[i]; Sergey Vojtovich +// PROFILE_ReleaseFile(); see MDEV-9997 free(MRUProfile[i]); } // endfor i diff --git a/storage/connect/jdbccat.h b/storage/connect/jdbccat.h new file mode 100644 index 0000000000000..37f33d7063d8b --- /dev/null +++ b/storage/connect/jdbccat.h @@ -0,0 +1,29 @@ +// Timeout and net wait defaults +#define DEFAULT_LOGIN_TIMEOUT -1 // means do not set +#define DEFAULT_QUERY_TIMEOUT -1 // means do not set + +typedef struct jdbc_parms { + int CheckSize(int rows); + char *Driver; // JDBC driver + char *Url; // Driver URL + char *User; // User connect info + char *Pwd; // Password connect info +//int Cto; // Connect timeout +//int Qto; // Query timeout + int Fsize; // Fetch size + bool Scrollable; // Scrollable cursor +} JDBCPARM, *PJPARM; + +/***********************************************************************/ +/* JDBC catalog function prototypes. */ +/***********************************************************************/ +#if defined(PROMPT_OK) +char *JDBCCheckConnection(PGLOBAL g, char *dsn, int cop); +#endif // PROMPT_OK +//PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info); +PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, + char *colpat, int maxres, bool info, PJPARM sop); +PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sop); +PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, + char *tabtyp, int maxres, bool info, PJPARM sop); +PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info); diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp new file mode 100644 index 0000000000000..88557fdd420d3 --- /dev/null +++ b/storage/connect/jdbconn.cpp @@ -0,0 +1,2151 @@ +/************ Jdbconn C++ Functions Source Code File (.CPP) ************/ +/* Name: JDBCONN.CPP Version 1.0 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* */ +/* This file contains the JDBC connection classes functions. */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant MariaDB header file. */ +/***********************************************************************/ +#include +#include +#if defined(__WIN__) +//nclude +//nclude +#include // for getcwd +#if defined(__BORLANDC__) +#define __MFC_COMPAT__ // To define min/max as macro +#endif // __BORLANDC__ +//#include +#else // !__WIN__ +#if defined(UNIX) +#include +#else // !UNIX +//nclude +#endif // !UNIX +#include +#include // for getenv +//nclude +#define NODW +#endif // !__WIN__ + +/***********************************************************************/ +/* Required objects includes. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "xobject.h" +#include "xtable.h" +#include "jdbccat.h" +#include "tabjdbc.h" +//#include "jdbconn.h" +//#include "plgcnx.h" // For DB types +#include "resource.h" +#include "valblk.h" +#include "osutil.h" + + +#if defined(__WIN__) +extern "C" HINSTANCE s_hModule; // Saved module handle +#else // !__WIN__ +#define nullptr 0 +#endif // !__WIN__ + +int GetConvSize(); +extern char *JvmPath; // The connect_jvm_path global variable value +extern char *ClassPath; // The connect_class_path global variable value + +/***********************************************************************/ +/* Static JDBConn objects. */ +/***********************************************************************/ +void *JDBConn::LibJvm = NULL; +CRTJVM JDBConn::CreateJavaVM = NULL; +GETJVM JDBConn::GetCreatedJavaVMs = NULL; + +/***********************************************************************/ +/* Some macro's (should be defined elsewhere to be more accessible) */ +/***********************************************************************/ +#if defined(_DEBUG) +#define ASSERT(f) assert(f) +#define DEBUG_ONLY(f) (f) +#else // !_DEBUG +#define ASSERT(f) ((void)0) +#define DEBUG_ONLY(f) ((void)0) +#endif // !_DEBUG + +// To avoid gcc warning +int TranslateJDBCType(int stp, int prec, int& len, char& v); + +/***********************************************************************/ +/* GetJDBCType: returns the SQL_TYPE corresponding to a PLG type. */ +/***********************************************************************/ +static short GetJDBCType(int type) +{ + short tp = 0; // NULL + + switch (type) { + case TYPE_STRING: tp = 12; break; // VARCHAR + case TYPE_SHORT: tp = 5; break; // SMALLINT + case TYPE_INT: tp = 4; break; // INTEGER + case TYPE_DATE: tp = 93; break; // DATE +//case TYPE_TIME: tp = 92; break; // TIME +//case TYPE_TIMESTAMP: tp = 93; break; // TIMESTAMP + case TYPE_BIGINT: tp = -5; break; // BIGINT + case TYPE_DOUBLE: tp = 8; break; // DOUBLE + case TYPE_TINY: tp = -6; break; // TINYINT + case TYPE_DECIM: tp = 3; break; // DECIMAL + } // endswitch type + + return tp; +} // end of GetJDBCType + +/***********************************************************************/ +/* TranslateJDBCType: translate a JDBC Type to a PLG type. */ +/***********************************************************************/ +int TranslateJDBCType(int stp, int prec, int& len, char& v) +{ + int type; + + switch (stp) { + case -1: // LONGVARCHAR + len = MY_MIN(abs(len), GetConvSize()); + case 12: // VARCHAR + v = 'V'; + case 1: // CHAR + type = TYPE_STRING; + break; + case 2: // NUMERIC + case 3: // DECIMAL + type = TYPE_DECIM; + break; + case 4: // INTEGER + type = TYPE_INT; + break; + case 5: // SMALLINT + type = TYPE_SHORT; + break; + case -6: // TINYINT + case -7: // BIT + type = TYPE_TINY; + break; + case 6: // FLOAT + case 7: // REAL + case 8: // DOUBLE + type = TYPE_DOUBLE; + break; + case 93: // TIMESTAMP + type = TYPE_DATE; + len = 19 + ((prec) ? (prec+1) : 0); + v = 'S'; + break; + case 91: // TYPE_DATE + type = TYPE_DATE; + len = 10; + v = 'D'; + break; + case 92: // TYPE_TIME + type = TYPE_DATE; + len = 8 + ((prec) ? (prec+1) : 0); + v = 'T'; + break; + case -5: // BIGINT + type = TYPE_BIGINT; + break; + case 0: // NULL + case -2: // BINARY + case -3: // VARBINARY + case -4: // LONGVARBINARY + default: + type = TYPE_ERROR; + len = 0; + } // endswitch type + + return type; +} // end of TranslateJDBCType + +/***********************************************************************/ +/* Allocate the structure used to refer to the result set. */ +/***********************************************************************/ +static JCATPARM *AllocCatInfo(PGLOBAL g, JCATINFO fid, char *db, + char *tab, PQRYRES qrp) +{ +//size_t m, n; + JCATPARM *cap; + +#if defined(_DEBUG) + assert(qrp); +#endif + + // Save stack and allocation environment and prepare error return + if (g->jump_level == MAX_JUMP) { + strcpy(g->Message, MSG(TOO_MANY_JUMPS)); + return NULL; + } // endif jump_level + + if (setjmp(g->jumper[++g->jump_level]) != 0) { + printf("%s\n", g->Message); + cap = NULL; + goto fin; + } // endif rc + +//m = (size_t)qrp->Maxres; +//n = (size_t)qrp->Nbcol; + cap = (JCATPARM *)PlugSubAlloc(g, NULL, sizeof(JCATPARM)); + memset(cap, 0, sizeof(JCATPARM)); + cap->Id = fid; + cap->Qrp = qrp; + cap->DB = (PUCHAR)db; + cap->Tab = (PUCHAR)tab; +//cap->Vlen = (SQLLEN* *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN *)); + +//for (i = 0; i < n; i++) +// cap->Vlen[i] = (SQLLEN *)PlugSubAlloc(g, NULL, m * sizeof(SQLLEN)); + +//cap->Status = (UWORD *)PlugSubAlloc(g, NULL, m * sizeof(UWORD)); + +fin: + g->jump_level--; + return cap; +} // end of AllocCatInfo + +/***********************************************************************/ +/* JDBCColumns: constructs the result blocks containing all columns */ +/* of a JDBC table that will be retrieved by GetData commands. */ +/***********************************************************************/ +PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, + int maxres, bool info, PJPARM sjp) +{ + int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING, + TYPE_SHORT, TYPE_STRING, TYPE_INT, TYPE_INT, + TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_STRING}; + XFLD fldtyp[] = {FLD_CAT, FLD_SCHEM, FLD_TABNAME, FLD_NAME, + FLD_TYPE, FLD_TYPENAME, FLD_PREC, FLD_LENGTH, + FLD_SCALE, FLD_RADIX, FLD_NULL, FLD_REM}; + unsigned int length[] = {0, 0, 0, 0, 6, 0, 10, 10, 6, 6, 6, 0}; + bool b[] = {true, true, false, false, false, false, false, false, true, true, false, true}; + int i, n, ncol = 12; + PCOLRES crp; + PQRYRES qrp; + JCATPARM *cap; + JDBConn *jcp = NULL; + + /************************************************************************/ + /* Do an evaluation of the result size. */ + /************************************************************************/ + if (!info) { + jcp = new(g)JDBConn(g, NULL); + + if (jcp->Open(sjp) != RC_OK) // openReadOnly + noJDBCdialog + return NULL; + + if (table && !strchr(table, '%')) { + // We fix a MySQL limit because some data sources return 32767 + n = jcp->GetMaxValue(1); // MAX_COLUMNS_IN_TABLE) + maxres = (n > 0) ? MY_MIN(n, 4096) : 4096; + } else if (!maxres) + maxres = 20000; + + // n = jcp->GetMaxValue(2); MAX_CATALOG_NAME_LEN + // length[0] = (n) ? (n + 1) : 0; + // n = jcp->GetMaxValue(3); MAX_SCHEMA_NAME_LEN + // length[1] = (n) ? (n + 1) : 0; + // n = jcp->GetMaxValue(4); MAX_TABLE_NAME_LEN + // length[2] = (n) ? (n + 1) : 0; + n = jcp->GetMaxValue(5); // MAX_COLUMN_NAME_LEN + length[3] = (n > 0) ? (n + 1) : 128; + } else { // Info table + maxres = 0; + length[0] = 128; + length[1] = 128; + length[2] = 128; + length[3] = 128; + length[5] = 30; + length[11] = 255; + } // endif jcp + + if (trace) + htrc("JDBCColumns: max=%d len=%d,%d,%d,%d\n", + maxres, length[0], length[1], length[2], length[3]); + + /************************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /************************************************************************/ + qrp = PlgAllocResult(g, ncol, maxres, IDS_COLUMNS, + buftyp, fldtyp, length, false, true); + + for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) + if (b[i]) + crp->Kdata->SetNullable(true); + + if (info || !qrp) // Info table + return qrp; + + if (trace) + htrc("Getting col results ncol=%d\n", qrp->Nbcol); + + if (!(cap = AllocCatInfo(g, CAT_COL, db, table, qrp))) + return NULL; + + cap->Pat = (PUCHAR)colpat; + + /************************************************************************/ + /* Now get the results into blocks. */ + /************************************************************************/ + if ((n = jcp->GetCatInfo(cap)) >= 0) { + qrp->Nblin = n; + // ResetNullValues(cap); + + if (trace) + htrc("Columns: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin); + + } else + qrp = NULL; + + /* Cleanup */ + jcp->Close(); + + /************************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /************************************************************************/ + return qrp; +} // end of JDBCColumns + +/**************************************************************************/ +/* JDBCSrcCols: constructs the result blocks containing the */ +/* description of all the columns of a Srcdef option. */ +/**************************************************************************/ +PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp) +{ + JDBConn *jcp = new(g)JDBConn(g, NULL); + + if (jcp->Open(sjp)) + return NULL; + + return jcp->GetMetaData(g, src); +} // end of JDBCSrcCols + +/**************************************************************************/ +/* JDBCTables: constructs the result blocks containing all tables in */ +/* an JDBC database that will be retrieved by GetData commands. */ +/**************************************************************************/ +PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, + int maxres, bool info, PJPARM sjp) +{ + int buftyp[] = {TYPE_STRING, TYPE_STRING, TYPE_STRING, + TYPE_STRING, TYPE_STRING}; + XFLD fldtyp[] = {FLD_CAT, FLD_SCHEM, FLD_NAME, FLD_TYPE, FLD_REM}; + unsigned int length[] = {0, 0, 0, 16, 0}; + bool b[] = {true, true, false, false, true}; + int i, n, ncol = 5; + PCOLRES crp; + PQRYRES qrp; + JCATPARM *cap; + JDBConn *jcp = NULL; + + /************************************************************************/ + /* Do an evaluation of the result size. */ + /************************************************************************/ + if (!info) { + /**********************************************************************/ + /* Open the connection with the JDBC data source. */ + /**********************************************************************/ + jcp = new(g)JDBConn(g, NULL); + + if (jcp->Open(sjp) == RC_FX) + return NULL; + + if (!maxres) + maxres = 10000; // This is completely arbitrary + + n = jcp->GetMaxValue(2); // Max catalog name length + + if (n < 0) + return NULL; + + length[0] = (n) ? (n + 1) : 0; + n = jcp->GetMaxValue(3); // Max schema name length + length[1] = (n) ? (n + 1) : 0; + n = jcp->GetMaxValue(4); // Max table name length + length[2] = (n) ? (n + 1) : 128; + } else { + maxres = 0; + length[0] = 128; + length[1] = 128; + length[2] = 128; + length[4] = 255; + } // endif info + + if (trace) + htrc("JDBCTables: max=%d len=%d,%d\n", maxres, length[0], length[1]); + + /************************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /************************************************************************/ + qrp = PlgAllocResult(g, ncol, maxres, IDS_TABLES, buftyp, + fldtyp, length, false, true); + + for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) + if (b[i]) + crp->Kdata->SetNullable(true); + + if (info || !qrp) + return qrp; + + if (!(cap = AllocCatInfo(g, CAT_TAB, db, tabpat, qrp))) + return NULL; + + cap->Pat = (PUCHAR)tabtyp; + + if (trace) + htrc("Getting table results ncol=%d\n", cap->Qrp->Nbcol); + + /************************************************************************/ + /* Now get the results into blocks. */ + /************************************************************************/ + if ((n = jcp->GetCatInfo(cap)) >= 0) { + qrp->Nblin = n; + // ResetNullValues(cap); + + if (trace) + htrc("Tables: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin); + + } else + qrp = NULL; + + /************************************************************************/ + /* Close any local connection. */ + /************************************************************************/ + jcp->Close(); + + /************************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /************************************************************************/ + return qrp; +} // end of JDBCTables + +/*************************************************************************/ +/* JDBCDrivers: constructs the result blocks containing all JDBC */ +/* drivers available on the local host. */ +/* Called with info=true to have result column names. */ +/*************************************************************************/ +PQRYRES JDBCDrivers(PGLOBAL g, int maxres, bool info) +{ + int buftyp[] ={TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_STRING}; + XFLD fldtyp[] ={FLD_NAME, FLD_EXTRA, FLD_DEFAULT, FLD_REM }; + unsigned int length[] ={ 128, 32, 4, 256 }; + bool b[] ={ false, false, false, true }; + int i, ncol = 4; + PCOLRES crp; + PQRYRES qrp; + JDBConn *jcp = NULL; + + /************************************************************************/ + /* Do an evaluation of the result size. */ + /************************************************************************/ + if (!info) { + jcp = new(g) JDBConn(g, NULL); + + if (jcp->Open(NULL) != RC_OK) + return NULL; + + if (!maxres) + maxres = 256; // Estimated max number of drivers + + } else + maxres = 0; + + if (trace) + htrc("JDBCDrivers: max=%d len=%d\n", maxres, length[0]); + + /************************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /************************************************************************/ + qrp = PlgAllocResult(g, ncol, maxres, 0, buftyp, fldtyp, length, false, true); + + for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) { + if (b[i]) + crp->Kdata->SetNullable(true); + + switch (i) { + case 0: crp->Name = "Name"; break; + case 1: crp->Name = "Version"; break; + case 2: crp->Name = "Compliant"; break; + case 3: crp->Name = "Description"; break; + } // endswitch + + } // endfor i + + /************************************************************************/ + /* Now get the results into blocks. */ + /************************************************************************/ + if (!info && qrp && jcp->GetDrivers(qrp)) + qrp = NULL; + + if (!info) + jcp->Close(); + + /************************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /************************************************************************/ + return qrp; +} // end of JDBCDrivers + +#if 0 +/*************************************************************************/ +/* JDBCDataSources: constructs the result blocks containing all JDBC */ +/* data sources available on the local host. */ +/* Called with info=true to have result column names. */ +/*************************************************************************/ +PQRYRES JDBCDataSources(PGLOBAL g, int maxres, bool info) +{ + int buftyp[] ={ TYPE_STRING, TYPE_STRING }; + XFLD fldtyp[] ={ FLD_NAME, FLD_REM }; + unsigned int length[] ={ 0, 256 }; + bool b[] ={ false, true }; + int i, n = 0, ncol = 2; + PCOLRES crp; + PQRYRES qrp; + JDBConn *jcp = NULL; + + /************************************************************************/ + /* Do an evaluation of the result size. */ + /************************************************************************/ + if (!info) { + jcp = new(g)JDBConn(g, NULL); + n = jcp->GetMaxValue(SQL_MAX_DSN_LENGTH); + length[0] = (n) ? (n + 1) : 256; + + if (!maxres) + maxres = 512; // Estimated max number of data sources + + } else { + length[0] = 256; + maxres = 0; + } // endif info + + if (trace) + htrc("JDBCDataSources: max=%d len=%d\n", maxres, length[0]); + + /************************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /************************************************************************/ + qrp = PlgAllocResult(g, ncol, maxres, IDS_DSRC, + buftyp, fldtyp, length, false, true); + + for (i = 0, crp = qrp->Colresp; crp; i++, crp = crp->Next) + if (b[i]) + crp->Kdata->SetNullable(true); + + /************************************************************************/ + /* Now get the results into blocks. */ + /************************************************************************/ + if (!info && qrp && jcp->GetDataSources(qrp)) + qrp = NULL; + + /************************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /************************************************************************/ + return qrp; +} // end of JDBCDataSources + +/**************************************************************************/ +/* PrimaryKeys: constructs the result blocks containing all the */ +/* JDBC catalog information concerning primary keys. */ +/**************************************************************************/ +PQRYRES JDBCPrimaryKeys(PGLOBAL g, JDBConn *op, char *dsn, char *table) +{ + static int buftyp[] ={ TYPE_STRING, TYPE_STRING, TYPE_STRING, + TYPE_STRING, TYPE_SHORT, TYPE_STRING }; + static unsigned int length[] ={ 0, 0, 0, 0, 6, 128 }; + int n, ncol = 5; + int maxres; + PQRYRES qrp; + JCATPARM *cap; + JDBConn *jcp = op; + + if (!op) { + /**********************************************************************/ + /* Open the connection with the JDBC data source. */ + /**********************************************************************/ + jcp = new(g)JDBConn(g, NULL); + + if (jcp->Open(dsn, 2) < 1) // 2 is openReadOnly + return NULL; + + } // endif op + + /************************************************************************/ + /* Do an evaluation of the result size. */ + /************************************************************************/ + n = jcp->GetMaxValue(SQL_MAX_COLUMNS_IN_TABLE); + maxres = (n) ? (int)n : 250; + n = jcp->GetMaxValue(SQL_MAX_CATALOG_NAME_LEN); + length[0] = (n) ? (n + 1) : 128; + n = jcp->GetMaxValue(SQL_MAX_SCHEMA_NAME_LEN); + length[1] = (n) ? (n + 1) : 128; + n = jcp->GetMaxValue(SQL_MAX_TABLE_NAME_LEN); + length[2] = (n) ? (n + 1) : 128; + n = jcp->GetMaxValue(SQL_MAX_COLUMN_NAME_LEN); + length[3] = (n) ? (n + 1) : 128; + + if (trace) + htrc("JDBCPrimaryKeys: max=%d len=%d,%d,%d\n", + maxres, length[0], length[1], length[2]); + + /************************************************************************/ + /* Allocate the structure used to refer to the result set. */ + /************************************************************************/ + qrp = PlgAllocResult(g, ncol, maxres, IDS_PKEY, + buftyp, NULL, length, false, true); + + if (trace) + htrc("Getting pkey results ncol=%d\n", qrp->Nbcol); + + cap = AllocCatInfo(g, CAT_KEY, NULL, table, qrp); + + /************************************************************************/ + /* Now get the results into blocks. */ + /************************************************************************/ + if ((n = jcp->GetCatInfo(cap)) >= 0) { + qrp->Nblin = n; + // ResetNullValues(cap); + + if (trace) + htrc("PrimaryKeys: NBCOL=%d NBLIN=%d\n", qrp->Nbcol, qrp->Nblin); + + } else + qrp = NULL; + + /************************************************************************/ + /* Close any local connection. */ + /************************************************************************/ + if (!op) + jcp->Close(); + + /************************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /************************************************************************/ + return qrp; +} // end of JDBCPrimaryKeys +#endif // 0 + +/***********************************************************************/ +/* JDBConn construction/destruction. */ +/***********************************************************************/ +JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) +{ + m_G = g; + m_Tdb = tdbp; + jvm = nullptr; // Pointer to the JVM (Java Virtual Machine) + env= nullptr; // Pointer to native interface + jdi = nullptr; // Pointer to the JdbcInterface class + job = nullptr; // The JdbcInterface class object + xqid = xuid = xid = grs = readid = fetchid = typid = nullptr; + prepid = xpid = pcid = nullptr; +//m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; +//m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; +//m_UpdateOptions = 0; + m_Driver = NULL; + m_Url = NULL; + m_User = NULL; + m_Pwd = NULL; + m_Ncol = 0; + m_Aff = 0; + m_Rows = 0; + m_Fetch = 0; + m_RowsetSize = 0; + m_Updatable = true; + m_Transact = false; + m_Scrollable = false; + m_Full = false; + m_Opened = false; + m_IDQuoteChar[0] = '"'; + m_IDQuoteChar[1] = 0; + //*m_ErrMsg = '\0'; +} // end of JDBConn + +//JDBConn::~JDBConn() +// { +//if (Connected()) +// EndCom(); + +// } // end of ~JDBConn + +/***********************************************************************/ +/* Screen for errors. */ +/***********************************************************************/ +char *JDBConn::Check(void) +{ + if (env->ExceptionCheck()) { + char *msg; + jthrowable exc = env->ExceptionOccurred(); + jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), + "toString", "()Ljava/lang/String;"); + + if (exc != nullptr && tid != nullptr) { + jstring s = (jstring)env->CallObjectMethod(exc, tid); + const char *utf = env->GetStringUTFChars(s, (jboolean)false); + env->DeleteLocalRef(s); + msg = PlugDup(m_G, utf); + } else + msg = "Exception occured"; + + env->ExceptionClear(); + return msg; + } // endif Check + + return NULL; +} // end of Check + +#if 0 +/***********************************************************************/ +/* Utility routine. */ +/***********************************************************************/ +PSZ JDBConn::GetStringInfo(ushort infotype) +{ + //ASSERT(m_hdbc != SQL_NULL_HDBC); + char *p, buffer[MAX_STRING_INFO]; + SWORD result; + RETCODE rc; + + rc = SQLGetInfo(m_hdbc, infotype, buffer, sizeof(buffer), &result); + + if (!Check(rc)) { + ThrowDJX(rc, "SQLGetInfo"); // Temporary + // *buffer = '\0'; + } // endif rc + + p = PlugDup(m_G, buffer); + return p; +} // end of GetStringInfo + +/***********************************************************************/ +/* Utility routines. */ +/***********************************************************************/ +void JDBConn::OnSetOptions(HSTMT hstmt) +{ + RETCODE rc; + ASSERT(m_hdbc != SQL_NULL_HDBC); + + if ((signed)m_QueryTimeout != -1) { + // Attempt to set query timeout. Ignore failure + rc = SQLSetStmtOption(hstmt, SQL_QUERY_TIMEOUT, m_QueryTimeout); + + if (!Check(rc)) + // don't attempt it again + m_QueryTimeout = (DWORD)-1; + + } // endif m_QueryTimeout + + if (m_RowsetSize > 0) { + // Attempt to set rowset size. + // In case of failure reset it to 0 to use Fetch. + rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, m_RowsetSize); + + if (!Check(rc)) + // don't attempt it again + m_RowsetSize = 0; + + } // endif m_RowsetSize + +} // end of OnSetOptions +#endif // 0 + +/***********************************************************************/ +/* Utility routine. */ +/***********************************************************************/ +int JDBConn::GetMaxValue(int n) +{ + jmethodID maxid = env->GetMethodID(jdi, "GetMaxValue", "(I)I"); + + if (maxid == nullptr) { + strcpy(m_G->Message, "ERROR: method GetMaxValue not found !"); + return -1; + } // endif maxid + + // call method + return (int)env->CallIntMethod(job, maxid, n); +} // end of GetMaxValue + +/***********************************************************************/ +/* Reset the JVM library. */ +/***********************************************************************/ +void JDBConn::ResetJVM(void) +{ + if (LibJvm) { +#if defined(__WIN__) + FreeLibrary((HMODULE)LibJvm); +#else // !__WIN__ + dlclose(LibJvm); +#endif // !__WIN__ + LibJvm = NULL; + CreateJavaVM = NULL; + GetCreatedJavaVMs = NULL; + } // endif LibJvm + +} // end of ResetJVM + +/***********************************************************************/ +/* Dynamically link the JVM library. */ +/* The purpose of this function is to allow using the CONNECT plugin */ +/* for other table types when the Java JDK is not installed. */ +/***********************************************************************/ +bool JDBConn::GetJVM(PGLOBAL g) +{ + if (!LibJvm) { + char soname[512]; + +#if defined(__WIN__) + if (JvmPath) + strcat(strcpy(soname, JvmPath), "\\jvm.dll"); + else + strcpy(soname, "jvm.dll"); + + // Load the desired shared library + if (!(LibJvm = LoadLibrary(soname))) { + char buf[256]; + DWORD rc = GetLastError(); + + sprintf(g->Message, MSG(DLL_LOAD_ERROR), rc, soname); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)buf, sizeof(buf), NULL); + strcat(strcat(g->Message, ": "), buf); + } else if (!(CreateJavaVM = (CRTJVM)GetProcAddress((HINSTANCE)LibJvm, + "JNI_CreateJavaVM"))) { + sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_CreateJavaVM"); + FreeLibrary((HMODULE)LibJvm); + LibJvm = NULL; + } else if (!(GetCreatedJavaVMs = (GETJVM)GetProcAddress((HINSTANCE)LibJvm, + "JNI_GetCreatedJavaVMs"))) { + sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs"); + FreeLibrary((HMODULE)LibJvm); + LibJvm = NULL; + } // endif LibJvm +#else // !__WIN__ + const char *error = NULL; + + if (JvmPath) + strcat(strcpy(soname, JvmPath), "/libjvm.so"); + else + strcpy(soname, "libjvm.so"); + + // Load the desired shared library + if (!(LibJvm = dlopen(soname, RTLD_LAZY))) { + error = dlerror(); + sprintf(g->Message, MSG(SHARED_LIB_ERR), soname, SVP(error)); + } else if (!(CreateJavaVM = (CRTJVM)dlsym(LibJvm, "JNI_CreateJavaVM"))) { + error = dlerror(); + sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_CreateJavaVM", SVP(error)); + dlclose(LibJvm); + LibJvm = NULL; + } else if (!(GetCreatedJavaVMs = (GETJVM)dlsym(LibJvm, "JNI_GetCreatedJavaVMs"))) { + error = dlerror(); + sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error)); + dlclose(LibJvm); + LibJvm = NULL; + } // endif LibJvm +#endif // !__WIN__ + + } // endif LibJvm + + return LibJvm == NULL; +} // end of GetJVM + +/***********************************************************************/ +/* Open: connect to a data source. */ +/***********************************************************************/ +int JDBConn::Open(PJPARM sop) +{ + PGLOBAL& g = m_G; + + // Link or check whether jvm library was linked + if (GetJVM(g)) + return RC_FX; + + // Firstly check whether the jvm was already created + JavaVM* jvms[1]; + jsize jsz; + jint rc = GetCreatedJavaVMs(jvms, 1, &jsz); + + if (rc == JNI_OK && jsz == 1) { + // jvm already existing + jvm = jvms[0]; + rc = jvm->AttachCurrentThread((void**)&env, nullptr); + + if (rc != JNI_OK) { + strcpy(g->Message, "Cannot attach jvm to the current thread"); + return RC_FX; + } // endif rc + + } else { + // Create a new jvm + PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path="); + char *cp = NULL; + char sep; + +#if defined(__WIN__) + sep = ';'; +#else + sep = ':'; +#endif + + //================== prepare loading of Java VM ============================ + JavaVMInitArgs vm_args; // Initialization arguments + JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options + + // where to find java .class + if ((cp = PlugDup(m_G, getenv("CLASSPATH")))) + jpop->Append(cp); + + if (trace) { + htrc("CLASSPATH=%s\n", getenv("CLASSPATH")); + htrc("ClassPath=%s\n", ClassPath); + } // endif trace + + if (ClassPath && *ClassPath) { + if (cp) + jpop->Append(sep); + + jpop->Append(ClassPath); + } // endif ClassPath + + if (trace) + htrc("%s\n", jpop->GetStr()); + + options[0].optionString = jpop->GetStr(); + //options[1].optionString = "-verbose:jni"; + vm_args.version = JNI_VERSION_1_6; // minimum Java version + vm_args.nOptions = 1; // number of options + vm_args.options = options; + vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail + + //=============== load and initialize Java VM and JNI interface ============= + rc = CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !! + delete options; // we then no longer need the initialisation options. + + switch (rc) { + case JNI_OK: + strcpy(g->Message, "VM successfully created"); + break; + case JNI_ERR: + strcpy(g->Message, "Initialising JVM failed: unknown error"); + return RC_FX; + case JNI_EDETACHED: + strcpy(g->Message, "Thread detached from the VM"); + return RC_FX; + case JNI_EVERSION: + strcpy(g->Message, "JNI version error"); + return RC_FX; + case JNI_ENOMEM: + strcpy(g->Message, "Not enough memory"); + return RC_FX; + case JNI_EEXIST: + strcpy(g->Message, "VM already created"); + return RC_FX; + case JNI_EINVAL: + strcpy(g->Message, "Invalid arguments"); + return RC_FX; + default: + sprintf(g->Message, "Unknown return code %d", rc); + return RC_FX; + } // endswitch rc + + } // endif rc + + //=============== Display JVM version ======================================= +//jint ver = env->GetVersion(); +//cout << ((ver>>16)&0x0f) << "."<<(ver&0x0f) << endl; + + // try to find the JdbcInterface class + jdi = env->FindClass("JdbcInterface"); + + if (jdi == nullptr) { + strcpy(g->Message, "ERROR: class JdbcInterface not found !"); + return RC_FX; + } // endif jdi + +#if 0 // Suppressed because it does not make any usable change + if (b && jpath && *jpath) { + // Try to add that path the the jvm class path + jmethodID alp = env->GetStaticMethodID(jdi, "addLibraryPath", + "(Ljava/lang/String;)I"); + + if (alp == nullptr) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } else { + char *msg; + jstring path = env->NewStringUTF(jpath); + rc = env->CallStaticIntMethod(jdi, alp, path); + + if ((msg = Check())) { + strcpy(g->Message, msg); + env->DeleteLocalRef(path); + return RC_FX; + } else switch (rc) { + case JNI_OK: + printf("jpath added\n"); + break; + case JNI_EEXIST: + printf("jpath already exist\n"); + break; + case JNI_ERR: + default: + strcpy(g->Message, "Error adding jpath"); + env->DeleteLocalRef(path); + return RC_FX; + } // endswitch rc + + env->DeleteLocalRef(path); + } // endif alp + + } // endif jpath +#endif // 0 + + // if class found, continue + jmethodID ctor = env->GetMethodID(jdi, "", "()V"); + + if (ctor == nullptr) { + strcpy(g->Message, "ERROR: JdbcInterface constructor not found !"); + return RC_FX; + } else + job = env->NewObject(jdi, ctor); + + // If the object is successfully constructed, + // we can then search for the method we want to call, + // and invoke it for the object: + if (job == nullptr) { + strcpy(g->Message, "JdbcInterface class object not constructed !"); + return RC_FX; + } // endif job + + if (!sop) // DRIVER catalog table + return RC_OK; + + jmethodID cid = env->GetMethodID(jdi, "JdbcConnect", "([Ljava/lang/String;IZ)I"); + + if (env->ExceptionCheck()) { + strcpy(g->Message, "ERROR: method JdbcConnect() not found!"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return RC_FX; + } // endif Check + + // Build the java string array + jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4 + env->FindClass("java/lang/String"), NULL); // Strings + + if (sop) { + m_Driver = sop->Driver; + m_Url = sop->Url; + m_User = sop->User; + m_Pwd = sop->Pwd; + m_Scrollable = sop->Scrollable; + m_RowsetSize = sop->Fsize; + //m_LoginTimeout = sop->Cto; + //m_QueryTimeout = sop->Qto; + //m_UseCnc = sop->UseCnc; + } // endif sop + + // change some elements + if (m_Driver) + env->SetObjectArrayElement(parms, 0, env->NewStringUTF(m_Driver)); + + if (m_Url) + env->SetObjectArrayElement(parms, 1, env->NewStringUTF(m_Url)); + + if (m_User) + env->SetObjectArrayElement(parms, 2, env->NewStringUTF(m_User)); + + if (m_Pwd) + env->SetObjectArrayElement(parms, 3, env->NewStringUTF(m_Pwd)); + + // call method + rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable); + + // Not used anymore + env->DeleteLocalRef(parms); + + if (rc != (jint)0) { + strcpy(g->Message, "Connection failed"); + return RC_FX; + } // endif rc + + typid = env->GetMethodID(jdi, "ColumnType", "(ILjava/lang/String;)I"); + + if (env->ExceptionCheck()) { + strcpy(g->Message, "ERROR: method ColumnType() not found!"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return RC_FX; + } else + m_Opened = true; + + return RC_OK; +} // end of Open + +/***********************************************************************/ +/* Execute an SQL command. */ +/***********************************************************************/ +int JDBConn::ExecSQLcommand(char *sql) +{ + int rc = RC_NF; + jint n; + jstring qry; + PGLOBAL& g = m_G; + + if (xid == nullptr) { + // Get the methods used to execute a query and get the result + xid = env->GetMethodID(jdi, "Execute", "(Ljava/lang/String;)I"); + + if (xid == nullptr) { + strcpy(g->Message, "Cannot find method Execute"); + return RC_FX; + } else + grs = env->GetMethodID(jdi, "GetResult", "()I"); + + if (grs == nullptr) { + strcpy(g->Message, "Cannot find method GetResult"); + return RC_FX; + } // endif grs + + } // endif xid + + qry = env->NewStringUTF(sql); + n = env->CallIntMethod(job, xid, qry); + env->DeleteLocalRef(qry); + + if (n < 0) { + sprintf(g->Message, "Error executing %s", sql); + return RC_FX; + } // endif n + + if ((m_Ncol = env->CallIntMethod(job, grs))) { + strcpy(g->Message, "Result set column number"); + rc = RC_OK; // A result set was returned + } else { + m_Aff = (int)n; // Affected rows + strcpy(g->Message, "Affected rows"); + } // endif ncol + + return rc; +} // end of ExecSQLcommand + +/***********************************************************************/ +/* Fetch next row. */ +/***********************************************************************/ +int JDBConn::Fetch(int pos) +{ + jint rc; + + if (m_Full) // Result set has one row + return 1; + + if (pos) { + if (!m_Scrollable) { + strcpy(m_G->Message, "Cannot fetch(pos) if FORWARD ONLY"); + return -1; + } else if (fetchid == nullptr) { + fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); + + if (fetchid == nullptr) { + strcpy(m_G->Message, "Cannot find method Fetch"); + return -1; + } // endif fetchid + + } // endif's + + if (env->CallBooleanMethod(job, fetchid, pos)) + rc = m_Rows; + else + rc = -1; + + } else { + if (readid == nullptr) { + readid = env->GetMethodID(jdi, "ReadNext", "()I"); + + if (readid == nullptr) { + strcpy(m_G->Message, "Cannot find method ReadNext"); + return -1; + } // endif readid + + } // endif readid + + rc = env->CallBooleanMethod(job, readid); + + if (rc >= 0) { + if (rc == 0) + m_Full = (m_Fetch == 1); + else + m_Fetch++; + + m_Rows += (int)rc; + } else + strcpy(m_G->Message, "Error fetching next row"); + + } // endif pos + + return (int)rc; +} // end of Fetch + +/***********************************************************************/ +/* Restart from beginning of result set */ +/***********************************************************************/ +int JDBConn::Rewind(char *sql) +{ + int rbuf = -1; + + if (m_Full) + rbuf = m_Rows; // No need to "rewind" + else if (m_Scrollable) { + if (fetchid == nullptr) { + fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); + + if (fetchid == nullptr) { + strcpy(m_G->Message, "Cannot find method Fetch"); + return -1; + } // endif readid + + } // endif readid + + jboolean b = env->CallBooleanMethod(job, fetchid, 0); + + rbuf = m_Rows; + } else if (ExecSQLcommand(sql) != RC_FX) + rbuf = 0; + + return rbuf; +} // end of Rewind + +/***********************************************************************/ +/* Disconnect connection */ +/***********************************************************************/ +void JDBConn::Close() +{ + if (m_Opened) { + jint rc; + jmethodID did = env->GetMethodID(jdi, "JdbcDisconnect", "()I"); + + if (did == nullptr) + printf("ERROR: method JdbcDisconnect() not found !"); + else if ((rc = env->CallIntMethod(job, did))) + printf("jdbcDisconnect: rc=%d", (int)rc); + + if ((rc = jvm->DetachCurrentThread())) + printf("DetachCurrentThread: rc = %d", (int)rc); + + //rc = jvm->DestroyJavaVM(); + m_Opened = false; + } // endif m_Opened + +} // end of Close + +/***********************************************************************/ +/* Retrieve and set the column value from the result set. */ +/***********************************************************************/ +void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) +{ + PGLOBAL& g = m_G; + char *msg; + jint ctyp; + jlong dtv; + jstring cn, jn = nullptr; + jobject dob; + jmethodID fldid = nullptr; + + if (rank == 0) + if (!name || (jn = env->NewStringUTF(name)) == nullptr) { + sprintf(g->Message, "Fail to allocate jstring %s", SVP(name)); + longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); + } // endif name + + ctyp = env->CallIntMethod(job, typid, rank, jn); + + if ((msg = Check())) { + sprintf(g->Message, "Getting ctyp: %s", msg); + longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); + } // endif Check + + switch (ctyp) { + case 12: // VARCHAR + case -1: // LONGVARCHAR + case 1: // CHAR + fldid = env->GetMethodID(jdi, "StringField", + "(ILjava/lang/String;)Ljava/lang/String;"); + + if (fldid != nullptr) { + cn = (jstring)env->CallObjectMethod(job, fldid, (jint)rank, jn); + + if (cn) { + const char *field = env->GetStringUTFChars(cn, (jboolean)false); + val->SetValue_psz((PSZ)field); + } else { + val->Reset(); + val->SetNull(true); + } // endif cn + + } else + val->Reset(); + + break; + case 4: // INTEGER + case 5: // SMALLINT + case -6: // TINYINT + fldid = env->GetMethodID(jdi, "IntField", "(ILjava/lang/String;)I"); + + if (fldid != nullptr) + val->SetValue((int)env->CallIntMethod(job, fldid, rank, jn)); + else + val->Reset(); + + break; + case 8: // DOUBLE + case 3: // DECIMAL + fldid = env->GetMethodID(jdi, "DoubleField", "(ILjava/lang/String;)D"); + + if (fldid != nullptr) + val->SetValue((double)env->CallDoubleMethod(job, fldid, rank, jn)); + else + val->Reset(); + + break; + case 7: // REAL + case 6: // FLOAT + fldid = env->GetMethodID(jdi, "FloatField", "(ILjava/lang/String;)F"); + + if (fldid != nullptr) + val->SetValue((float)env->CallFloatMethod(job, fldid, rank, jn)); + else + val->Reset(); + + break; + case 91: // DATE + case 92: // TIME + case 93: // TIMESTAMP + fldid = env->GetMethodID(jdi, "TimestampField", + "(ILjava/lang/String;)Ljava/sql/Timestamp;"); + + if (fldid != nullptr) { + dob = env->CallObjectMethod(job, fldid, (jint)rank, jn); + + if (dob) { + jclass jts = env->FindClass("java/sql/Timestamp"); + + if (env->ExceptionCheck()) { + val->Reset(); + } else { + jmethodID getTime = env->GetMethodID(jts, "getTime", "()J"); + + if (getTime != nullptr) { + dtv = env->CallLongMethod(dob, getTime); + val->SetValue((int)(dtv / 1000)); + } else + val->Reset(); + + } // endif check + + } else + val->Reset(); + + } else + val->Reset(); + + break; + case -5: // BIGINT + fldid = env->GetMethodID(jdi, "BigintField", "(ILjava/lang/String;)J"); + + if (fldid != nullptr) + val->SetValue((long long)env->CallLongMethod(job, fldid, (jint)rank, jn)); + else + val->Reset(); + + break; + /* case java.sql.Types.SMALLINT: + System.out.print(jdi.IntField(i)); + break; + case java.sql.Types.BOOLEAN: + System.out.print(jdi.BooleanField(i)); */ + default: + val->Reset(); + } // endswitch Type + + if ((msg = Check())) { + if (rank == 0) + env->DeleteLocalRef(jn); + + sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", msg, rank, (int)ctyp); + longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); + } // endif Check + + if (rank == 0) + env->DeleteLocalRef(jn); + +} // end of SetColumnValue + +/***********************************************************************/ +/* Prepare an SQL statement for insert. */ +/***********************************************************************/ +bool JDBConn::PrepareSQL(char *sql) +{ + if (prepid == nullptr) { + prepid = env->GetMethodID(jdi, "CreatePrepStmt", "(Ljava/lang/String;)Z"); + + if (prepid == nullptr) { + strcpy(m_G->Message, "Cannot find method CreatePrepStmt"); + return true; + } // endif prepid + + } // endif prepid + + // Create the prepared statement + jstring qry = env->NewStringUTF(sql); + jboolean b = env->CallBooleanMethod(job, prepid, qry); + env->DeleteLocalRef(qry); + return (bool)b; +} // end of PrepareSQL + +/***********************************************************************/ +/* Execute an SQL query that returns a result set. */ +/***********************************************************************/ +int JDBConn::ExecuteQuery(char *sql) +{ + jint ncol; + jstring qry; + PGLOBAL& g = m_G; + + if (xqid == nullptr) { + // Get the methods used to execute a query and get the result + xqid = env->GetMethodID(jdi, "ExecuteQuery", "(Ljava/lang/String;)I"); + + if (xqid == nullptr) { + strcpy(g->Message, "Cannot find method ExecuteQuery"); + return RC_FX; + } // endif !xqid + + } // endif xqid + + qry = env->NewStringUTF(sql); + ncol = env->CallIntMethod(job, xqid, qry); + env->DeleteLocalRef(qry); + + if (ncol < 0) { + sprintf(g->Message, "Error executing %s: ncol = %d", sql, ncol); + return RC_FX; + } else { + m_Ncol = (int)ncol; + m_Aff = 0; // Affected rows + } // endif ncol + + return RC_OK; +} // end of ExecuteQuery + +/***********************************************************************/ +/* Execute an SQL query and get the affected rows. */ +/***********************************************************************/ +int JDBConn::ExecuteUpdate(char *sql) +{ + jint n; + jstring qry; + PGLOBAL& g = m_G; + + if (xuid == nullptr) { + // Get the methods used to execute a query and get the affected rows + xuid = env->GetMethodID(jdi, "ExecuteUpdate", "(Ljava/lang/String;)I"); + + if (xuid == nullptr) { + strcpy(g->Message, "Cannot find method ExecuteUpdate"); + return RC_FX; + } // endif !xuid + + } // endif xuid + + qry = env->NewStringUTF(sql); + n = env->CallIntMethod(job, xuid, qry); + env->DeleteLocalRef(qry); + + if (n < 0) { + sprintf(g->Message, "Error executing %s: n = %d", sql, n); + return RC_FX; + } else { + m_Ncol = 0; + m_Aff = (int)n; // Affected rows + } // endif n + + return RC_OK; +} // end of ExecuteUpdate + +/***********************************************************************/ +/* Get the number of lines of the result set. */ +/***********************************************************************/ +int JDBConn::GetResultSize(char *sql, JDBCCOL *colp) +{ + int rc, n = 0; + + if ((rc = ExecuteQuery(sql)) != RC_OK) + return -1; + + if ((rc = Fetch()) > 0) + SetColumnValue(1, NULL, colp->GetValue()); + else + return -2; + + if ((rc = Fetch()) != 0) + return -3; + + m_Full = false; + return colp->GetIntValue(); +} // end of GetResultSize + +/***********************************************************************/ +/* Execute a prepared statement. */ +/***********************************************************************/ +int JDBConn::ExecuteSQL(void) +{ + int rc = RC_FX; + PGLOBAL& g = m_G; + + if (xpid == nullptr) { + // Get the methods used to execute a prepared statement + xpid = env->GetMethodID(jdi, "ExecutePrep", "()I"); + + if (xpid == nullptr) { + strcpy(g->Message, "Cannot find method ExecutePrep"); + return rc; + } // endif xpid + + } // endif xpid + + jint n = env->CallIntMethod(job, xpid); + + switch ((int)n) { + case -1: + case -2: + strcpy(g->Message, "Exception error thrown while executing SQL"); + break; + case -3: + strcpy(g->Message, "SQL statement is not prepared"); + break; + default: + m_Aff = (int)n; + rc = RC_OK; + } // endswitch n + + return rc; +} // end of ExecuteSQL + +/***********************************************************************/ +/* Set a parameter for inserting. */ +/***********************************************************************/ +bool JDBConn::SetParam(JDBCCOL *colp) +{ + PGLOBAL& g = m_G; + char *msg; + int rc = false; + PVAL val = colp->GetValue(); + jint n, i = (jint)colp->GetRank(); + jshort s; + jlong lg; +//jfloat f; + jdouble d; + jclass dat; + jobject datobj; + jstring jst = nullptr; + jmethodID dtc, setid = nullptr; + + switch (val->GetType()) { + case TYPE_STRING: + setid = env->GetMethodID(jdi, "SetStringParm", "(ILjava/lang/String;)V"); + + if (setid == nullptr) { + strcpy(g->Message, "Cannot fing method SetStringParm"); + return true; + } // endif setid + + jst = env->NewStringUTF(val->GetCharValue()); + env->CallVoidMethod(job, setid, i, jst); + break; + case TYPE_INT: + setid = env->GetMethodID(jdi, "SetIntParm", "(II)V"); + + if (setid == nullptr) { + strcpy(g->Message, "Cannot fing method SetIntParm"); + return true; + } // endif setid + + n = (jint)val->GetIntValue(); + env->CallVoidMethod(job, setid, i, n); + break; + case TYPE_TINY: + case TYPE_SHORT: + setid = env->GetMethodID(jdi, "SetShortParm", "(IS)V"); + + if (setid == nullptr) { + strcpy(g->Message, "Cannot fing method SetShortParm"); + return true; + } // endif setid + + s = (jshort)val->GetShortValue(); + env->CallVoidMethod(job, setid, i, s); + break; + case TYPE_BIGINT: + setid = env->GetMethodID(jdi, "SetBigintParm", "(IJ)V"); + + if (setid == nullptr) { + strcpy(g->Message, "Cannot fing method SetBigintParm"); + return true; + } // endif setid + + lg = (jlong)val->GetBigintValue(); + env->CallVoidMethod(job, setid, i, lg); + break; + case TYPE_DOUBLE: + case TYPE_DECIM: + setid = env->GetMethodID(jdi, "SetDoubleParm", "(ID)V"); + + if (setid == nullptr) { + strcpy(g->Message, "Cannot find method SetDoubleParm"); + return true; + } // endif setid + + d = (jdouble)val->GetFloatValue(); + env->CallVoidMethod(job, setid, i, d); + break; + case TYPE_DATE: + if ((dat = env->FindClass("java/sql/Timestamp")) == nullptr) { + strcpy(g->Message, "Cannot find Timestamp class"); + return true; + } else if (!(dtc = env->GetMethodID(dat, "", "(J)V"))) { + strcpy(g->Message, "Cannot find Timestamp class constructor"); + return true; + } // endif's + + lg = (jlong)val->GetBigintValue() * 1000; + + if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) { + strcpy(g->Message, "Cannot make Timestamp object"); + return true; + } else if ((setid = env->GetMethodID(jdi, "SetTimestampParm", + "(ILjava/sql/Timestamp;)V")) == nullptr) { + strcpy(g->Message, "Cannot find method SetTimestampParm"); + return true; + } // endif setid + + env->CallVoidMethod(job, setid, i, datobj); + break; + default: + sprintf(g->Message, "Parm type %d not supported", val->GetType()); + return true; + } // endswitch Type + + if ((msg = Check())) { + sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), msg); + rc = true; + } // endif msg + + if (jst) + env->DeleteLocalRef(jst); + + return rc; + } // end of SetParam + +#if 0 + /***********************************************************************/ + /* Get the list of Data Sources and set it in qrp. */ + /***********************************************************************/ + bool JDBConn::GetDataSources(PQRYRES qrp) + { + bool rv = false; + UCHAR *dsn, *des; + UWORD dir = SQL_FETCH_FIRST; + SWORD n1, n2, p1, p2; + PCOLRES crp1 = qrp->Colresp, crp2 = qrp->Colresp->Next; + RETCODE rc; + + n1 = crp1->Clen; + n2 = crp2->Clen; + + try { + rc = SQLAllocEnv(&m_henv); + + if (!Check(rc)) + ThrowDJX(rc, "SQLAllocEnv"); // Fatal + + for (int i = 0; i < qrp->Maxres; i++) { + dsn = (UCHAR*)crp1->Kdata->GetValPtr(i); + des = (UCHAR*)crp2->Kdata->GetValPtr(i); + rc = SQLDataSources(m_henv, dir, dsn, n1, &p1, des, n2, &p2); + + if (rc == SQL_NO_DATA_FOUND) + break; + else if (!Check(rc)) + ThrowDJX(rc, "SQLDataSources"); + + qrp->Nblin++; + dir = SQL_FETCH_NEXT; + } // endfor i + + } + catch (DJX *x) { + sprintf(m_G->Message, "%s: %s", x->m_Msg, x->GetErrorMessage(0)); + rv = true; + } // end try/catch + + Close(); + return rv; + } // end of GetDataSources +#endif // 0 + + /***********************************************************************/ + /* Get the list of Drivers and set it in qrp. */ + /***********************************************************************/ + bool JDBConn::GetDrivers(PQRYRES qrp) + { + PSZ sval; + int i, n, size; + PCOLRES crp; + jstring js; + jmethodID gdid = env->GetMethodID(jdi, "GetDrivers", "([Ljava/lang/String;I)I"); + + if (env->ExceptionCheck()) { + strcpy(m_G->Message, "ERROR: method GetDrivers() not found!"); + env->ExceptionDescribe(); + env->ExceptionClear(); + return true; + } // endif Check + + // Build the java string array + jobjectArray s = env->NewObjectArray(4 * qrp->Maxres, + env->FindClass("java/lang/String"), NULL); + + size = env->CallIntMethod(job, gdid, s, qrp->Maxres); + + for (i = 0, n = 0; i < size; i++) { + crp = qrp->Colresp; + js = (jstring)env->GetObjectArrayElement(s, n++); + sval = (PSZ)env->GetStringUTFChars(js, 0); + crp->Kdata->SetValue(sval, i); + crp = crp->Next; + js = (jstring)env->GetObjectArrayElement(s, n++); + sval = (PSZ)env->GetStringUTFChars(js, 0); + crp->Kdata->SetValue(sval, i); + crp = crp->Next; + js = (jstring)env->GetObjectArrayElement(s, n++); + sval = (PSZ)env->GetStringUTFChars(js, 0); + crp->Kdata->SetValue(sval, i); + crp = crp->Next; + js = (jstring)env->GetObjectArrayElement(s, n++); + sval = (PSZ)env->GetStringUTFChars(js, 0); + crp->Kdata->SetValue(sval, i); + } // endfor i + + // Not used anymore + env->DeleteLocalRef(s); + + qrp->Nblin = size; + return false; + } // end of GetDrivers + + /**************************************************************************/ + /* GetMetaData: constructs the result blocks containing the */ + /* description of all the columns of an SQL command. */ + /**************************************************************************/ + PQRYRES JDBConn::GetMetaData(PGLOBAL g, char *src) + { + static int buftyp[] = {TYPE_STRING, TYPE_INT, TYPE_INT, + TYPE_INT, TYPE_INT}; + static XFLD fldtyp[] = {FLD_NAME, FLD_TYPE, FLD_PREC, + FLD_SCALE, FLD_NULL }; + static unsigned int length[] = {0, 6, 10, 6, 6}; + const char *name; + int len, qcol = 5; + PQRYRES qrp = NULL; + PCOLRES crp; + ushort i; + jint *n = nullptr; + jstring label; + jmethodID colid; + int rc = ExecSQLcommand(src); + + if (rc == RC_NF) { + strcpy(g->Message, "Srcdef is not returning a result set"); + return NULL; + } else if ((rc) == RC_FX) { + return NULL; + } else if (m_Ncol == 0) { + strcpy(g->Message, "Invalid Srcdef"); + return NULL; + } // endif's + + colid = env->GetMethodID(jdi, "ColumnDesc", "(I[I)Ljava/lang/String;"); + + if (colid == nullptr) { + strcpy(m_G->Message, "ERROR: method ColumnDesc() not found!"); + return NULL; + } // endif colid + + // Build the java string array + jintArray val = env->NewIntArray(4); + + if (val == nullptr) { + strcpy(m_G->Message, "Cannot allocate jint array"); + return NULL; + } // endif colid + + // Get max column name length + len = GetMaxValue(5); + length[0] = (len > 0) ? len + 1 : 128; + + /************************************************************************/ + /* Allocate the structures used to refer to the result set. */ + /************************************************************************/ + if (!(qrp = PlgAllocResult(g, qcol, m_Ncol, IDS_COLUMNS + 3, + buftyp, fldtyp, length, false, true))) + return NULL; + + // Some columns must be renamed + for (i = 0, crp = qrp->Colresp; crp; crp = crp->Next) + switch (++i) { + case 3: crp->Name = "Precision"; break; + case 4: crp->Name = "Scale"; break; + case 5: crp->Name = "Nullable"; break; + } // endswitch i + + /************************************************************************/ + /* Now get the results into blocks. */ + /************************************************************************/ + for (i = 0; i < m_Ncol; i++) { + label = (jstring)env->CallObjectMethod(job, colid, i + 1, val); + name = env->GetStringUTFChars(label, (jboolean)false); + crp = qrp->Colresp; // Column_Name + crp->Kdata->SetValue((char*)name, i); + n = env->GetIntArrayElements(val, 0); + crp = crp->Next; // Data_Type + crp->Kdata->SetValue((int)n[0], i); + crp = crp->Next; // Precision (length) + crp->Kdata->SetValue((int)n[1], i); + crp = crp->Next; // Scale + crp->Kdata->SetValue((int)n[2], i); + crp = crp->Next; // Nullable + crp->Kdata->SetValue((int)n[3], i); + qrp->Nblin++; + } // endfor i + + /* Cleanup */ + env->ReleaseIntArrayElements(val, n, 0); + Close(); + + /************************************************************************/ + /* Return the result pointer for use by GetData routines. */ + /************************************************************************/ + return qrp; + } // end of GetMetaData + + /***********************************************************************/ + /* A helper class to split an optionally qualified table name into */ + /* components. */ + /* These formats are understood: */ + /* "CatalogName.SchemaName.TableName" */ + /* "SchemaName.TableName" */ + /* "TableName" */ + /***********************************************************************/ + class SQLQualifiedName + { + static const uint max_parts= 3; // Catalog.Schema.Table + MYSQL_LEX_STRING m_part[max_parts]; + char m_buf[512]; + + void lex_string_set(MYSQL_LEX_STRING *S, char *str, size_t length) + { + S->str= str; + S->length= length; + } // end of lex_string_set + + void lex_string_shorten_down(MYSQL_LEX_STRING *S, size_t offs) + { + DBUG_ASSERT(offs <= S->length); + S->str+= offs; + S->length-= offs; + } // end of lex_string_shorten_down + + /*********************************************************************/ + /* Find the rightmost '.' delimiter and return the length */ + /* of the qualifier, including the rightmost '.' delimier. */ + /* For example, for the string {"a.b.c",5} it will return 4, */ + /* which is the length of the qualifier "a.b." */ + /*********************************************************************/ + size_t lex_string_find_qualifier(MYSQL_LEX_STRING *S) + { + size_t i; + for (i= S->length; i > 0; i--) + { + if (S->str[i - 1] == '.') + { + S->str[i - 1]= '\0'; + return i; + } + } + return 0; + } // end of lex_string_find_qualifier + + public: + /*********************************************************************/ + /* Initialize to the given optionally qualified name. */ + /* NULL pointer in "name" is supported. */ + /* name qualifier has precedence over schema. */ + /*********************************************************************/ + SQLQualifiedName(JCATPARM *cap) + { + const char *name = (const char *)cap->Tab; + char *db = (char *)cap->DB; + size_t len, i; + + // Initialize the parts + for (i = 0; i < max_parts; i++) + lex_string_set(&m_part[i], NULL, 0); + + if (name) { + // Initialize the first (rightmost) part + lex_string_set(&m_part[0], m_buf, + strmake(m_buf, name, sizeof(m_buf) - 1) - m_buf); + + // Initialize the other parts, if exist. + for (i= 1; i < max_parts; i++) { + if (!(len= lex_string_find_qualifier(&m_part[i - 1]))) + break; + + lex_string_set(&m_part[i], m_part[i - 1].str, len - 1); + lex_string_shorten_down(&m_part[i - 1], len); + } // endfor i + + } // endif name + + // If it was not specified, set schema as the passed db name + if (db && !m_part[1].length) + lex_string_set(&m_part[1], db, strlen(db)); + + } // end of SQLQualifiedName + + char *ptr(uint i) + { + DBUG_ASSERT(i < max_parts); + return (char *)(m_part[i].length ? m_part[i].str : NULL); + } // end of ptr + + size_t length(uint i) + { + DBUG_ASSERT(i < max_parts); + return m_part[i].length; + } // end of length + + }; // end of class SQLQualifiedName + + /***********************************************************************/ + /* Allocate recset and call SQLTables, SQLColumns or SQLPrimaryKeys. */ + /***********************************************************************/ + int JDBConn::GetCatInfo(JCATPARM *cap) + { + PGLOBAL& g = m_G; +// void *buffer; + int i; + PSZ fnc = "Unknown"; + uint n, ncol; + short len, tp; + int crow = 0; + PQRYRES qrp = cap->Qrp; + PCOLRES crp; + jboolean rc = false; +// HSTMT hstmt = NULL; +// SQLLEN *vl, *vlen = NULL; + PVAL *pval = NULL; + char* *pbuf = NULL; + jobjectArray parms; + jmethodID catid; + + if (qrp->Maxres <= 0) + return 0; // 0-sized result" + + SQLQualifiedName name(cap); + + // Build the java string array + parms = env->NewObjectArray(4, env->FindClass("java/lang/String"), NULL); + env->SetObjectArrayElement(parms, 0, env->NewStringUTF(name.ptr(2))); + env->SetObjectArrayElement(parms, 1, env->NewStringUTF(name.ptr(1))); + env->SetObjectArrayElement(parms, 2, env->NewStringUTF(name.ptr(0))); + + if (cap->Pat) + env->SetObjectArrayElement(parms, 3, env->NewStringUTF((const char*)cap->Pat)); + + // Now do call the proper JDBC API + switch (cap->Id) { + case CAT_COL: + fnc = "GetColumns"; + break; + case CAT_TAB: + fnc = "GetTables"; + break; +#if 0 + case CAT_KEY: + fnc = "SQLPrimaryKeys"; + rc = SQLPrimaryKeys(hstmt, name.ptr(2), name.length(2), + name.ptr(1), name.length(1), + name.ptr(0), name.length(0)); + break; + case CAT_STAT: + fnc = "SQLStatistics"; + rc = SQLStatistics(hstmt, name.ptr(2), name.length(2), + name.ptr(1), name.length(1), + name.ptr(0), name.length(0), + cap->Unique, cap->Accuracy); + break; + case CAT_SPC: + ThrowDJX("SQLSpecialColumns not available yet"); +#endif // 0 + default: + sprintf(g->Message, "Invalid SQL function id"); + return -1; + } // endswitch infotype + + catid = env->GetMethodID(jdi, fnc, "([Ljava/lang/String;)I"); + + if (catid == nullptr) { + sprintf(g->Message, "ERROR: method %s not found !", fnc); + return -1; + } // endif maxid + + // call method + ncol = env->CallIntMethod(job, catid, parms); + + // Not used anymore + env->DeleteLocalRef(parms); + + if (trace) + htrc("Method %s returned %d columns\n", fnc, ncol); + + // n because we no more ignore the first column + if ((n = qrp->Nbcol) > (uint)ncol) { + strcpy(g->Message, MSG(COL_NUM_MISM)); + return -1; + } // endif n + + // Unconditional to handle STRBLK's + pval = (PVAL *)PlugSubAlloc(g, NULL, n * sizeof(PVAL)); +// vlen = (SQLLEN *)PlugSubAlloc(g, NULL, n * sizeof(SQLLEN)); + pbuf = (char**)PlugSubAlloc(g, NULL, n * sizeof(char*)); + + // Prepare retrieving column values + for (n = 0, crp = qrp->Colresp; crp; crp = crp->Next) { + if (!(tp = GetJDBCType(crp->Type))) { + sprintf(g->Message, MSG(INV_COLUMN_TYPE), crp->Type, crp->Name); + return -1; + } // endif tp + + if (!(len = GetTypeSize(crp->Type, crp->Length))) { + len = 255; // for STRBLK's + ((STRBLK*)crp->Kdata)->SetSorted(true); + } // endif len + + pval[n] = AllocateValue(g, crp->Type, len); + + if (crp->Type == TYPE_STRING) { + pbuf[n] = (char*)PlugSubAlloc(g, NULL, len); +// buffer = pbuf[n]; + } // endif Type +// } else +// buffer = pval[n]->GetTo_Val(); + + n++; + } // endfor n + + // Now fetch the result + for (i = 0; i < qrp->Maxres; i++) { + if ((rc = Fetch(0)) == 0) { + if (trace) + htrc("End of fetches i=%d\n", i); + + break; + } else if (rc < 0) + return -1; + + for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) { + SetColumnValue(n + 1, nullptr, pval[n]); + crp->Kdata->SetValue(pval[n], i); + } // endfor n + + } // endfor i + + if (rc > 0) + qrp->Truncated = true; + + return i; + } // end of GetCatInfo + + /***********************************************************************/ + /* Allocate a CONNECT result structure from the JDBC result. */ + /***********************************************************************/ + PQRYRES JDBConn::AllocateResult(PGLOBAL g) + { + bool uns; + PJDBCCOL colp; + PCOLRES *pcrp, crp; + PQRYRES qrp; + + if (!m_Rows) { + strcpy(g->Message, "Void result"); + return NULL; + } // endif m_Res + + /*********************************************************************/ + /* Allocate the result storage for future retrieval. */ + /*********************************************************************/ + qrp = (PQRYRES)PlugSubAlloc(g, NULL, sizeof(QRYRES)); + pcrp = &qrp->Colresp; + qrp->Continued = FALSE; + qrp->Truncated = FALSE; + qrp->Info = FALSE; + qrp->Suball = TRUE; + qrp->BadLines = 0; + qrp->Maxsize = m_Rows; + qrp->Maxres = m_Rows; + qrp->Nbcol = 0; + qrp->Nblin = 0; + qrp->Cursor = 0; + + for (colp = (PJDBCCOL)m_Tdb->Columns; colp; + colp = (PJDBCCOL)colp->GetNext()) + if (!colp->IsSpecial()) { + *pcrp = (PCOLRES)PlugSubAlloc(g, NULL, sizeof(COLRES)); + crp = *pcrp; + pcrp = &crp->Next; + memset(crp, 0, sizeof(COLRES)); + crp->Ncol = ++qrp->Nbcol; + crp->Name = colp->GetName(); + crp->Type = colp->GetResultType(); + crp->Prec = colp->GetScale(); + crp->Length = colp->GetLength(); + crp->Clen = colp->GetValue()->GetClen(); + uns = colp->IsUnsigned(); + + if (!(crp->Kdata = AllocValBlock(g, NULL, crp->Type, m_Rows, + crp->Clen, 0, FALSE, TRUE, uns))) { + sprintf(g->Message, MSG(INV_RESULT_TYPE), + GetFormatType(crp->Type)); + return NULL; + } // endif Kdata + + if (!colp->IsNullable()) + crp->Nulls = NULL; + else { + crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); + memset(crp->Nulls, ' ', m_Rows); + } // endelse Nullable + + colp->SetCrp(crp); + } // endif colp + + *pcrp = NULL; + //qrp->Nblin = n; + return qrp; + } // end of AllocateResult diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h new file mode 100644 index 0000000000000..4014a52cdcc2b --- /dev/null +++ b/storage/connect/jdbconn.h @@ -0,0 +1,171 @@ +/***********************************************************************/ +/* JDBConn.h : header file for the JDBC connection classes. */ +/***********************************************************************/ +//nclude /* Windows include file */ +//nclude /* Message crackers */ + +/***********************************************************************/ +/* Included C-definition files required by the interface. */ +/***********************************************************************/ +#include "block.h" + +/***********************************************************************/ +/* JDBC interface. */ +/***********************************************************************/ +#include + +/***********************************************************************/ +/* Constants and defines. */ +/***********************************************************************/ +// Miscellaneous sizing info +#define MAX_NUM_OF_MSG 10 // Max number of error messages +//efine MAX_CURRENCY 30 // Max size of Currency($) string +#define MAX_TNAME_LEN 32 // Max size of table names +//efine MAX_FNAME_LEN 256 // Max size of field names +//efine MAX_STRING_INFO 256 // Max size of string from SQLGetInfo +//efine MAX_DNAME_LEN 256 // Max size of Recordset names +#define MAX_CONNECT_LEN 512 // Max size of Connect string +//efine MAX_CURSOR_NAME 18 // Max size of a cursor name +#define DEFAULT_FIELD_TYPE 0 // TYPE_NULL + +#if !defined(__WIN__) +typedef unsigned char *PUCHAR; +#endif // !__WIN__ + +enum JCATINFO { + CAT_TAB = 1, // JDBC Tables + CAT_COL = 2, // JDBC Columns + CAT_KEY = 3, // JDBC PrimaryKeys +//CAT_STAT = 4, // SQLStatistics +//CAT_SPC = 5 // SQLSpecialColumns +}; + +/***********************************************************************/ +/* This structure is used to control the catalog functions. */ +/***********************************************************************/ +typedef struct tagJCATPARM { + JCATINFO Id; // Id to indicate function + PQRYRES Qrp; // Result set pointer + PUCHAR DB; // Database (Schema) + PUCHAR Tab; // Table name or pattern + PUCHAR Pat; // Table type or column pattern +} JCATPARM; + +typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *); +typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *); + +// JDBC connection to a data source +class TDBJDBC; +class JDBCCOL; +class JDBConn; +class TDBXJDC; + +/***********************************************************************/ +/* JDBConn class. */ +/***********************************************************************/ +class JDBConn : public BLOCK { + friend class TDBJDBC; + friend class TDBXJDC; +//friend PQRYRES GetColumnInfo(PGLOBAL, char*&, char *, int, PVBLK&); +private: + JDBConn(); // Standard (unused) constructor + +public: + JDBConn(PGLOBAL g, TDBJDBC *tdbp); + + int Open(PJPARM sop); + int Rewind(char *sql); + void Close(void); + PQRYRES AllocateResult(PGLOBAL g); + + // Attributes +public: + char *GetQuoteChar(void) { return m_IDQuoteChar; } + // Database successfully opened? + bool IsOpen(void) { return m_Opened; } +//PSZ GetStringInfo(ushort infotype); + int GetMaxValue(int infotype); +//PSZ GetConnect(void) { return m_Connect; } + +public: + // Operations + //void SetLoginTimeout(DWORD sec) {m_LoginTimeout = sec;} + //void SetQueryTimeout(DWORD sec) {m_QueryTimeout = sec;} + //void SetUserName(PSZ user) {m_User = user;} + //void SetUserPwd(PSZ pwd) {m_Pwd = pwd;} + int GetResultSize(char *sql, JDBCCOL *colp); + int ExecuteQuery(char *sql); + int ExecuteUpdate(char *sql); + int Fetch(int pos = 0); + bool PrepareSQL(char *sql); + int ExecuteSQL(void); + bool SetParam(JDBCCOL *colp); + int ExecSQLcommand(char *sql); + void SetColumnValue(int rank, PSZ name, PVAL val); + int GetCatInfo(JCATPARM *cap); + //bool GetDataSources(PQRYRES qrp); + bool GetDrivers(PQRYRES qrp); + PQRYRES GetMetaData(PGLOBAL g, char *src); + +public: + // Set static variables + static void SetJVM(void) + { LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; } + static void ResetJVM(void); + static bool GetJVM(PGLOBAL g); + + // Implementation +public: + //virtual ~JDBConn(); + + // JDBC operations +protected: + char *Check(void); +//void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/); +//void ThrowDJX(PSZ msg); +//void Free(void); + +protected: + // Members +#if defined(__WIN__) + static HANDLE LibJvm; // Handle to the jvm DLL +#else // !__WIN__ + static void *LibJvm; // Handle for the jvm shared library +#endif // !__WIN__ + static CRTJVM CreateJavaVM; + static GETJVM GetCreatedJavaVMs; + PGLOBAL m_G; + TDBJDBC *m_Tdb; + JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) + JNIEnv *env; // Pointer to native interface + jclass jdi; // Pointer to the JdbcInterface class + jobject job; // The JdbcInterface class object + jmethodID xqid; // The ExecuteQuery method ID + jmethodID xuid; // The ExecuteUpdate method ID + jmethodID xid; // The Execute method ID + jmethodID grs; // The GetResult method ID + jmethodID readid; // The ReadNext method ID + jmethodID fetchid; // The Fetch method ID + jmethodID typid; // The ColumnType method ID + jmethodID prepid; // The CreatePrepStmt method ID + jmethodID xpid; // The ExecutePrep method ID + jmethodID pcid; // The ClosePrepStmt method ID + //DWORD m_LoginTimeout; +//DWORD m_QueryTimeout; +//DWORD m_UpdateOptions; + char m_IDQuoteChar[2]; + PSZ m_Driver; + PSZ m_Url; + PSZ m_User; + PSZ m_Pwd; + int m_Ncol; + int m_Aff; + int m_Rows; + int m_Fetch; + int m_RowsetSize; + jboolean m_Updatable; + jboolean m_Transact; + jboolean m_Scrollable; + bool m_Opened; + bool m_Full; +}; // end of JDBConn class definition diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index eae872b81cc77..d377b7d4b6324 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -3538,37 +3538,9 @@ void jsoncontains_path_deinit(UDF_INIT* initid) } // end of jsoncontains_path_deinit /*********************************************************************************/ -/* Set Json items of a Json document according to path. */ +/* This function is used by the json_set/insert/update_item functions. */ /*********************************************************************************/ -my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) -{ - unsigned long reslen, memlen; - int n = IsJson(args, 0); - - if (!(args->arg_count % 2)) { - strcpy(message, "This function must have an odd number of arguments"); - return true; - } else if (!n && args->arg_type[0] != STRING_RESULT) { - strcpy(message, "First argument must be a json item"); - return true; - } else - CalcLen(args, false, reslen, memlen); - - if (n == 2 && args->args[0]) { - char fn[_MAX_PATH]; - long fl; - - memcpy(fn, args->args[0], args->lengths[0]); - fn[args->lengths[0]] = 0; - fl = GetFileLength(fn); - memlen += fl * 3; - } else if (n != 3) - memlen += args->lengths[0] * 3; - - return JsonInit(initid, args, message, true, reslen, memlen); -} // end of json_set_item_init - -char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, +char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) { char *p, *path, *str = NULL; @@ -3586,12 +3558,16 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - if (!strcmp(result, "$insert")) + if (!strcmp(result, "$set")) + w = 0; + else if (!strcmp(result, "$insert")) w = 1; else if (!strcmp(result, "$update")) w = 2; - else - w = 0; + else { + PUSH_WARNING("Logical error, please contact CONNECT developer"); + goto err; + } // endelse // Save stack and allocation environment and prepare error return if (g->jump_level == MAX_JUMP) { @@ -3660,10 +3636,10 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, // Keep result of constant function g->Activityp = (PACTIVITY)str; - err: +err: g->jump_level--; - fin: +fin: if (!str) { *is_null = 1; *res_length = 0; @@ -3671,6 +3647,44 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, *res_length = strlen(str); return str; +} // end of handle_item + +/*********************************************************************************/ +/* Set Json items of a Json document according to path. */ +/*********************************************************************************/ +my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + unsigned long reslen, memlen; + int n = IsJson(args, 0); + + if (!(args->arg_count % 2)) { + strcpy(message, "This function must have an odd number of arguments"); + return true; + } else if (!n && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + if (n == 2 && args->args[0]) { + char fn[_MAX_PATH]; + long fl; + + memcpy(fn, args->args[0], args->lengths[0]); + fn[args->lengths[0]] = 0; + fl = GetFileLength(fn); + memlen += fl * 3; + } else if (n != 3) + memlen += args->lengths[0] * 3; + + return JsonInit(initid, args, message, true, reslen, memlen); +} // end of json_set_item_init + +char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *p) +{ + strcpy(result, "$set"); + return handle_item(initid, args, result, res_length, is_null, p); } // end of json_set_item void json_set_item_deinit(UDF_INIT* initid) @@ -3690,7 +3704,7 @@ char *json_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$insert"); - return json_set_item(initid, args, result, res_length, is_null, p); + return handle_item(initid, args, result, res_length, is_null, p); } // end of json_insert_item void json_insert_item_deinit(UDF_INIT* initid) @@ -3710,7 +3724,7 @@ char *json_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$update"); - return json_set_item(initid, args, result, res_length, is_null, p); + return handle_item(initid, args, result, res_length, is_null, p); } // end of json_update_item void json_update_item_deinit(UDF_INIT* initid) @@ -4706,14 +4720,9 @@ void jbin_item_merge_deinit(UDF_INIT* initid) } // end of jbin_item_merge_deinit /*********************************************************************************/ -/* Set Json items of a Json document according to path. */ +/* This function is used by the jbin_set/insert/update functions. */ /*********************************************************************************/ -my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) -{ - return json_set_item_init(initid, args, message); -} // end of jbin_set_item_init - -char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, +char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) { char *p, *path; @@ -4732,12 +4741,16 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - if (!strcmp(result, "$insert")) + if (!strcmp(result, "$set")) + w = 0; + else if (!strcmp(result, "$insert")) w = 1; else if (!strcmp(result, "$update")) w = 2; - else - w = 0; + else { + PUSH_WARNING("Logical error, please contact CONNECT developer"); + goto fin; + } // endelse if (!g->Xchk) { if (CheckMemory(g, initid, args, 1, true, false, true)) { @@ -4791,7 +4804,7 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, // Keep result of constant function g->Activityp = (PACTIVITY)bsp; - fin: +fin: if (!bsp) { *is_null = 1; *res_length = 0; @@ -4799,6 +4812,21 @@ char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, *res_length = sizeof(BSON); return (char*)bsp; +} // end of bin_handle_item + +/*********************************************************************************/ +/* Set Json items of a Json document according to path. */ +/*********************************************************************************/ +my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + return json_set_item_init(initid, args, message); +} // end of jbin_set_item_init + +char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *p) +{ + strcpy(result, "$set"); + return bin_handle_item(initid, args, result, res_length, is_null, p); } // end of jbin_set_item void jbin_set_item_deinit(UDF_INIT* initid) @@ -4818,7 +4846,7 @@ char *jbin_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$insert"); - return jbin_set_item(initid, args, result, res_length, is_null, p); + return bin_handle_item(initid, args, result, res_length, is_null, p); } // end of jbin_insert_item void jbin_insert_item_deinit(UDF_INIT* initid) @@ -4838,7 +4866,7 @@ char *jbin_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { strcpy(result, "$update"); - return jbin_set_item(initid, args, result, res_length, is_null, p); + return bin_handle_item(initid, args, result, res_length, is_null, p); } // end of jbin_update_item void jbin_update_item_deinit(UDF_INIT* initid) @@ -4999,3 +5027,30 @@ void json_serialize_deinit(UDF_INIT* initid) { JsonFreeMem((PGLOBAL)initid->ptr); } // end of json_serialize_deinit + +/*********************************************************************************/ +/* Utility function returning an environment variable value. */ +/*********************************************************************************/ +my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) +{ + if (args->arg_count != 1) { + strcpy(message, "Unique argument must be an environment variable name"); + return true; + } else + return false; + +} // end of envar_init + +char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *, char *) +{ + char *str, name[256]; + int n = MY_MIN(args->lengths[0], sizeof(name) - 1); + + memcpy(name, args->args[0], n); + name[n] = 0; + str = getenv(name); + *res_length = (str) ? strlen(str) : 0; + return str; +} // end of envar + diff --git a/storage/connect/jsonudf.h b/storage/connect/jsonudf.h index b7e9b8ecabb07..1406d9f2f2e94 100644 --- a/storage/connect/jsonudf.h +++ b/storage/connect/jsonudf.h @@ -218,8 +218,12 @@ extern "C" { DllExport my_bool json_serialize_init(UDF_INIT*, UDF_ARGS*, char*); DllExport char *json_serialize(UDF_EXEC_ARGS); DllExport void json_serialize_deinit(UDF_INIT*); + + DllExport my_bool envar_init(UDF_INIT*, UDF_ARGS*, char*); + DllExport char *envar(UDF_EXEC_ARGS); } // extern "C" + /*********************************************************************************/ /* Structure JPN. Used to make the locate path. */ /*********************************************************************************/ diff --git a/storage/connect/plgdbutl.cpp b/storage/connect/plgdbutl.cpp index 1ec1108c639f7..13c0dfd1e1892 100644 --- a/storage/connect/plgdbutl.cpp +++ b/storage/connect/plgdbutl.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 1998-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 1998-2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -46,9 +46,9 @@ #else // !__WIN__ #include #include -#if defined(THREAD) +//#if defined(THREAD) #include -#endif // THREAD +//#endif // THREAD #include #define BIGMEM 2147483647 // Max int value #endif // !__WIN__ @@ -69,17 +69,6 @@ #include "valblk.h" #include "rcmsg.h" -/***********************************************************************/ -/* Macro or external routine definition */ -/***********************************************************************/ -#if defined(THREAD) -#if defined(__WIN__) -extern CRITICAL_SECTION parsec; // Used calling the Flex parser -#else // !__WIN__ -extern pthread_mutex_t parmut; -#endif // !__WIN__ -#endif // THREAD - /***********************************************************************/ /* DB static variables. */ /***********************************************************************/ @@ -90,6 +79,12 @@ extern "C" { extern char version[]; } // extern "C" +#if defined(__WIN__) +extern CRITICAL_SECTION parsec; // Used calling the Flex parser +#else // !__WIN__ +extern pthread_mutex_t parmut; +#endif // !__WIN__ + // The debug trace used by the main thread FILE *pfile = NULL; @@ -702,21 +697,21 @@ PDTP MakeDateFormat(PGLOBAL g, PSZ dfmt, bool in, bool out, int flag) /* Call the FLEX generated parser. In multi-threading mode the next */ /* instruction is included in an Enter/LeaveCriticalSection bracket. */ /*********************************************************************/ -#if defined(THREAD) + //#if defined(THREAD) #if defined(__WIN__) EnterCriticalSection((LPCRITICAL_SECTION)&parsec); #else // !__WIN__ pthread_mutex_lock(&parmut); #endif // !__WIN__ -#endif // THREAD +//#endif // THREAD rc = fmdflex(pdp); -#if defined(THREAD) +//#if defined(THREAD) #if defined(__WIN__) LeaveCriticalSection((LPCRITICAL_SECTION)&parsec); #else // !__WIN__ pthread_mutex_unlock(&parmut); #endif // !__WIN__ -#endif // THREAD +//#endif // THREAD if (trace) htrc("Done: in=%s out=%s rc=%d\n", SVP(pdp->InFmt), SVP(pdp->OutFmt), rc); @@ -1102,7 +1097,8 @@ char *GetAmName(PGLOBAL g, AMT am, void *memp) case TYPE_AM_DOM: strcpy(amn, "DOM"); break; case TYPE_AM_DIR: strcpy(amn, "DIR"); break; case TYPE_AM_ODBC: strcpy(amn, "ODBC"); break; - case TYPE_AM_MAC: strcpy(amn, "MAC"); break; + case TYPE_AM_JDBC: strcpy(amn, "JDBC"); break; + case TYPE_AM_MAC: strcpy(amn, "MAC"); break; case TYPE_AM_OEM: strcpy(amn, "OEM"); break; case TYPE_AM_OUT: strcpy(amn, "OUT"); break; default: sprintf(amn, "OEM(%d)", am); diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp index e455bc8f1a520..2c8ada52e6f5c 100644 --- a/storage/connect/reldef.cpp +++ b/storage/connect/reldef.cpp @@ -305,7 +305,7 @@ int TABDEF::GetColCatInfo(PGLOBAL g) case TAB_OEM: poff = 0; // Offset represents an independant flag break; - default: // VCT PLG ODBC MYSQL WMI... + default: // VCT PLG ODBC JDBC MYSQL WMI... poff = 0; // NA break; } // endswitch tc @@ -514,10 +514,11 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g) } // endif getdef #else // !__WIN__ const char *error = NULL; - Dl_info dl_info; #if 0 // Don't know what all this stuff does - // The OEM lib must retrieve exported CONNECT variables + Dl_info dl_info; + + // The OEM lib must retrieve exported CONNECT variables if (dladdr(&connect_hton, &dl_info)) { if (dlopen(dl_info.dli_fname, RTLD_NOLOAD | RTLD_NOW | RTLD_GLOBAL) == 0) { error = dlerror(); diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp new file mode 100644 index 0000000000000..37850ce6358cc --- /dev/null +++ b/storage/connect/tabjdbc.cpp @@ -0,0 +1,1707 @@ +/************* TabJDBC C++ Program Source Code File (.CPP) *************/ +/* PROGRAM NAME: TABJDBC */ +/* ------------- */ +/* Version 1.0 */ +/* */ +/* COPYRIGHT: */ +/* ---------- */ +/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* */ +/* WHAT THIS PROGRAM DOES: */ +/* ----------------------- */ +/* This program are the TABJDBC class DB execution routines. */ +/* */ +/* WHAT YOU NEED TO COMPILE THIS PROGRAM: */ +/* -------------------------------------- */ +/* */ +/* REQUIRED FILES: */ +/* --------------- */ +/* TABJDBC.CPP - Source code */ +/* PLGDBSEM.H - DB application declaration file */ +/* TABJDBC.H - TABJDBC classes declaration file */ +/* GLOBAL.H - Global declaration file */ +/* */ +/* REQUIRED LIBRARIES: */ +/* ------------------- */ +/* Large model C library */ +/* */ +/* REQUIRED PROGRAMS: */ +/* ------------------ */ +/* IBM, Borland, GNU or Microsoft C++ Compiler and Linker */ +/* */ +/***********************************************************************/ + +/***********************************************************************/ +/* Include relevant MariaDB header file. */ +/***********************************************************************/ +#include "my_global.h" +#include "sql_class.h" +#if defined(__WIN__) +#include +#include +#if defined(__BORLANDC__) +#define __MFC_COMPAT__ // To define min/max as macro +#endif +//#include +#include +#else +#if defined(UNIX) +#include +#define NODW +#include "osutil.h" +#else +#include +#endif +#include +#endif + +/***********************************************************************/ +/* Include application header files: */ +/* global.h is header containing all global declarations. */ +/* plgdbsem.h is header containing the DB application declarations. */ +/* kindex.h is kindex header that also includes tabdos.h. */ +/* tabJDBC.h is header containing the TABJDBC class declarations. */ +/* JDBConn.h is header containing JDBC connection declarations. */ +/***********************************************************************/ +#include "global.h" +#include "plgdbsem.h" +#include "mycat.h" +#include "xtable.h" +#include "jdbccat.h" +#include "tabjdbc.h" +#include "tabmul.h" +#include "reldef.h" +#include "tabcol.h" +#include "valblk.h" +#include "ha_connect.h" + +#include "sql_string.h" + +/***********************************************************************/ +/* DB static variables. */ +/***********************************************************************/ +// int num_read, num_there, num_eq[2], num_nf; // Statistics +extern int num_read, num_there, num_eq[2]; // Statistics + +/***********************************************************************/ +/* External function. */ +/***********************************************************************/ +bool ExactInfo(void); + +/* -------------------------- Class JDBCDEF -------------------------- */ + +/***********************************************************************/ +/* Constructor. */ +/***********************************************************************/ +JDBCDEF::JDBCDEF(void) +{ + Driver = Url = Tabname = Tabschema = Username = NULL; + Password = Tabcat = Tabtype = Srcdef = Qchar = Qrystr = Sep = NULL; + Options = Quoted = Maxerr = Maxres = Memory = 0; + Scrollable = Xsrc = false; +} // end of JDBCDEF constructor + +/***********************************************************************/ +/* DefineAM: define specific AM block values from JDBC file. */ +/***********************************************************************/ +bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) +{ + Driver = GetStringCatInfo(g, "Driver", NULL); + Desc = Url = GetStringCatInfo(g, "Connect", NULL); + + if (!Url && !Catfunc) { + // Look in the option list (deprecated) + Url = GetStringCatInfo(g, "Url", NULL); + + if (!Url) { + sprintf(g->Message, "Missing URL for JDBC table %s", Name); + return true; + } // endif Url + + } // endif Connect + + Tabname = GetStringCatInfo(g, "Name", + (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); + Tabname = GetStringCatInfo(g, "Tabname", Tabname); + Tabschema = GetStringCatInfo(g, "Dbname", NULL); + Tabschema = GetStringCatInfo(g, "Schema", Tabschema); + Tabcat = GetStringCatInfo(g, "Qualifier", NULL); + Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); + Tabtype = GetStringCatInfo(g, "Tabtype", NULL); + Username = GetStringCatInfo(g, "User", NULL); + Password = GetStringCatInfo(g, "Password", NULL); + + if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) + Read_Only = true; + + Qrystr = GetStringCatInfo(g, "Query_String", "?"); + Sep = GetStringCatInfo(g, "Separator", NULL); + Xsrc = GetBoolCatInfo("Execsrc", FALSE); + Maxerr = GetIntCatInfo("Maxerr", 0); + Maxres = GetIntCatInfo("Maxres", 0); + Quoted = GetIntCatInfo("Quoted", 0); +//Options = JDBConn::noJDBCDialog; +//Options = JDBConn::noJDBCDialog | JDBConn::useCursorLib; +//Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); +//Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); + Scrollable = GetBoolCatInfo("Scrollable", false); + Memory = GetIntCatInfo("Memory", 0); + Pseudo = 2; // FILID is Ok but not ROWID + return false; +} // end of DefineAM + +/***********************************************************************/ +/* GetTable: makes a new Table Description Block. */ +/***********************************************************************/ +PTDB JDBCDEF::GetTable(PGLOBAL g, MODE m) +{ + PTDBASE tdbp = NULL; + + /*********************************************************************/ + /* Allocate a TDB of the proper type. */ + /* Column blocks will be allocated only when needed. */ + /*********************************************************************/ + if (Xsrc) + tdbp = new(g)TDBXJDC(this); + else switch (Catfunc) { + case FNC_COL: + tdbp = new(g)TDBJDBCL(this); + break; +#if 0 + case FNC_DSN: + tdbp = new(g)TDBJSRC(this); + break; +#endif // 0 + case FNC_TABLE: + tdbp = new(g)TDBJTB(this); + break; + case FNC_DRIVER: + tdbp = new(g)TDBJDRV(this); + break; + default: + tdbp = new(g)TDBJDBC(this); + + if (Multiple == 1) + tdbp = new(g)TDBMUL(tdbp); + else if (Multiple == 2) + strcpy(g->Message, "NO_JDBC_MUL"); + + } // endswitch Catfunc + + return tdbp; +} // end of GetTable + +/***********************************************************************/ +/* The MySQL and MariaDB JDBC drivers return by default a result set */ +/* containing the entire result of the executed query. This can be an */ +/* issue for big tables and memory error can occur. An alternative is */ +/* to use streaming (reading one row at a time) but to specify this, */ +/* a fech size of the integer min value must be send to the driver. */ +/***********************************************************************/ +int JDBCPARM::CheckSize(int rows) +{ + if (Url && rows == 1) { + // Are we connected to a MySQL JDBC connector? + bool b = (!strncmp(Url, "jdbc:mysql:", 11) || + !strncmp(Url, "jdbc:mariadb:", 13)); + return b ? INT_MIN32 : rows; + } else + return rows; + +} // end of CheckSize + +/* -------------------------- Class TDBJDBC -------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBJDBC class. */ +/***********************************************************************/ +TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) +{ + Jcp = NULL; + Cnp = NULL; + + if (tdp) { + Ops.Driver = tdp->Driver; + Ops.Url = tdp->Url; + TableName = tdp->Tabname; + Schema = tdp->Tabschema; + Ops.User = tdp->Username; + Ops.Pwd = tdp->Password; + Catalog = tdp->Tabcat; + Srcdef = tdp->Srcdef; + Qrystr = tdp->Qrystr; + Sep = tdp->GetSep(); + Options = tdp->Options; +// Ops.Cto = tdp->Cto; +// Ops.Qto = tdp->Qto; + Quoted = MY_MAX(0, tdp->GetQuoted()); + Rows = tdp->GetElemt(); + Memory = tdp->Memory; + Ops.Scrollable = tdp->Scrollable; + } else { + TableName = NULL; + Schema = NULL; + Ops.Driver = NULL; + Ops.Url = NULL; + Ops.User = NULL; + Ops.Pwd = NULL; + Catalog = NULL; + Srcdef = NULL; + Qrystr = NULL; + Sep = 0; + Options = 0; +// Ops.Cto = DEFAULT_LOGIN_TIMEOUT; +// Ops.Qto = DEFAULT_QUERY_TIMEOUT; + Quoted = 0; + Rows = 0; + Memory = 0; + Ops.Scrollable = false; + } // endif tdp + + Quote = NULL; + Query = NULL; + Count = NULL; +//Where = NULL; + MulConn = NULL; + DBQ = NULL; + Qrp = NULL; + Fpos = 0; + Curpos = 0; + AftRows = 0; + CurNum = 0; + Rbuf = 0; + BufSize = 0; + Ncol = 0; + Nparm = 0; + Placed = false; + Werr = false; + Rerr = false; + Ops.Fsize = Ops.CheckSize(Rows); +} // end of TDBJDBC standard constructor + +TDBJDBC::TDBJDBC(PTDBJDBC tdbp) : TDBASE(tdbp) +{ + Jcp = tdbp->Jcp; // is that right ? + Cnp = tdbp->Cnp; + TableName = tdbp->TableName; + Schema = tdbp->Schema; + Ops = tdbp->Ops; + Catalog = tdbp->Catalog; + Srcdef = tdbp->Srcdef; + Qrystr = tdbp->Qrystr; + Memory = tdbp->Memory; +//Scrollable = tdbp->Scrollable; + Quote = tdbp->Quote; + Query = tdbp->Query; + Count = tdbp->Count; +//Where = tdbp->Where; + MulConn = tdbp->MulConn; + DBQ = tdbp->DBQ; + Options = tdbp->Options; + Quoted = tdbp->Quoted; + Rows = tdbp->Rows; + Fpos = 0; + Curpos = 0; + AftRows = 0; + CurNum = 0; + Rbuf = 0; + BufSize = tdbp->BufSize; + Nparm = tdbp->Nparm; + Qrp = tdbp->Qrp; + Placed = false; +} // end of TDBJDBC copy constructor + +// Method +PTDB TDBJDBC::CopyOne(PTABS t) +{ + PTDB tp; + PJDBCCOL cp1, cp2; + PGLOBAL g = t->G; // Is this really useful ??? + + tp = new(g)TDBJDBC(this); + + for (cp1 = (PJDBCCOL)Columns; cp1; cp1 = (PJDBCCOL)cp1->GetNext()) { + cp2 = new(g)JDBCCOL(cp1, tp); // Make a copy + NewPointer(t, cp1, cp2); + } // endfor cp1 + + return tp; +} // end of CopyOne + +/***********************************************************************/ +/* Allocate JDBC column description block. */ +/***********************************************************************/ +PCOL TDBJDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) +{ + return new(g)JDBCCOL(cdp, this, cprec, n); +} // end of MakeCol + +/******************************************************************/ +/* Convert an UTF-8 string to latin characters. */ +/******************************************************************/ +int TDBJDBC::Decode(char *txt, char *buf, size_t n) +{ + uint dummy_errors; + uint32 len= copy_and_convert(buf, n, &my_charset_latin1, + txt, strlen(txt), + &my_charset_utf8_general_ci, + &dummy_errors); + buf[len]= '\0'; + return 0; +} // end of Decode + +/***********************************************************************/ +/* MakeSQL: make the SQL statement use with JDBC connection. */ +/* TODO: when implementing EOM filtering, column only used in local */ +/* filter should be removed from column list. */ +/***********************************************************************/ +bool TDBJDBC::MakeSQL(PGLOBAL g, bool cnt) +{ + char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3]; + int len; + bool oom = false, first = true; + PTABLE tablep = To_Table; + PCOL colp; + + if (Srcdef) { + Query = new(g)STRING(g, 0, Srcdef); + return false; + } // endif Srcdef + + // Allocate the string used to contain the Query + Query = new(g)STRING(g, 1023, "SELECT "); + + if (!cnt) { + if (Columns) { + // Normal SQL statement to retrieve results + for (colp = Columns; colp; colp = colp->GetNext()) + if (!colp->IsSpecial()) { + if (!first) + oom |= Query->Append(", "); + else + first = false; + + // Column name can be encoded in UTF-8 + Decode(colp->GetName(), buf, sizeof(buf)); + + if (Quote) { + // Put column name between identifier quotes in case in contains blanks + oom |= Query->Append(Quote); + oom |= Query->Append(buf); + oom |= Query->Append(Quote); + } else + oom |= Query->Append(buf); + + ((PJDBCCOL)colp)->Rank = ++Ncol; + } // endif colp + + } else + // !Columns can occur for queries such that sql count(*) from... + // for which we will count the rows from sql * from... + oom |= Query->Append('*'); + + } else + // SQL statement used to retrieve the size of the result + oom |= Query->Append("count(*)"); + + oom |= Query->Append(" FROM "); + + if (Catalog && *Catalog) + catp = Catalog; + + if (tablep->GetSchema()) + schmp = (char*)tablep->GetSchema(); + else if (Schema && *Schema) + schmp = Schema; + + if (catp) { + oom |= Query->Append(catp); + + if (schmp) { + oom |= Query->Append('.'); + oom |= Query->Append(schmp); + } // endif schmp + + oom |= Query->Append('.'); + } else if (schmp) { + oom |= Query->Append(schmp); + oom |= Query->Append('.'); + } // endif schmp + + // Table name can be encoded in UTF-8 + Decode(TableName, buf, sizeof(buf)); + + if (Quote) { + // Put table name between identifier quotes in case in contains blanks + oom |= Query->Append(Quote); + oom |= Query->Append(buf); + oom |= Query->Append(Quote); + } else + oom |= Query->Append(buf); + + len = Query->GetLength(); + + if (To_CondFil) { + if (Mode == MODE_READ) { + oom |= Query->Append(" WHERE "); + oom |= Query->Append(To_CondFil->Body); + len = Query->GetLength() + 1; + } else + len += (strlen(To_CondFil->Body) + 256); + + } else + len += ((Mode == MODE_READX) ? 256 : 1); + + if (oom || Query->Resize(len)) { + strcpy(g->Message, "MakeSQL: Out of memory"); + return true; + } // endif oom + + if (trace) + htrc("Query=%s\n", Query->GetStr()); + + return false; +} // end of MakeSQL + +/***********************************************************************/ +/* MakeInsert: make the Insert statement used with JDBC connection. */ +/***********************************************************************/ +bool TDBJDBC::MakeInsert(PGLOBAL g) +{ + char *schmp = NULL, *catp = NULL, buf[NAM_LEN * 3]; + int len = 0; + uint pos; + bool b = false, oom = false; + PTABLE tablep = To_Table; + PCOL colp; + + for (colp = Columns; colp; colp = colp->GetNext()) + if (colp->IsSpecial()) { + strcpy(g->Message, "No JDBC special columns"); + return true; + } else { + // Column name can be encoded in UTF-8 + Decode(colp->GetName(), buf, sizeof(buf)); + len += (strlen(buf) + 6); // comma + quotes + valist + ((PJDBCCOL)colp)->Rank = ++Nparm; + } // endif colp + + // Below 32 is enough to contain the fixed part of the query + if (Catalog && *Catalog) + catp = Catalog; + + if (catp) + len += strlen(catp) + 1; + + if (tablep->GetSchema()) + schmp = (char*)tablep->GetSchema(); + else if (Schema && *Schema) + schmp = Schema; + + if (schmp) + len += strlen(schmp) + 1; + + // Table name can be encoded in UTF-8 + Decode(TableName, buf, sizeof(buf)); + len += (strlen(buf) + 32); + Query = new(g)STRING(g, len, "INSERT INTO "); + + if (catp) { + oom |= Query->Append(catp); + + if (schmp) { + oom |= Query->Append('.'); + oom |= Query->Append(schmp); + } // endif schmp + + oom |= Query->Append('.'); + } else if (schmp) { + oom |= Query->Append(schmp); + oom |= Query->Append('.'); + } // endif schmp + + if (Quote) { + // Put table name between identifier quotes in case in contains blanks + oom |= Query->Append(Quote); + oom |= Query->Append(buf); + oom |= Query->Append(Quote); + } else + oom |= Query->Append(buf); + + oom |= Query->Append('('); + + for (colp = Columns; colp; colp = colp->GetNext()) { + if (b) + oom |= Query->Append(", "); + else + b = true; + + // Column name can be in UTF-8 encoding + Decode(colp->GetName(), buf, sizeof(buf)); + + if (Quote) { + // Put column name between identifier quotes in case in contains blanks + oom |= Query->Append(Quote); + oom |= Query->Append(buf); + oom |= Query->Append(Quote); + } else + oom |= Query->Append(buf); + + } // endfor colp + + if ((oom |= Query->Append(") VALUES ("))) { + strcpy(g->Message, "MakeInsert: Out of memory"); + return true; + } else // in case prepared statement fails + pos = Query->GetLength(); + + // Make prepared statement + for (int i = 0; i < Nparm; i++) + oom |= Query->Append("?,"); + + if (oom) { + strcpy(g->Message, "MakeInsert: Out of memory"); + return true; + } else + Query->RepLast(')'); + + // Now see if we can use prepared statement + if (Jcp->PrepareSQL(Query->GetStr())) + Query->Truncate(pos); // Restore query to not prepared + else + Prepared = true; + + return false; +} // end of MakeInsert + +/***********************************************************************/ +/* JDBC Set Parameter function. */ +/***********************************************************************/ +bool TDBJDBC::SetParameters(PGLOBAL g) +{ + PJDBCCOL colp; + + for (colp = (PJDBCCOL)Columns; colp; colp = (PJDBCCOL)colp->Next) + if (Jcp->SetParam(colp)) + return true; + + return false; +} // end of SetParameters + +/***********************************************************************/ +/* MakeCommand: make the Update or Delete statement to send to the */ +/* MySQL server. Limited to remote values and filtering. */ +/***********************************************************************/ +bool TDBJDBC::MakeCommand(PGLOBAL g) +{ + char *p, *stmt, name[68], *body = NULL, *qc = Jcp->GetQuoteChar(); + char *qrystr = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 1); + bool qtd = Quoted > 0; + int i = 0, k = 0; + + // Make a lower case copy of the originale query and change + // back ticks to the data source identifier quoting character + do { + qrystr[i] = (Qrystr[i] == '`') ? *qc : tolower(Qrystr[i]); + } while (Qrystr[i++]); + + if (To_CondFil && (p = strstr(qrystr, " where "))) { + p[7] = 0; // Remove where clause + Qrystr[(p - qrystr) + 7] = 0; + body = To_CondFil->Body; + stmt = (char*)PlugSubAlloc(g, NULL, strlen(qrystr) + + strlen(body) + 64); + } else + stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64); + + // Check whether the table name is equal to a keyword + // If so, it must be quoted in the original query + strlwr(strcat(strcat(strcpy(name, " "), Name), " ")); + + if (!strstr(" update delete low_priority ignore quick from ", name)) + strlwr(strcpy(name, Name)); // Not a keyword + else + strlwr(strcat(strcat(strcpy(name, qc), Name), qc)); + + if ((p = strstr(qrystr, name))) { + for (i = 0; i < p - qrystr; i++) + stmt[i] = (Qrystr[i] == '`') ? *qc : Qrystr[i]; + + stmt[i] = 0; + k = i + (int)strlen(Name); + + if (qtd && *(p-1) == ' ') + strcat(strcat(strcat(stmt, qc), TableName), qc); + else + strcat(stmt, TableName); + + i = (int)strlen(stmt); + + do { + stmt[i++] = (Qrystr[k] == '`') ? *qc : Qrystr[k]; + } while (Qrystr[k++]); + + if (body) + strcat(stmt, body); + + } else { + sprintf(g->Message, "Cannot use this %s command", + (Mode == MODE_UPDATE) ? "UPDATE" : "DELETE"); + return NULL; + } // endif p + + Query = new(g)STRING(g, 0, stmt); + return (!Query->GetSize()); +} // end of MakeCommand + +/***********************************************************************/ +/* ResetSize: call by TDBMUL when calculating size estimate. */ +/***********************************************************************/ +void TDBJDBC::ResetSize(void) +{ + MaxSize = -1; + + if (Jcp && Jcp->IsOpen()) + Jcp->Close(); + +} // end of ResetSize + +/***********************************************************************/ +/* JDBC Cardinality: returns table size in number of rows. */ +/***********************************************************************/ +int TDBJDBC::Cardinality(PGLOBAL g) +{ + if (!g) + return (Mode == MODE_ANY && !Srcdef) ? 1 : 0; + +#if 0 + if (Cardinal < 0 && Mode == MODE_ANY && !Srcdef && ExactInfo()) { + // Info command, we must return the exact table row number + char qry[96], tbn[64]; + JDBConn *jcp = new(g)JDBConn(g, this); + + if (jcp->Open(&Ops) == RC_FX) + return -1; + + // Table name can be encoded in UTF-8 + Decode(TableName, tbn, sizeof(tbn)); + strcpy(qry, "SELECT COUNT(*) FROM "); + + if (Quote) + strcat(strcat(strcat(qry, Quote), tbn), Quote); + else + strcat(qry, tbn); + + // Allocate a Count(*) column (must not use the default constructor) + Cnp = new(g)JDBCCOL; + Cnp->InitValue(g); + + if ((Cardinal = jcp->GetResultSize(qry, Cnp)) < 0) + return -3; + + jcp->Close(); + } else +#endif // 0 + Cardinal = 10; // To make MariaDB happy + + return Cardinal; +} // end of Cardinality + +/***********************************************************************/ +/* JDBC GetMaxSize: returns table size estimate in number of lines. */ +/***********************************************************************/ +int TDBJDBC::GetMaxSize(PGLOBAL g) +{ + if (MaxSize < 0) { + if (Mode == MODE_DELETE) + // Return 0 in mode DELETE in case of delete all. + MaxSize = 0; + else if (!Cardinality(NULL)) + MaxSize = 10; // To make MySQL happy + else if ((MaxSize = Cardinality(g)) < 0) + MaxSize = 12; // So we can see an error occured + + } // endif MaxSize + + return MaxSize; +} // end of GetMaxSize + +/***********************************************************************/ +/* Return max size value. */ +/***********************************************************************/ +int TDBJDBC::GetProgMax(PGLOBAL g) +{ + return GetMaxSize(g); +} // end of GetProgMax + +/***********************************************************************/ +/* JDBC Access Method opening routine. */ +/* New method now that this routine is called recursively (last table */ +/* first in reverse order): index blocks are immediately linked to */ +/* join block of next table if it exists or else are discarted. */ +/***********************************************************************/ +bool TDBJDBC::OpenDB(PGLOBAL g) +{ + bool rc = true; + + if (trace) + htrc("JDBC OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n", + this, Tdb_No, Use, Mode); + + if (Use == USE_OPEN) { + /*******************************************************************/ + /* Table already open, just replace it at its beginning. */ + /*******************************************************************/ + if (Memory == 1) { + if ((Qrp = Jcp->AllocateResult(g))) + Memory = 2; // Must be filled + else + Memory = 0; // Allocation failed, don't use it + + } else if (Memory == 2) + Memory = 3; // Ok to use memory result + + if (Memory < 3) { + // Method will depend on cursor type + if ((Rbuf = Jcp->Rewind(Query->GetStr())) < 0) + if (Mode != MODE_READX) { + Jcp->Close(); + return true; + } else + Rbuf = 0; + + } else + Rbuf = Qrp->Nblin; + + CurNum = 0; + Fpos = 0; + Curpos = 1; + return false; + } // endif use + + /*********************************************************************/ + /* Open an JDBC connection for this table. */ + /* Note: this may not be the proper way to do. Perhaps it is better */ + /* to test whether a connection is already open for this datasource */ + /* and if so to allocate just a new result set. But this only for */ + /* drivers allowing concurency in getting results ??? */ + /*********************************************************************/ + if (!Jcp) + Jcp = new(g)JDBConn(g, this); + else if (Jcp->IsOpen()) + Jcp->Close(); + + if (Jcp->Open(&Ops) == RC_FX) + return true; + else if (Quoted) + Quote = Jcp->GetQuoteChar(); + + Use = USE_OPEN; // Do it now in case we are recursively called + + /*********************************************************************/ + /* Make the command and allocate whatever is used for getting results. */ + /*********************************************************************/ + if (Mode == MODE_READ || Mode == MODE_READX) { + if (Memory > 1 && !Srcdef) { + int n; + + if (!MakeSQL(g, true)) { + // Allocate a Count(*) column + Cnp = new(g)JDBCCOL; + Cnp->InitValue(g); + + if ((n = Jcp->GetResultSize(Query->GetStr(), Cnp)) < 0) { + sprintf(g->Message, "Cannot get result size rc=%d", n); + return true; + } else if (n) { + Jcp->m_Rows = n; + + if ((Qrp = Jcp->AllocateResult(g))) + Memory = 2; // Must be filled + else { + strcpy(g->Message, "Result set memory allocation failed"); + return true; + } // endif n + + } else // Void result + Memory = 0; + + Jcp->m_Rows = 0; + } else + return true; + + } // endif Memory + + if (!(rc = MakeSQL(g, false))) { +// for (PJDBCCOL colp = (PJDBCCOL)Columns; colp; colp = (PJDBCCOL)colp->GetNext()) +// if (!colp->IsSpecial()) +// colp->AllocateBuffers(g, Rows); + + rc = (Mode == MODE_READ) + ? (Jcp->ExecuteQuery(Query->GetStr()) != RC_OK) + : false; + } // endif rc + + } else if (Mode == MODE_INSERT) { +#if 0 + if (!(rc = MakeInsert(g))) { + if (Nparm != Jcp->PrepareSQL(Query->GetStr())) { + strcpy(g->Message, MSG(PARM_CNT_MISS)); + rc = true; + } else + rc = BindParameters(g); + + } // endif rc +#endif // 0 + rc = MakeInsert(g); + } else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { + rc = false; // wait for CheckCond before calling MakeCommand(g); + } else + sprintf(g->Message, "Invalid mode %d", Mode); + + if (rc) { + Jcp->Close(); + return true; + } // endif rc + + /*********************************************************************/ + /* Reset statistics values. */ + /*********************************************************************/ + num_read = num_there = num_eq[0] = num_eq[1] = 0; + return false; +} // end of OpenDB + +/***********************************************************************/ +/* GetRecpos: return the position of last read record. */ +/***********************************************************************/ +int TDBJDBC::GetRecpos(void) +{ + return Fpos; +} // end of GetRecpos + +/***********************************************************************/ +/* SetRecpos: set the position of next read record. */ +/***********************************************************************/ +bool TDBJDBC::SetRecpos(PGLOBAL g, int recpos) +{ + if (Jcp->m_Full) { + Fpos = 0; +// CurNum = 0; + CurNum = 1; + } else if (Memory == 3) { +// Fpos = recpos; +// CurNum = -1; + Fpos = 0; + CurNum = recpos; + } else if (Ops.Scrollable) { + // Is new position in the current row set? +// if (recpos >= Curpos && recpos < Curpos + Rbuf) { +// CurNum = recpos - Curpos; +// Fpos = 0; + if (recpos > 0 && recpos <= Rbuf) { + CurNum = recpos; + Fpos = recpos; + } else { + strcpy(g->Message, "Scrolling out of row set NIY"); + return true; + } // endif recpos + + } else { + strcpy(g->Message, "This action requires a scrollable cursor"); + return true; + } // endif's + + // Indicate the table position was externally set + Placed = true; + return false; +} // end of SetRecpos + +/***********************************************************************/ +/* Data Base indexed read routine for JDBC access method. */ +/***********************************************************************/ +bool TDBJDBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) +{ + char c = Quote ? *Quote : 0; + int rc, oldlen = Query->GetLength(); + PHC hc = To_Def->GetHandler(); + + if (!(kr || hc->end_range) || op == OP_NEXT || + Mode == MODE_UPDATE || Mode == MODE_DELETE) { + if (!kr && Mode == MODE_READX) { + // This is a false indexed read + rc = Jcp->ExecuteQuery((char*)Query->GetStr()); + Mode = MODE_READ; + Rows = 1; // ??? + return (rc != RC_OK); + } // endif key + + return false; + } else { + if (hc->MakeKeyWhere(g, Query, op, c, kr)) + return true; + + if (To_CondFil) { + if (To_CondFil->Idx != hc->active_index) { + To_CondFil->Idx = hc->active_index; + To_CondFil->Body= (char*)PlugSubAlloc(g, NULL, 0); + *To_CondFil->Body= 0; + + if ((To_CondFil = hc->CheckCond(g, To_CondFil, To_CondFil->Cond))) + PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1); + + } // endif active_index + + if (To_CondFil) + if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) { + strcpy(g->Message, "Readkey: Out of memory"); + return true; + } // endif Append + + } // endif To_Condfil + + Mode = MODE_READ; + } // endif's op + + if (trace) + htrc("JDBC ReadKey: Query=%s\n", Query->GetStr()); + + rc = Jcp->ExecuteQuery((char*)Query->GetStr()); + Query->Truncate(oldlen); + Rows = 1; // ??? + return (rc != RC_OK); +} // end of ReadKey + +/***********************************************************************/ +/* Data Base read routine for JDBC access method. */ +/***********************************************************************/ +int TDBJDBC::ReadDB(PGLOBAL g) +{ + int rc; + + if (trace > 1) + htrc("JDBC ReadDB: R%d Mode=%d key=%p link=%p Kindex=%p\n", + GetTdb_No(), Mode, To_Key_Col, To_Link, To_Kindex); + + if (Mode == MODE_UPDATE || Mode == MODE_DELETE) { + if (!Query && MakeCommand(g)) + return RC_FX; + + // Send the UPDATE/DELETE command to the remote table + rc = Jcp->ExecuteUpdate(Query->GetStr()); + + if (rc == RC_OK) { + AftRows = Jcp->m_Aff; + return RC_EF; // Nothing else to do + } else { + Werr = true; + return RC_FX; + } // endif rc + + } // endif Mode + + if (To_Kindex) { + // Direct access of JDBC tables is not implemented + strcpy(g->Message, "No JDBC direct access"); + return RC_FX; + } // endif To_Kindex + + /*********************************************************************/ + /* Now start the reading process. */ + /* Here is the place to fetch the line(s). */ + /*********************************************************************/ + if (Placed) { + if (Fpos && CurNum >= 0) + Rbuf = Jcp->Fetch((Curpos = Fpos)); + else + Fpos = CurNum; + + rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; + Placed = false; + } else { + if (Memory != 3) { + if (++CurNum >= Rbuf) { + Rbuf = Jcp->Fetch(); + Curpos = Fpos + 1; + CurNum = 0; + } // endif CurNum + + rc = (Rbuf > 0) ? RC_OK : (Rbuf == 0) ? RC_EF : RC_FX; + } else // Getting result from memory + rc = (Fpos < Qrp->Nblin) ? RC_OK : RC_EF; + + if (rc == RC_OK) { + if (Memory == 2) + Qrp->Nblin++; + + Fpos++; // Used for memory and pos + } // endif rc + + } // endif placed + + if (trace > 1) + htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc); + + return rc; +} // end of ReadDB + +/***********************************************************************/ +/* Data Base Insert write routine for JDBC access method. */ +/***********************************************************************/ +int TDBJDBC::WriteDB(PGLOBAL g) +{ + int rc; + + if (Prepared) { + if (SetParameters(g)) { + Werr = true; + rc = RC_FX; + } else if ((rc = Jcp->ExecuteSQL()) == RC_OK) + AftRows += Jcp->m_Aff; + else + Werr = true; + + return rc; + } // endif Prepared + + // Statement was not prepared, we must construct and execute + // an insert query for each line to insert + uint len = Query->GetLength(); + char buf[64]; + bool oom = false; + + // Make the Insert command value list + for (PCOL colp = Columns; colp; colp = colp->GetNext()) { + if (!colp->GetValue()->IsNull()) { + char *s = colp->GetValue()->GetCharString(buf); + + if (colp->GetResultType() == TYPE_STRING) + oom |= Query->Append_quoted(s); + else if (colp->GetResultType() == TYPE_DATE) { + DTVAL *dtv = (DTVAL*)colp->GetValue(); + + if (dtv->IsFormatted()) + oom |= Query->Append_quoted(s); + else + oom |= Query->Append(s); + + } else + oom |= Query->Append(s); + + } else + oom |= Query->Append("NULL"); + + oom |= Query->Append(','); + } // endfor colp + + if (unlikely(oom)) { + strcpy(g->Message, "WriteDB: Out of memory"); + return RC_FX; + } // endif oom + + Query->RepLast(')'); + rc = Jcp->ExecuteUpdate(Query->GetStr()); + Query->Truncate(len); // Restore query + + if (rc == RC_OK) + AftRows += Jcp->m_Aff; + else + Werr = true; + + return rc; +} // end of WriteDB + +/***********************************************************************/ +/* Data Base delete line routine for JDBC access method. */ +/***********************************************************************/ +int TDBJDBC::DeleteDB(PGLOBAL g, int irc) +{ + if (irc == RC_FX) { + if (!Query && MakeCommand(g)) + return RC_FX; + + // Send the DELETE (all) command to the remote table + if (Jcp->ExecuteUpdate(Query->GetStr()) == RC_OK) { + AftRows = Jcp->m_Aff; + sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); + + if (trace) + htrc("%s\n", g->Message); + + PushWarning(g, this, 0); // 0 means a Note + return RC_OK; // This is a delete all + } else + return RC_FX; // Error + + } else + return RC_OK; // Ignore + +} // end of DeleteDB + +/***********************************************************************/ +/* Data Base close routine for JDBC access method. */ +/***********************************************************************/ +void TDBJDBC::CloseDB(PGLOBAL g) +{ + //if (To_Kindex) { + // To_Kindex->Close(); + // To_Kindex = NULL; + // } // endif + + if (Jcp) + Jcp->Close(); + + if (trace) + htrc("JDBC CloseDB: closing %s\n", Name); + + if (!Werr && + (Mode == MODE_INSERT || Mode == MODE_UPDATE || Mode == MODE_DELETE)) { + sprintf(g->Message, "%s: %d affected rows", TableName, AftRows); + + if (trace) + htrc("%s\n", g->Message); + + PushWarning(g, this, 0); // 0 means a Note + } // endif Mode + + Prepared = false; +} // end of CloseDB + +/* --------------------------- JDBCCOL ------------------------------- */ + +/***********************************************************************/ +/* JDBCCOL public constructor. */ +/***********************************************************************/ +JDBCCOL::JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) + : COLBLK(cdp, tdbp, i) +{ + if (cprec) { + Next = cprec->GetNext(); + cprec->SetNext(this); + } else { + Next = tdbp->GetColumns(); + tdbp->SetColumns(this); + } // endif cprec + + // Set additional JDBC access method information for column. + Crp = NULL; + //Long = cdp->GetLong(); + Long = Precision; + //strcpy(F_Date, cdp->F_Date); + To_Val = NULL; +//Slen = 0; +//StrLen = &Slen; +//Sqlbuf = NULL; + Bufp = NULL; + Blkp = NULL; + Rank = 0; // Not known yet + + if (trace) + htrc(" making new %sCOL C%d %s at %p\n", am, Index, Name, this); + +} // end of JDBCCOL constructor + +/***********************************************************************/ +/* JDBCCOL private constructor. */ +/***********************************************************************/ +JDBCCOL::JDBCCOL(void) : COLBLK() +{ + Crp = NULL; + Buf_Type = TYPE_INT; // This is a count(*) column + // Set additional Dos access method information for column. + Long = sizeof(int); + To_Val = NULL; +//Slen = 0; +//StrLen = &Slen; +//Sqlbuf = NULL; + Bufp = NULL; + Blkp = NULL; + Rank = 1; +} // end of JDBCCOL constructor + +/***********************************************************************/ +/* JDBCCOL constructor used for copying columns. */ +/* tdbp is the pointer to the new table descriptor. */ +/***********************************************************************/ +JDBCCOL::JDBCCOL(JDBCCOL *col1, PTDB tdbp) : COLBLK(col1, tdbp) +{ + Crp = col1->Crp; + Long = col1->Long; + //strcpy(F_Date, col1->F_Date); + To_Val = col1->To_Val; +//Slen = col1->Slen; +//StrLen = col1->StrLen; +//Sqlbuf = col1->Sqlbuf; + Bufp = col1->Bufp; + Blkp = col1->Blkp; + Rank = col1->Rank; +} // end of JDBCCOL copy constructor + +/***********************************************************************/ +/* SetBuffer: prepare a column block for write operation. */ +/***********************************************************************/ +bool JDBCCOL::SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check) +{ + if (!(To_Val = value)) { + sprintf(g->Message, MSG(VALUE_ERROR), Name); + return true; + } else if (Buf_Type == value->GetType()) { + // Values are of the (good) column type + if (Buf_Type == TYPE_DATE) { + // If any of the date values is formatted + // output format must be set for the receiving table + if (GetDomain() || ((DTVAL *)value)->IsFormatted()) + goto newval; // This will make a new value; + + } else if (Buf_Type == TYPE_DOUBLE) + // Float values must be written with the correct (column) precision + // Note: maybe this should be forced by ShowValue instead of this ? + value->SetPrec(GetScale()); + + Value = value; // Directly access the external value + } else { + // Values are not of the (good) column type + if (check) { + sprintf(g->Message, MSG(TYPE_VALUE_ERR), Name, + GetTypeName(Buf_Type), GetTypeName(value->GetType())); + return true; + } // endif check + + newval: + if (InitValue(g)) // Allocate the matching value block + return true; + + } // endif's Value, Buf_Type + + // Because Colblk's have been made from a copy of the original TDB in + // case of Update, we must reset them to point to the original one. + if (To_Tdb->GetOrig()) + To_Tdb = (PTDB)To_Tdb->GetOrig(); + + // Set the Column + Status = (ok) ? BUF_EMPTY : BUF_NO; + return false; +} // end of SetBuffer + +/***********************************************************************/ +/* ReadColumn: when SQLFetch is used there is nothing to do as the */ +/* column buffer was bind to the record set. This is also the case */ +/* when calculating MaxSize (Bufp is NULL even when Rows is not). */ +/***********************************************************************/ +void JDBCCOL::ReadColumn(PGLOBAL g) +{ + PTDBJDBC tdbp = (PTDBJDBC)To_Tdb; + int i = tdbp->Fpos - 1, n = tdbp->CurNum; + + if (tdbp->Memory == 3) { + // Get the value from the stored memory + if (Crp->Nulls && Crp->Nulls[i] == '*') { + Value->Reset(); + Value->SetNull(true); + } else { + Value->SetValue_pvblk(Crp->Kdata, i); + Value->SetNull(false); + } // endif Nulls + + return; + } // endif Memory + + /*********************************************************************/ + /* Get the column value. */ + /*********************************************************************/ + tdbp->Jcp->SetColumnValue(Rank, Name, Value); + + if (tdbp->Memory != 2) + return; + + /*********************************************************************/ + /* Fill the allocated result structure. */ + /*********************************************************************/ + if (Value->IsNull()) { + if (Crp->Nulls) + Crp->Nulls[i] = '*'; // Null value + + Crp->Kdata->Reset(i); + } else + Crp->Kdata->SetValue(Value, i); + +} // end of ReadColumn + +#if 0 +/***********************************************************************/ +/* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */ +/* or Fetch. Note: we use Long+1 here because JDBC must have space */ +/* for the ending null character. */ +/***********************************************************************/ +void JDBCCOL::AllocateBuffers(PGLOBAL g, int rows) +{ + if (Buf_Type == TYPE_DATE) + Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL, + sizeof(TIMESTAMP_STRUCT)); + + if (!rows) + return; + + if (Buf_Type == TYPE_DATE) + Bufp = PlugSubAlloc(g, NULL, rows * sizeof(TIMESTAMP_STRUCT)); + else { + Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(), + GetScale(), true, false, false); + Bufp = Blkp->GetValPointer(); + } // endelse + + if (rows > 1) + StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN)); + +} // end of AllocateBuffers + +/***********************************************************************/ +/* Returns the buffer to use for Fetch or Extended Fetch. */ +/***********************************************************************/ +void *JDBCCOL::GetBuffer(DWORD rows) +{ + if (rows && To_Tdb) { + assert(rows == (DWORD)((TDBJDBC*)To_Tdb)->Rows); + return Bufp; + } else + return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val(); + +} // end of GetBuffer + +/***********************************************************************/ +/* Returns the buffer length to use for Fetch or Extended Fetch. */ +/***********************************************************************/ +SWORD JDBCCOL::GetBuflen(void) +{ + SWORD flen; + + switch (Buf_Type) { + case TYPE_DATE: + flen = (SWORD)sizeof(TIMESTAMP_STRUCT); + break; + case TYPE_STRING: + case TYPE_DECIM: + flen = (SWORD)Value->GetClen() + 1; + break; + default: + flen = (SWORD)Value->GetClen(); + } // endswitch Buf_Type + + return flen; +} // end of GetBuflen +#endif // 0 + +/***********************************************************************/ +/* WriteColumn: make sure the bind buffer is updated. */ +/***********************************************************************/ +void JDBCCOL::WriteColumn(PGLOBAL g) +{ + /*********************************************************************/ + /* Do convert the column value if necessary. */ + /*********************************************************************/ + if (Value != To_Val) + Value->SetValue_pval(To_Val, FALSE); // Convert the inserted value + +#if 0 + if (Buf_Type == TYPE_DATE) { + struct tm tm, *dbtime = ((DTVAL*)Value)->GetGmTime(&tm); + + Sqlbuf->second = dbtime->tm_sec; + Sqlbuf->minute = dbtime->tm_min; + Sqlbuf->hour = dbtime->tm_hour; + Sqlbuf->day = dbtime->tm_mday; + Sqlbuf->month = dbtime->tm_mon + 1; + Sqlbuf->year = dbtime->tm_year + 1900; + Sqlbuf->fraction = 0; + } else if (Buf_Type == TYPE_DECIM) { + // Some data sources require local decimal separator + char *p, sep = ((PTDBJDBC)To_Tdb)->Sep; + + if (sep && (p = strchr(Value->GetCharValue(), '.'))) + *p = sep; + + } // endif Buf_Type + + if (Nullable) + *StrLen = (Value->IsNull()) ? SQL_NULL_DATA : + (IsTypeChar(Buf_Type)) ? SQL_NTS : 0; +#endif // 0 +} // end of WriteColumn + +/* -------------------------- Class TDBXJDC -------------------------- */ + +/***********************************************************************/ +/* Implementation of the TDBXJDC class. */ +/***********************************************************************/ +TDBXJDC::TDBXJDC(PJDBCDEF tdp) : TDBJDBC(tdp) +{ + Cmdlist = NULL; + Cmdcol = NULL; + Mxr = tdp->Maxerr; + Nerr = 0; +} // end of TDBXJDC constructor + +/***********************************************************************/ +/* Allocate XSRC column description block. */ +/***********************************************************************/ +PCOL TDBXJDC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n) +{ + PJSRCCOL colp = new(g)JSRCCOL(cdp, this, cprec, n); + + if (!colp->Flag) + Cmdcol = colp->GetName(); + + return colp; +} // end of MakeCol + +/***********************************************************************/ +/* MakeCMD: make the SQL statement to send to JDBC connection. */ +/***********************************************************************/ +PCMD TDBXJDC::MakeCMD(PGLOBAL g) +{ + PCMD xcmd = NULL; + + if (To_CondFil) { + if (Cmdcol) { + if (!stricmp(Cmdcol, To_CondFil->Body) && + (To_CondFil->Op == OP_EQ || To_CondFil->Op == OP_IN)) { + xcmd = To_CondFil->Cmds; + } else + strcpy(g->Message, "Invalid command specification filter"); + + } else + strcpy(g->Message, "No command column in select list"); + + } else if (!Srcdef) + strcpy(g->Message, "No Srcdef default command"); + else + xcmd = new(g) CMD(g, Srcdef); + + return xcmd; +} // end of MakeCMD + +#if 0 +/***********************************************************************/ +/* JDBC Bind Parameter function. */ +/***********************************************************************/ +bool TDBXJDC::BindParameters(PGLOBAL g) +{ + PJDBCCOL colp; + + for (colp = (PJDBCCOL)Columns; colp; colp = (PJDBCCOL)colp->Next) { + colp->AllocateBuffers(g, 0); + + if (Jcp->BindParam(colp)) + return true; + + } // endfor colp + + return false; +} // end of BindParameters +#endif // 0 + +/***********************************************************************/ +/* XDBC GetMaxSize: returns table size (not always one row). */ +/***********************************************************************/ +int TDBXJDC::GetMaxSize(PGLOBAL g) +{ + if (MaxSize < 0) + MaxSize = 2; // Just a guess + + return MaxSize; +} // end of GetMaxSize + +/***********************************************************************/ +/* JDBC Access Method opening routine. */ +/* New method now that this routine is called recursively (last table */ +/* first in reverse order): index blocks are immediately linked to */ +/* join block of next table if it exists or else are discarted. */ +/***********************************************************************/ +bool TDBXJDC::OpenDB(PGLOBAL g) +{ + bool rc = false; + + if (trace) + htrc("JDBC OpenDB: tdbp=%p tdb=R%d use=%d mode=%d\n", + this, Tdb_No, Use, Mode); + + if (Use == USE_OPEN) { + strcpy(g->Message, "Multiple execution is not allowed"); + return true; + } // endif use + + /*********************************************************************/ + /* Open an JDBC connection for this table. */ + /* Note: this may not be the proper way to do. Perhaps it is better */ + /* to test whether a connection is already open for this datasource */ + /* and if so to allocate just a new result set. But this only for */ + /* drivers allowing concurency in getting results ??? */ + /*********************************************************************/ + if (!Jcp) { + Jcp = new(g) JDBConn(g, this); + } else if (Jcp->IsOpen()) + Jcp->Close(); + + if (Jcp->Open(&Ops) == RC_FX) + return true; + + Use = USE_OPEN; // Do it now in case we are recursively called + + if (Mode != MODE_READ && Mode != MODE_READX) { + strcpy(g->Message, "No INSERT/DELETE/UPDATE of XJDBC tables"); + return true; + } // endif Mode + + /*********************************************************************/ + /* Get the command to execute. */ + /*********************************************************************/ + if (!(Cmdlist = MakeCMD(g))) { + Jcp->Close(); + return true; + } // endif Query + + Rows = 1; + return false; +} // end of OpenDB + +/***********************************************************************/ +/* ReadDB: Data Base read routine for xdbc access method. */ +/***********************************************************************/ +int TDBXJDC::ReadDB(PGLOBAL g) +{ + if (Cmdlist) { + int rc; + + if (!Query) + Query = new(g) STRING(g, 0, Cmdlist->Cmd); + else + Query->Set(Cmdlist->Cmd); + + if ((rc = Jcp->ExecSQLcommand(Query->GetStr())) == RC_FX) + Nerr++; + + if (rc == RC_NF) + AftRows = Jcp->m_Aff; + else if (rc == RC_OK) + AftRows = Jcp->m_Ncol; + + Fpos++; // Used for progress info + Cmdlist = (Nerr > Mxr) ? NULL : Cmdlist->Next; + return RC_OK; + } else + return RC_EF; + +} // end of ReadDB + +/***********************************************************************/ +/* Data Base write line routine for JDBC access method. */ +/***********************************************************************/ +int TDBXJDC::WriteDB(PGLOBAL g) +{ + strcpy(g->Message, "Execsrc tables are read only"); + return RC_FX; +} // end of DeleteDB + +/***********************************************************************/ +/* Data Base delete line routine for JDBC access method. */ +/***********************************************************************/ +int TDBXJDC::DeleteDB(PGLOBAL g, int irc) +{ + strcpy(g->Message, "NO_XJDBC_DELETE"); + return RC_FX; +} // end of DeleteDB + +/* --------------------------- JSRCCOL ------------------------------- */ + +/***********************************************************************/ +/* JSRCCOL public constructor. */ +/***********************************************************************/ +JSRCCOL::JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am) + : JDBCCOL(cdp, tdbp, cprec, i, am) +{ + // Set additional JDBC access method information for column. + Flag = cdp->GetOffset(); +} // end of JSRCCOL constructor + +/***********************************************************************/ +/* ReadColumn: set column value according to Flag. */ +/***********************************************************************/ +void JSRCCOL::ReadColumn(PGLOBAL g) +{ + PTDBXJDC tdbp = (PTDBXJDC)To_Tdb; + + switch (Flag) { + case 0: Value->SetValue_psz(tdbp->Query->GetStr()); break; + case 1: Value->SetValue(tdbp->AftRows); break; + case 2: Value->SetValue_psz(g->Message); break; + default: Value->SetValue_psz("Invalid Flag"); break; + } // endswitch Flag + +} // end of ReadColumn + +/***********************************************************************/ +/* WriteColumn: Should never be called. */ +/***********************************************************************/ +void JSRCCOL::WriteColumn(PGLOBAL g) +{ + // Should never be called +} // end of WriteColumn + +/* ---------------------------TDBJDRV class -------------------------- */ + +/***********************************************************************/ +/* GetResult: Get the list of JDBC drivers. */ +/***********************************************************************/ +PQRYRES TDBJDRV::GetResult(PGLOBAL g) +{ + return JDBCDrivers(g, Maxres, false); +} // end of GetResult + +/* ---------------------------TDBJTB class --------------------------- */ + +/***********************************************************************/ +/* TDBJTB class constructor. */ +/***********************************************************************/ +TDBJTB::TDBJTB(PJDBCDEF tdp) : TDBJDRV(tdp) +{ + Schema = tdp->Tabschema; + Tab = tdp->Tabname; + Tabtype = tdp->Tabtype; + Ops.Driver = tdp->Driver; + Ops.Url = tdp->Url; + Ops.User = tdp->Username; + Ops.Pwd = tdp->Password; + Ops.Fsize = 0; + Ops.Scrollable = false; +} // end of TDBJTB constructor + +/***********************************************************************/ +/* GetResult: Get the list of JDBC tables. */ +/***********************************************************************/ +PQRYRES TDBJTB::GetResult(PGLOBAL g) +{ + return JDBCTables(g, Schema, Tab, Tabtype, Maxres, false, &Ops); +} // end of GetResult + +/* --------------------------TDBJDBCL class -------------------------- */ + +/***********************************************************************/ +/* GetResult: Get the list of JDBC table columns. */ +/***********************************************************************/ +PQRYRES TDBJDBCL::GetResult(PGLOBAL g) +{ + return JDBCColumns(g, Schema, Tab, NULL, Maxres, false, &Ops); +} // end of GetResult + +#if 0 +/* ---------------------------TDBJSRC class -------------------------- */ + +/***********************************************************************/ +/* GetResult: Get the list of JDBC data sources. */ +/***********************************************************************/ +PQRYRES TDBJSRC::GetResult(PGLOBAL g) +{ + return JDBCDataSources(g, Maxres, false); +} // end of GetResult + +/* ------------------------ End of TabJDBC --------------------------- */ +#endif // 0 diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h new file mode 100644 index 0000000000000..1624b9036104e --- /dev/null +++ b/storage/connect/tabjdbc.h @@ -0,0 +1,343 @@ +/*************** Tabjdbc H Declares Source Code File (.H) **************/ +/* Name: TABJDBC.H Version 1.0 */ +/* */ +/* (C) Copyright to the author Olivier BERTRAND 2016 */ +/* */ +/* This file contains the TDBJDBC classes declares. */ +/***********************************************************************/ +#include "colblk.h" +#include "resource.h" + +typedef class JDBCDEF *PJDBCDEF; +typedef class TDBJDBC *PTDBJDBC; +typedef class JDBCCOL *PJDBCCOL; +typedef class TDBXJDC *PTDBXJDC; +typedef class JSRCCOL *PJSRCCOL; +//typedef class TDBOIF *PTDBOIF; +//typedef class OIFCOL *POIFCOL; +//typedef class TDBJSRC *PTDBJSRC; + +/***********************************************************************/ +/* JDBC table. */ +/***********************************************************************/ +class DllExport JDBCDEF : public TABDEF { /* Logical table description */ + friend class TDBJDBC; + friend class TDBXJDC; + friend class TDBJDRV; + friend class TDBJTB; +public: + // Constructor + JDBCDEF(void); + + // Implementation + virtual const char *GetType(void) { return "JDBC"; } + PSZ GetTabname(void) { return Tabname; } + PSZ GetTabschema(void) { return Tabschema; } + PSZ GetTabcat(void) { return Tabcat; } + PSZ GetSrcdef(void) { return Srcdef; } + char GetSep(void) { return (Sep) ? *Sep : 0; } + int GetQuoted(void) { return Quoted; } +//int GetCatver(void) { return Catver; } + int GetOptions(void) { return Options; } + + // Methods + virtual int Indexable(void) { return 2; } + virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); + virtual PTDB GetTable(PGLOBAL g, MODE m); + +protected: + // Members + PSZ Driver; /* JDBC driver */ + PSZ Url; /* JDBC driver URL */ + PSZ Tabname; /* External table name */ + PSZ Tabschema; /* External table schema */ + PSZ Username; /* User connect name */ + PSZ Password; /* Password connect info */ + PSZ Tabcat; /* External table catalog */ + PSZ Tabtype; /* External table type */ + PSZ Srcdef; /* The source table SQL definition */ + PSZ Qchar; /* Identifier quoting character */ + PSZ Qrystr; /* The original query */ + PSZ Sep; /* Decimal separator */ + int Options; /* Open connection options */ +//int Cto; /* Open connection timeout */ +//int Qto; /* Query (command) timeout */ + int Quoted; /* Identifier quoting level */ + int Maxerr; /* Maxerr for an Exec table */ + int Maxres; /* Maxres for a catalog table */ + int Memory; /* Put result set in memory */ + bool Scrollable; /* Use scrollable cursor */ + bool Xsrc; /* Execution type */ +}; // end of JDBCDEF + +#if !defined(NJDBC) +#include "jdbconn.h" + +/***********************************************************************/ +/* This is the JDBC Access Method class declaration for files from */ +/* other DB drivers to be accessed via JDBC. */ +/***********************************************************************/ +class TDBJDBC : public TDBASE { + friend class JDBCCOL; + friend class JDBConn; +public: + // Constructor + TDBJDBC(PJDBCDEF tdp = NULL); + TDBJDBC(PTDBJDBC tdbp); + + // Implementation + virtual AMT GetAmType(void) { return TYPE_AM_JDBC; } + virtual PTDB Duplicate(PGLOBAL g) { return (PTDB)new(g)TDBJDBC(this); } + + // Methods + virtual PTDB CopyOne(PTABS t); + virtual int GetRecpos(void); + virtual bool SetRecpos(PGLOBAL g, int recpos); +//virtual PSZ GetFile(PGLOBAL g); +//virtual void SetFile(PGLOBAL g, PSZ fn); + virtual void ResetSize(void); + //virtual int GetAffectedRows(void) {return AftRows;} + virtual PSZ GetServer(void) { return "JDBC"; } + virtual int Indexable(void) { return 2; } + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); + virtual int Cardinality(PGLOBAL g); + virtual int GetMaxSize(PGLOBAL g); + virtual int GetProgMax(PGLOBAL g); + virtual bool OpenDB(PGLOBAL g); + virtual int ReadDB(PGLOBAL g); + virtual int WriteDB(PGLOBAL g); + virtual int DeleteDB(PGLOBAL g, int irc); + virtual void CloseDB(PGLOBAL g); + virtual bool ReadKey(PGLOBAL g, OPVAL op, const key_range *kr); + +protected: + // Internal functions + int Decode(char *utf, char *buf, size_t n); + bool MakeSQL(PGLOBAL g, bool cnt); + bool MakeInsert(PGLOBAL g); + bool MakeCommand(PGLOBAL g); + //bool MakeFilter(PGLOBAL g, bool c); + bool SetParameters(PGLOBAL g); + //char *MakeUpdate(PGLOBAL g); + //char *MakeDelete(PGLOBAL g); + + // Members + JDBConn *Jcp; // Points to a JDBC connection class + JDBCCOL *Cnp; // Points to count(*) column + JDBCPARM Ops; // Additional parameters + PSTRG Query; // Constructed SQL query + char *TableName; // Points to JDBC table name + char *Schema; // Points to JDBC table Schema + char *User; // User connect info + char *Pwd; // Password connect info + char *Catalog; // Points to JDBC table Catalog + char *Srcdef; // The source table SQL definition + char *Count; // Points to count(*) SQL statement +//char *Where; // Points to local where clause + char *Quote; // The identifier quoting character + char *MulConn; // Used for multiple JDBC tables + char *DBQ; // The address part of Connect string + char *Qrystr; // The original query + char Sep; // The decimal separator + int Options; // Connect options +//int Cto; // Connect timeout +//int Qto; // Query timeout + int Quoted; // The identifier quoting level + int Fpos; // Position of last read record + int Curpos; // Cursor position of last fetch + int AftRows; // The number of affected rows + int Rows; // Rowset size + int CurNum; // Current buffer line number + int Rbuf; // Number of lines read in buffer + int BufSize; // Size of connect string buffer + int Ncol; // The column number + int Nparm; // The number of statement parameters + int Memory; // 0: No 1: Alloc 2: Put 3: Get +//bool Scrollable; // Use scrollable cursor --> in Ops + bool Placed; // True for position reading + bool Prepared; // True when using prepared statement + bool Werr; // Write error + bool Rerr; // Rewind error + PQRYRES Qrp; // Points to storage result +}; // end of class TDBJDBC + +/***********************************************************************/ +/* Class JDBCCOL: JDBC access method column descriptor. */ +/* This A.M. is used for JDBC tables. */ +/***********************************************************************/ +class JDBCCOL : public COLBLK { + friend class TDBJDBC; +public: + // Constructors + JDBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC"); + JDBCCOL(JDBCCOL *colp, PTDB tdbp); // Constructor used in copy process + + // Implementation + virtual int GetAmType(void) { return TYPE_AM_JDBC; } +//SQLLEN *GetStrLen(void) { return StrLen; } + int GetRank(void) { return Rank; } +//PVBLK GetBlkp(void) {return Blkp;} + void SetCrp(PCOLRES crp) { Crp = crp; } + + // Methods + virtual bool SetBuffer(PGLOBAL g, PVAL value, bool ok, bool check); + virtual void ReadColumn(PGLOBAL g); + virtual void WriteColumn(PGLOBAL g); +//void AllocateBuffers(PGLOBAL g, int rows); +//void *GetBuffer(DWORD rows); +//SWORD GetBuflen(void); + // void Print(PGLOBAL g, FILE *, uint); + +protected: + // Constructor used by GetMaxSize + JDBCCOL(void); + + // Members + //TIMESTAMP_STRUCT *Sqlbuf; // To get SQL_TIMESTAMP's + PCOLRES Crp; // To storage result + void *Bufp; // To extended buffer + PVBLK Blkp; // To Value Block + //char F_Date[12]; // Internal Date format + PVAL To_Val; // To value used for Insert +//SQLLEN *StrLen; // As returned by JDBC +//SQLLEN Slen; // Used with Fetch + int Rank; // Rank (position) number in the query +}; // end of class JDBCCOL + +/***********************************************************************/ +/* This is the JDBC Access Method class declaration that send */ +/* commands to be executed by other DB JDBC drivers. */ +/***********************************************************************/ +class TDBXJDC : public TDBJDBC { + friend class JSRCCOL; + friend class JDBConn; +public: + // Constructors + TDBXJDC(PJDBCDEF tdp = NULL); + + // Implementation + virtual AMT GetAmType(void) {return TYPE_AM_XDBC;} + + // Methods + //virtual int GetRecpos(void); + //virtual PSZ GetFile(PGLOBAL g); + //virtual void SetFile(PGLOBAL g, PSZ fn); + //virtual void ResetSize(void); + //virtual int GetAffectedRows(void) {return AftRows;} + //virtual PSZ GetServer(void) {return "JDBC";} + + // Database routines + virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n); + //virtual int GetProgMax(PGLOBAL g); + virtual int GetMaxSize(PGLOBAL g); + virtual bool OpenDB(PGLOBAL g); + virtual int ReadDB(PGLOBAL g); + virtual int WriteDB(PGLOBAL g); + virtual int DeleteDB(PGLOBAL g, int irc); + //virtual void CloseDB(PGLOBAL g); + +protected: + // Internal functions + PCMD MakeCMD(PGLOBAL g); + //bool BindParameters(PGLOBAL g); + + // Members + PCMD Cmdlist; // The commands to execute + char *Cmdcol; // The name of the Xsrc command column + int Mxr; // Maximum errors before closing + int Nerr; // Number of errors so far +}; // end of class TDBXJDC + +/***********************************************************************/ +/* Used by table in source execute mode. */ +/***********************************************************************/ +class JSRCCOL : public JDBCCOL { + friend class TDBXJDC; +public: + // Constructors + JSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PSZ am = "JDBC"); + + // Implementation + //virtual int GetAmType(void) {return TYPE_AM_JDBC;} + + // Methods + virtual void ReadColumn(PGLOBAL g); + virtual void WriteColumn(PGLOBAL g); + // void Print(PGLOBAL g, FILE *, uint); + +protected: + // Members + char *Buffer; // To get returned message + int Flag; // Column content desc +}; // end of class JSRCCOL + +/***********************************************************************/ +/* This is the class declaration for the Drivers catalog table. */ +/***********************************************************************/ +class TDBJDRV : public TDBCAT { +public: + // Constructor + TDBJDRV(PJDBCDEF tdp) : TDBCAT(tdp) {Maxres = tdp->Maxres;} + +protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // Members + int Maxres; // Returned lines limit +}; // end of class TDBJDRV + +/***********************************************************************/ +/* This is the class declaration for the tables catalog table. */ +/***********************************************************************/ +class TDBJTB : public TDBJDRV { +public: + // Constructor + TDBJTB(PJDBCDEF tdp); + +protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // Members + char *Schema; // Points to schema name or NULL + char *Tab; // Points to JDBC table name or pattern + char *Tabtype; // Points to JDBC table type + JDBCPARM Ops; // Additional parameters +}; // end of class TDBJTB + +/***********************************************************************/ +/* This is the class declaration for the columns catalog table. */ +/***********************************************************************/ +class TDBJDBCL : public TDBJTB { +public: + // Constructor + TDBJDBCL(PJDBCDEF tdp) : TDBJTB(tdp) {} + +protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // No additional Members +}; // end of class TDBJCL + +#if 0 +/***********************************************************************/ +/* This is the class declaration for the Data Sources catalog table. */ +/***********************************************************************/ +class TDBJSRC : public TDBJDRV { +public: + // Constructor + TDBJSRC(PJDBCDEF tdp) : TDBJDRV(tdp) {} + +protected: + // Specific routines + virtual PQRYRES GetResult(PGLOBAL g); + + // No additional Members +}; // end of class TDBJSRC +#endif // 0 + +#endif // !NJDBC From 4a1ffc3853dcbb279dfe3dce313d21b9ea1eb2f5 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 12 May 2016 23:26:40 +0200 Subject: [PATCH 024/112] Add forgotten changes made on 10.1 --- storage/connect/mycat.cc | 16 +++++++++++++--- storage/connect/odbconn.cpp | 2 +- storage/connect/plgdbsem.h | 12 ++++++++---- storage/connect/tabodbc.cpp | 8 ++++---- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index 97ad980dd6a7a..da8be20723796 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -80,6 +80,10 @@ #define NODBC #include "tabodbc.h" #endif // ODBC_SUPPORT +#if defined(JDBC_SUPPORT) +#define NJDBC +#include "tabjdbc.h" +#endif // ODBC_SUPPORT #if defined(PIVOT_SUPPORT) #include "tabpivot.h" #endif // PIVOT_SUPPORT @@ -140,7 +144,10 @@ TABTYPE GetTypeID(const char *type) #ifdef ODBC_SUPPORT : (!stricmp(type, "ODBC")) ? TAB_ODBC #endif - : (!stricmp(type, "MYSQL")) ? TAB_MYSQL +#ifdef JDBC_SUPPORT + : (!stricmp(type, "JDBC")) ? TAB_JDBC +#endif + : (!stricmp(type, "MYSQL")) ? TAB_MYSQL : (!stricmp(type, "MYPRX")) ? TAB_MYSQL : (!stricmp(type, "DIR")) ? TAB_DIR #ifdef __WIN__ @@ -301,12 +308,12 @@ int GetIndexType(TABTYPE type) break; case TAB_MYSQL: case TAB_ODBC: - xtyp= 2; + case TAB_JDBC: + xtyp= 2; break; case TAB_VIR: xtyp= 3; break; -// case TAB_ODBC: default: xtyp= 0; break; @@ -558,6 +565,9 @@ PRELDEF MYCAT::MakeTableDesc(PGLOBAL g, PTABLE tablep, LPCSTR am) #if defined(ODBC_SUPPORT) case TAB_ODBC: tdp= new(g) ODBCDEF; break; #endif // ODBC_SUPPORT +#if defined(JDBC_SUPPORT) + case TAB_JDBC: tdp= new(g)JDBCDEF; break; +#endif // JDBC_SUPPORT #if defined(__WIN__) case TAB_MAC: tdp= new(g) MACDEF; break; case TAB_WMI: tdp= new(g) WMIDEF; break; diff --git a/storage/connect/odbconn.cpp b/storage/connect/odbconn.cpp index 55ccbdbada1d9..8b2626fe96249 100644 --- a/storage/connect/odbconn.cpp +++ b/storage/connect/odbconn.cpp @@ -1458,7 +1458,7 @@ int ODBConn::ExecDirectSQL(char *sql, ODBCCOL *tocols) n++; // n can be 0 for query such as Select count(*) from table - if (n && n != (UWORD)ncol) + if (n && n > (UWORD)ncol) ThrowDBX(MSG(COL_NUM_MISM)); // Now bind the column buffers diff --git a/storage/connect/plgdbsem.h b/storage/connect/plgdbsem.h index b57d9e20ceb9c..910ce97f48ae2 100644 --- a/storage/connect/plgdbsem.h +++ b/storage/connect/plgdbsem.h @@ -77,7 +77,8 @@ enum TABTYPE {TAB_UNDEF = 0, /* Table of undefined type */ TAB_JSON = 23, /* JSON tables */ TAB_JCT = 24, /* Junction tables NIY */ TAB_DMY = 25, /* DMY Dummy tables NIY */ - TAB_NIY = 26}; /* Table not implemented yet */ + TAB_JDBC = 26, /* Table accessed via JDBC */ + TAB_NIY = 27}; /* Table not implemented yet */ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ TYPE_AM_ROWID = 1, /* ROWID type (special column) */ @@ -109,7 +110,9 @@ enum AMT {TYPE_AM_ERROR = 0, /* Type not defined */ TYPE_AM_DIR = 90, /* DIR access method type no */ TYPE_AM_ODBC = 100, /* ODBC access method type no */ TYPE_AM_XDBC = 101, /* XDBC access method type no */ - TYPE_AM_OEM = 110, /* OEM access method type no */ + TYPE_AM_JDBC = 102, /* JDBC access method type no */ + TYPE_AM_XJDC = 103, /* XJDC access method type no */ + TYPE_AM_OEM = 110, /* OEM access method type no */ TYPE_AM_TBL = 115, /* TBL access method type no */ TYPE_AM_PIVOT = 120, /* PIVOT access method type no */ TYPE_AM_SRC = 121, /* PIVOT multiple column type no */ @@ -146,8 +149,9 @@ enum RECFM {RECFM_NAF = -2, /* Not a file */ RECFM_BIN = 2, /* Binary DOS files (also fixed) */ RECFM_VCT = 3, /* VCT formatted files */ RECFM_ODBC = 4, /* Table accessed via ODBC */ - RECFM_PLG = 5, /* Table accessed via PLGconn */ - RECFM_DBF = 6}; /* DBase formatted file */ + RECFM_JDBC = 5, /* Table accessed via JDBC */ + RECFM_PLG = 6, /* Table accessed via PLGconn */ + RECFM_DBF = 7}; /* DBase formatted file */ enum MISC {DB_TABNO = 1, /* DB routines in Utility Table */ MAX_MULT_KEY = 10, /* Max multiple key number */ diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp index b8961789ccd31..b3b6c2919c0a3 100644 --- a/storage/connect/tabodbc.cpp +++ b/storage/connect/tabodbc.cpp @@ -97,8 +97,8 @@ ODBCDEF::ODBCDEF(void) { Connect = Tabname = Tabschema = Username = Password = NULL; Tabcat = Srcdef = Qchar = Qrystr = Sep = NULL; - Catver = Options = Cto = Qto = Quoted = Maxerr = Maxres = 0; - Scrollable = Memory = Xsrc = UseCnc = false; + Catver = Options = Cto = Qto = Quoted = Maxerr = Maxres = Memory = 0; + Scrollable = Xsrc = UseCnc = false; } // end of ODBCDEF constructor /***********************************************************************/ @@ -1009,7 +1009,7 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos) } // end of SetRecpos /***********************************************************************/ -/* Data Base indexed read routine for MYSQL access method. */ +/* Data Base indexed read routine for ODBC access method. */ /***********************************************************************/ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) { @@ -1028,7 +1028,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr) return false; } else { - if (To_Def->GetHandler()->MakeKeyWhere(g, Query, op, c, kr)) + if (hc->MakeKeyWhere(g, Query, op, c, kr)) return true; if (To_CondFil) { From 9d72fb4af0d87f6a69a3ccb9202b4029acf2bd56 Mon Sep 17 00:00:00 2001 From: Shishir Jaiswal Date: Mon, 16 May 2016 13:46:49 +0530 Subject: [PATCH 025/112] Bug#21977380 - POSSIBLE BUFFER OVERFLOW ISSUES DESCRIPTION =========== Buffer overflow is reported in a lot of code sections spanning across server, client programs, Regex libraries etc. If not handled appropriately, they can cause abnormal behaviour. ANALYSIS ======== The reported casea are the ones which are likely to result in SEGFAULT, MEMORY LEAK etc. FIX === - sprintf() has been replaced by my_snprintf() to avoid buffer overflow. - my_free() is done after checking if the pointer isn't NULL already and setting it to NULL thereafter at few places. - Buffer is ensured to be large enough to hold the data. - 'unsigned int' (aka 'uint') is replaced with 'size_t' to avoid wraparound. - Memory is freed (if not done so) after its alloced and used. - Inserted assert() for size check in InnoDb memcached code (from 5.6 onwards) - Other minor changes (cherry picked from commit 3487e20959c940cbd24429afa795ebfc8a01e94f) --- client/mysqlcheck.c | 42 +++++++++++++++++++++-------------- client/mysqldump.c | 49 +++++++++++++++++++++++------------------ client/mysqlshow.c | 36 ++++++++++++++++-------------- extra/yassl/src/log.cpp | 4 ++-- regex/split.c | 4 ++++ 5 files changed, 78 insertions(+), 57 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index a564e871281c2..55b941e7f1a76 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -213,13 +213,13 @@ static int process_selected_tables(char *db, char **table_names, int tables); static int process_all_tables_in_db(char *database); static int process_one_db(char *database); static int use_db(char *database); -static int handle_request_for_tables(char *tables, uint length); +static int handle_request_for_tables(char *tables, size_t length); static int dbConnect(char *host, char *user,char *passwd); static void dbDisconnect(char *host); static void DBerror(MYSQL *mysql, const char *when); static void safe_exit(int error); static void print_result(); -static uint fixed_name_length(const char *name); +static size_t fixed_name_length(const char *name); static char *fix_table_name(char *dest, char *src); int what_to_do = 0; @@ -486,7 +486,7 @@ static int process_selected_tables(char *db, char **table_names, int tables) *end++= ','; } *--end = 0; - handle_request_for_tables(table_names_comma_sep + 1, (uint) (tot_length - 1)); + handle_request_for_tables(table_names_comma_sep + 1, tot_length - 1); my_free(table_names_comma_sep); } else @@ -496,10 +496,10 @@ static int process_selected_tables(char *db, char **table_names, int tables) } /* process_selected_tables */ -static uint fixed_name_length(const char *name) +static size_t fixed_name_length(const char *name) { const char *p; - uint extra_length= 2; /* count the first/last backticks */ + size_t extra_length= 2; /* count the first/last backticks */ for (p= name; *p; p++) { @@ -508,7 +508,7 @@ static uint fixed_name_length(const char *name) else if (*p == '.') extra_length+= 2; } - return (uint) ((p - name) + extra_length); + return (size_t) ((p - name) + extra_length); } @@ -564,7 +564,7 @@ static int process_all_tables_in_db(char *database) */ char *tables, *end; - uint tot_length = 0; + size_t tot_length = 0; while ((row = mysql_fetch_row(res))) tot_length+= fixed_name_length(row[0]) + 2; @@ -622,7 +622,9 @@ static int fix_table_storage_name(const char *name) int rc= 0; if (strncmp(name, "#mysql50#", 9)) return 1; - sprintf(qbuf, "RENAME TABLE `%s` TO `%s`", name, name + 9); + my_snprintf(qbuf, sizeof(qbuf), "RENAME TABLE `%s` TO `%s`", + name, name + 9); + rc= run_query(qbuf); if (verbose) printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); @@ -635,7 +637,8 @@ static int fix_database_storage_name(const char *name) int rc= 0; if (strncmp(name, "#mysql50#", 9)) return 1; - sprintf(qbuf, "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY NAME", name); + my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY " + "NAME", name); rc= run_query(qbuf); if (verbose) printf("%-50s %s\n", name, rc ? "FAILED" : "OK"); @@ -653,7 +656,7 @@ static int rebuild_table(char *name) ptr= strmov(query, "ALTER TABLE "); ptr= fix_table_name(ptr, name); ptr= strxmov(ptr, " FORCE", NullS); - if (mysql_real_query(sock, query, (uint)(ptr - query))) + if (mysql_real_query(sock, query, (ulong)(ptr - query))) { fprintf(stderr, "Failed to %s\n", query); fprintf(stderr, "Error: %s\n", mysql_error(sock)); @@ -702,10 +705,10 @@ static int disable_binlog() return run_query(stmt); } -static int handle_request_for_tables(char *tables, uint length) +static int handle_request_for_tables(char *tables, size_t length) { char *query, *end, options[100], message[100]; - uint query_length= 0; + size_t query_length= 0, query_size= sizeof(char)*(length+110); const char *op = 0; options[0] = 0; @@ -736,10 +739,14 @@ static int handle_request_for_tables(char *tables, uint length) return fix_table_storage_name(tables); } - if (!(query =(char *) my_malloc((sizeof(char)*(length+110)), MYF(MY_WME)))) + if (!(query =(char *) my_malloc(query_size, MYF(MY_WME)))) + { return 1; + } if (opt_all_in_1) { + DBUG_ASSERT(strlen(op)+strlen(tables)+strlen(options)+8+1 <= query_size); + /* No backticks here as we added them before */ query_length= sprintf(query, "%s TABLE %s %s", op, tables, options); } @@ -750,7 +757,7 @@ static int handle_request_for_tables(char *tables, uint length) ptr= strmov(strmov(query, op), " TABLE "); ptr= fix_table_name(ptr, tables); ptr= strxmov(ptr, " ", options, NullS); - query_length= (uint) (ptr - query); + query_length= (size_t) (ptr - query); } if (mysql_real_query(sock, query, query_length)) { @@ -834,7 +841,10 @@ static void print_result() prev_alter[0]= 0; } else - strcpy(prev_alter, alter_txt); + { + strncpy(prev_alter, alter_txt, MAX_ALTER_STR_SIZE-1); + prev_alter[MAX_ALTER_STR_SIZE-1]= 0; + } } } } @@ -978,7 +988,7 @@ int main(int argc, char **argv) process_databases(argv); if (opt_auto_repair) { - uint i; + size_t i; if (!opt_silent && (tables4repair.elements || tables4rebuild.elements)) puts("\nRepairing tables"); diff --git a/client/mysqldump.c b/client/mysqldump.c index 6c4fec313c56a..00265def4899c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -86,7 +86,7 @@ static void add_load_option(DYNAMIC_STRING *str, const char *option, const char *option_value); -static ulong find_set(TYPELIB *lib, const char *x, uint length, +static ulong find_set(TYPELIB *lib, const char *x, size_t length, char **err_pos, uint *err_len); static char *alloc_query_str(ulong size); @@ -852,7 +852,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt_set_charset= 0; opt_compatible_mode_str= argument; opt_compatible_mode= find_set(&compatible_mode_typelib, - argument, (uint) strlen(argument), + argument, strlen(argument), &err_ptr, &err_len); if (err_len) { @@ -862,7 +862,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } #if !defined(DBUG_OFF) { - uint size_for_sql_mode= 0; + size_t size_for_sql_mode= 0; const char **ptr; for (ptr= compatible_mode_names; *ptr; ptr++) size_for_sql_mode+= strlen(*ptr); @@ -1138,8 +1138,8 @@ static int fetch_db_collation(const char *db_name, break; } - strncpy(db_cl_name, db_cl_row[0], db_cl_size); - db_cl_name[db_cl_size - 1]= 0; /* just in case. */ + strncpy(db_cl_name, db_cl_row[0], db_cl_size-1); + db_cl_name[db_cl_size - 1]= 0; } while (FALSE); @@ -1150,7 +1150,7 @@ static int fetch_db_collation(const char *db_name, static char *my_case_str(const char *str, - uint str_len, + size_t str_len, const char *token, uint token_len) { @@ -1366,7 +1366,7 @@ static int switch_character_set_results(MYSQL *mysql, const char *cs_name) */ static char *cover_definer_clause(const char *stmt_str, - uint stmt_length, + size_t stmt_length, const char *definer_version_str, uint definer_version_length, const char *stmt_version_str, @@ -1548,14 +1548,14 @@ static void dbDisconnect(char *host) } /* dbDisconnect */ -static void unescape(FILE *file,char *pos,uint length) +static void unescape(FILE *file,char *pos, size_t length) { char *tmp; DBUG_ENTER("unescape"); if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME)))) die(EX_MYSQLERR, "Couldn't allocate memory"); - mysql_real_escape_string(&mysql_connection, tmp, pos, length); + mysql_real_escape_string(&mysql_connection, tmp, pos, (ulong)length); fputc('\'', file); fputs(tmp, file); fputc('\'', file); @@ -1669,7 +1669,7 @@ static char *quote_for_like(const char *name, char *buff) Quote '<' '>' '&' '\"' chars and print a string to the xml_file. */ -static void print_quoted_xml(FILE *xml_file, const char *str, ulong len, +static void print_quoted_xml(FILE *xml_file, const char *str, size_t len, my_bool is_attribute_name) { const char *end; @@ -1928,7 +1928,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, squeezed to a single hyphen. */ -static void print_xml_comment(FILE *xml_file, ulong len, +static void print_xml_comment(FILE *xml_file, size_t len, const char *comment_string) { const char* end; @@ -2045,7 +2045,7 @@ static uint dump_events_for_db(char *db) DBUG_ENTER("dump_events_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); - mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, db_name_buff, db, (ulong)strlen(db)); /* nice comments */ print_comment(sql_file, 0, @@ -2164,6 +2164,11 @@ static uint dump_events_for_db(char *db) (const char *) (query_str != NULL ? query_str : row[3]), (const char *) delimiter); + if(query_str) + { + my_free(query_str); + query_str= NULL; + } restore_time_zone(sql_file, delimiter); restore_sql_mode(sql_file, delimiter); @@ -2257,7 +2262,7 @@ static uint dump_routines_for_db(char *db) DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); - mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, db_name_buff, db, (ulong)strlen(db)); /* nice comments */ print_comment(sql_file, 0, @@ -2311,9 +2316,9 @@ static uint dump_routines_for_db(char *db) if the user has EXECUTE privilege he see routine names, but NOT the routine body of other routines that are not the creator of! */ - DBUG_PRINT("info",("length of body for %s row[2] '%s' is %d", + DBUG_PRINT("info",("length of body for %s row[2] '%s' is %zu", routine_name, row[2] ? row[2] : "(null)", - row[2] ? (int) strlen(row[2]) : 0)); + row[2] ? strlen(row[2]) : 0)); if (row[2] == NULL) { print_comment(sql_file, 1, "\n-- insufficient privileges to %s\n", @@ -3873,7 +3878,7 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables) int i; char name_buff[NAME_LEN*2+3]; - mysql_real_escape_string(mysql, name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, name_buff, db, (ulong)strlen(db)); init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN (" "SELECT DISTINCT TABLESPACE_NAME FROM" @@ -3886,7 +3891,7 @@ static int dump_tablespaces_for_tables(char *db, char **table_names, int tables) for (i=0 ; imax_length) length=field->max_length; @@ -500,7 +501,8 @@ static int list_tables(MYSQL *mysql,const char *db,const char *table) { const char *header; - uint head_length, counter = 0; + size_t head_length; + uint counter = 0; char query[NAME_LEN + 100], rows[NAME_LEN], fields[16]; MYSQL_FIELD *field; MYSQL_RES *result; @@ -537,7 +539,7 @@ list_tables(MYSQL *mysql,const char *db,const char *table) putchar('\n'); header="Tables"; - head_length=(uint) strlen(header); + head_length= strlen(header); field=mysql_fetch_field(result); if (head_length < field->max_length) head_length=field->max_length; @@ -766,10 +768,10 @@ list_fields(MYSQL *mysql,const char *db,const char *table, *****************************************************************************/ static void -print_header(const char *header,uint head_length,...) +print_header(const char *header,size_t head_length,...) { va_list args; - uint length,i,str_length,pre_space; + size_t length,i,str_length,pre_space; const char *field; va_start(args,head_length); @@ -792,10 +794,10 @@ print_header(const char *header,uint head_length,...) putchar('|'); for (;;) { - str_length=(uint) strlen(field); + str_length= strlen(field); if (str_length > length) str_length=length+1; - pre_space=(uint) (((int) length-(int) str_length)/2)+1; + pre_space= ((length- str_length)/2)+1; for (i=0 ; i < pre_space ; i++) putchar(' '); for (i = 0 ; i < str_length ; i++) @@ -829,11 +831,11 @@ print_header(const char *header,uint head_length,...) static void -print_row(const char *header,uint head_length,...) +print_row(const char *header,size_t head_length,...) { va_list args; const char *field; - uint i,length,field_length; + size_t i,length,field_length; va_start(args,head_length); field=header; length=head_length; @@ -842,7 +844,7 @@ print_row(const char *header,uint head_length,...) putchar('|'); putchar(' '); fputs(field,stdout); - field_length=(uint) strlen(field); + field_length= strlen(field); for (i=field_length ; i <= length ; i++) putchar(' '); if (!(field=va_arg(args,char *))) @@ -856,10 +858,10 @@ print_row(const char *header,uint head_length,...) static void -print_trailer(uint head_length,...) +print_trailer(size_t head_length,...) { va_list args; - uint length,i; + size_t length,i; va_start(args,head_length); length=head_length; @@ -902,7 +904,7 @@ static void print_res_top(MYSQL_RES *result) mysql_field_seek(result,0); while((field = mysql_fetch_field(result))) { - if ((length=(uint) strlen(field->name)) > field->max_length) + if ((length= strlen(field->name)) > field->max_length) field->max_length=length; else length=field->max_length; diff --git a/extra/yassl/src/log.cpp b/extra/yassl/src/log.cpp index 13c682957473f..2f112ac35f965 100644 --- a/extra/yassl/src/log.cpp +++ b/extra/yassl/src/log.cpp @@ -1,6 +1,5 @@ /* - Copyright (C) 2000-2007 MySQL AB - Use is subject to license terms + Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -61,6 +60,7 @@ namespace yaSSL { time_t clicks = time(0); char timeStr[32]; + memset(timeStr, 0, sizeof(timeStr)); // get rid of newline strncpy(timeStr, ctime(&clicks), sizeof(timeStr)); unsigned int len = strlen(timeStr); diff --git a/regex/split.c b/regex/split.c index bd2a53c01e334..a3a11f793ed85 100644 --- a/regex/split.c +++ b/regex/split.c @@ -163,6 +163,10 @@ char *argv[]; } else if (argc > 3) for (n = atoi(argv[3]); n > 0; n--) { + if(sizeof(buf)-1 < strlen(argv[1])) + { + exit(EXIT_FAILURE); + } (void) strcpy(buf, argv[1]); (void) split(buf, fields, MNF, argv[2]); } From ef3f09f0c9e62ea1bf86b33b5d97e954b3ae34fe Mon Sep 17 00:00:00 2001 From: Sujatha Sivakumar Date: Fri, 13 May 2016 16:42:45 +0530 Subject: [PATCH 026/112] Bug#23251517: SEMISYNC REPLICATION HANGING Revert following bug fix: Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR DISK SPACE This fix results in a deadlock between slave IO thread and SQL thread. (cherry picked from commit e3fea6c6dbb36c6ab21c4ab777224560e9608b53) --- mysql-test/include/assert_grep.inc | 154 ------------------ mysql-test/include/rpl_init.inc | 31 +--- mysql-test/include/rpl_reconnect.inc | 33 +--- mysql-test/include/start_slave_sql.inc | 39 ----- .../r/rpl_io_thd_wait_for_disk_space.result | 15 -- .../rpl/t/rpl_io_thd_wait_for_disk_space.test | 71 -------- mysys/errors.c | 14 +- mysys/my_write.c | 8 +- sql/log.cc | 75 +-------- sql/log.h | 5 +- sql/slave.cc | 38 ++--- sql/slave.h | 2 +- sql/sql_reload.cc | 2 +- 13 files changed, 41 insertions(+), 446 deletions(-) delete mode 100644 mysql-test/include/assert_grep.inc delete mode 100644 mysql-test/include/start_slave_sql.inc delete mode 100644 mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result delete mode 100644 mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test diff --git a/mysql-test/include/assert_grep.inc b/mysql-test/include/assert_grep.inc deleted file mode 100644 index a980a6d73b184..0000000000000 --- a/mysql-test/include/assert_grep.inc +++ /dev/null @@ -1,154 +0,0 @@ -# ==== Purpose ==== -# -# Grep a file for a pattern, produce a single string out of the -# matching lines, and assert that the string matches a given regular -# expression. -# -# ==== Usage ==== -# -# --let $assert_text= TEXT -# --let $assert_file= FILE -# --let $assert_select= REGEX -# [--let $assert_match= REGEX | --let $assert_count= NUMBER] -# [--let $assert_only_after= REGEX] -# --source include/assert_grep.inc -# -# Parameters: -# -# $assert_text -# Text that describes what is being checked. This text is written to -# the query log so it should not contain non-deterministic elements. -# -# $assert_file -# File to search. -# -# $assert_select -# All lines matching this text will be checked. -# -# $assert_match -# The script will find all lines that match $assert_select, -# concatenate them to a long string, and assert that it matches -# $assert_match. -# -# $assert_count -# Instead of asserting that the selected lines match -# $assert_match, assert that there were exactly $assert_count -# matching lines. -# -# $assert_only_after -# Reset all the lines matched and the counter when finding this pattern. -# It is useful for searching things in the mysqld.err log file just -# after the last server restart for example (discarding the log content -# of previous server executions). - - -if (!$assert_text) -{ - --die !!!ERROR IN TEST: you must set $assert_text -} -if (!$assert_file) -{ - --die !!!ERROR IN TEST: you must set $assert_file -} -if (!$assert_select) -{ - --die !!!ERROR IN TEST: you must set $assert_select -} -if ($assert_match == '') -{ - if ($assert_count == '') - { - --die !!!ERROR IN TEST: you must set either $assert_match or $assert_count - } -} -if ($assert_match != '') -{ - if ($assert_count != '') - { - --echo assert_text='$assert_text' assert_count='$assert_count' - --die !!!ERROR IN TEST: you must set only one of $assert_match or $assert_count - } -} - - ---let $include_filename= assert_grep.inc [$assert_text] ---source include/begin_include_file.inc - - ---let _AG_ASSERT_TEXT= $assert_text ---let _AG_ASSERT_FILE= $assert_file ---let _AG_ASSERT_SELECT= $assert_select ---let _AG_ASSERT_MATCH= $assert_match ---let _AG_ASSERT_COUNT= $assert_count ---let _AG_OUT= `SELECT CONCAT('$MYSQLTEST_VARDIR/tmp/_ag_', UUID())` ---let _AG_ASSERT_ONLY_AFTER= $assert_only_after - - ---perl - use strict; - use warnings; - my $file= $ENV{'_AG_ASSERT_FILE'}; - my $assert_select= $ENV{'_AG_ASSERT_SELECT'}; - my $assert_match= $ENV{'_AG_ASSERT_MATCH'}; - my $assert_count= $ENV{'_AG_ASSERT_COUNT'}; - my $assert_only_after= $ENV{'_AG_ASSERT_ONLY_AFTER'}; - my $out= $ENV{'_AG_OUT'}; - - my $result= ''; - my $count= 0; - open(FILE, "$file") or die("Error $? opening $file: $!\n"); - while () { - my $line = $_; - if ($assert_only_after && $line =~ /$assert_only_after/) { - $result = ""; - $count = 0; - } - if ($line =~ /$assert_select/) { - if ($assert_count ne '') { - $count++; - } - else { - $result .= $line; - } - } - } - close(FILE) or die("Error $? closing $file: $!"); - open OUT, "> $out" or die("Error $? opening $out: $!"); - if ($assert_count ne '' && ($count != $assert_count)) { - print OUT ($count) or die("Error $? writing $out: $!"); - } - elsif ($assert_count eq '' && $result !~ /$assert_match/) { - print OUT ($result) or die("Error $? writing $out: $!"); - } - else { - print OUT ("assert_grep.inc ok"); - } - close OUT or die("Error $? closing $out: $!"); -EOF - - ---let $_ag_outcome= `SELECT LOAD_FILE('$_AG_OUT')` -if ($_ag_outcome != 'assert_grep.inc ok') -{ - --source include/show_rpl_debug_info.inc - --echo include/assert_grep.inc failed! - --echo assert_text: '$assert_text' - --echo assert_file: '$assert_file' - --echo assert_select: '$assert_select' - --echo assert_match: '$assert_match' - --echo assert_count: '$assert_count' - --echo assert_only_after: '$assert_only_after' - if ($assert_match != '') - { - --echo matching lines: '$_ag_outcome' - } - if ($assert_count != '') - { - --echo number of matching lines: $_ag_outcome - } - --die assert_grep.inc failed. -} - - ---let $include_filename= include/assert_grep.inc [$assert_text] ---source include/end_include_file.inc diff --git a/mysql-test/include/rpl_init.inc b/mysql-test/include/rpl_init.inc index 820bc8e90160a..2abfd901b037e 100644 --- a/mysql-test/include/rpl_init.inc +++ b/mysql-test/include/rpl_init.inc @@ -43,7 +43,6 @@ # # [--let $rpl_server_count= 7] # --let $rpl_topology= 1->2->3->1->4, 2->5, 6->7 -# [--let $rpl_extra_connections_per_server= 1] # [--let $rpl_check_server_ids= 1] # [--let $rpl_skip_change_master= 1] # [--let $rpl_skip_start_slave= 1] @@ -66,12 +65,6 @@ # want to specify the empty topology (no server replicates at # all), you have to set $rpl_topology=none. # -# $rpl_extra_connections_per_server -# By default, this script creates connections server_N and -# server_N_1. If you can set this variable to a number, the -# script creates: -# server_N, server_N_1, ..., server_N_$rpl_extra_connections_per_server -# # $rpl_check_server_ids # If $rpl_check_server_ids is set, this script checks that the # @@server_id of all servers are different. This is normally @@ -146,17 +139,8 @@ if (!$SERVER_MYPORT_4) # Check that $rpl_server_count is set if (!$rpl_server_count) { - --let $rpl_server_count= `SELECT REPLACE('$rpl_topology', '->', ',')` - if (`SELECT LOCATE(',', '$rpl_server_count')`) - { - --let $rpl_server_count= `SELECT GREATEST($rpl_server_count)` - } -} - ---let $_rpl_extra_connections_per_server= $rpl_extra_connections_per_server -if ($_rpl_extra_connections_per_server == '') -{ - --let $_rpl_extra_connections_per_server= 1 + --let $_compute_rpl_server_count= `SELECT REPLACE('$rpl_topology', '->', ',')` + --let $rpl_server_count= `SELECT GREATEST($_compute_rpl_server_count)` } @@ -175,20 +159,15 @@ if (!$rpl_debug) # Create two connections to each server; reset master/slave, select # database, set autoinc variables. --let $_rpl_server= $rpl_server_count ---let $underscore= _ +--let $_rpl_one= _1 while ($_rpl_server) { # Connect. --let $rpl_server_number= $_rpl_server --let $rpl_connection_name= server_$_rpl_server --source include/rpl_connect.inc - --let $_rpl_connection_number= 1 - while ($_rpl_connection_number <= $_rpl_extra_connections_per_server) - { - --let $rpl_connection_name= server_$_rpl_server$underscore$_rpl_connection_number - --source include/rpl_connect.inc - --inc $_rpl_connection_number - } + --let $rpl_connection_name= server_$_rpl_server$_rpl_one + --source include/rpl_connect.inc # Configure server. --let $rpl_connection_name= server_$_rpl_server diff --git a/mysql-test/include/rpl_reconnect.inc b/mysql-test/include/rpl_reconnect.inc index 673f382bac023..cdbbd0a1bf112 100644 --- a/mysql-test/include/rpl_reconnect.inc +++ b/mysql-test/include/rpl_reconnect.inc @@ -12,7 +12,6 @@ # ==== Usage ==== # # --let $rpl_server_number= N -# [--let $rpl_extra_connections_per_server= 1] # [--let $rpl_debug= 1] # --source include/rpl_reconnect.inc # @@ -22,7 +21,7 @@ # master server, 2 the slave server, 3 the 3rd server, and so on. # Cf. include/rpl_init.inc # -# $rpl_extra_connections_per_server, $rpl_debug +# $rpl_debug # See include/rpl_init.inc --let $include_filename= rpl_reconnect.inc @@ -33,11 +32,6 @@ if (!$rpl_server_number) --die ERROR IN TEST: you must set $rpl_server_number before you source rpl_connect.inc } -if ($_rpl_extra_connections_per_server == '') -{ - --let $_rpl_extra_connections_per_server= 1 -} - if ($rpl_debug) { @@ -78,14 +72,10 @@ if (!$_rpl_server_number) --source include/rpl_connection.inc --enable_reconnect ---let $_rpl_connection_number= 1 -while ($_rpl_connection_number <= $_rpl_extra_connections_per_server) -{ - --let $rpl_connection_name= server_$rpl_server_number$underscore$_rpl_connection_number - --source include/rpl_connection.inc - --enable_reconnect - --inc $_rpl_connection_number -} +--let $_rpl_one= _1 +--let $rpl_connection_name= server_$rpl_server_number$_rpl_one +--source include/rpl_connection.inc +--enable_reconnect if ($rpl_debug) { @@ -132,15 +122,10 @@ if (!$_rpl_server_number) --source include/wait_until_connected_again.inc --disable_reconnect ---let $_rpl_connection_number= 1 -while ($_rpl_connection_number <= $_rpl_extra_connections_per_server) -{ - --let $rpl_connection_name= server_$rpl_server_number$underscore$_rpl_connection_number - --source include/rpl_connection.inc - --source include/wait_until_connected_again.inc - --disable_reconnect - --inc $_rpl_connection_number -} +--let $rpl_connection_name= server_$rpl_server_number$_rpl_one +--source include/rpl_connection.inc +--source include/wait_until_connected_again.inc +--disable_reconnect --let $include_filename= rpl_reconnect.inc diff --git a/mysql-test/include/start_slave_sql.inc b/mysql-test/include/start_slave_sql.inc deleted file mode 100644 index 9cb66a2eb402c..0000000000000 --- a/mysql-test/include/start_slave_sql.inc +++ /dev/null @@ -1,39 +0,0 @@ -# ==== Purpose ==== -# -# Issues START SLAVE SQL_THREAD on the current connection. Then waits -# until the SQL thread has started, or until a timeout is reached. -# -# Please use this instead of 'START SLAVE SQL_THREAD', to reduce the -# risk of races in test cases. -# -# -# ==== Usage ==== -# -# [--let $slave_timeout= NUMBER] -# [--let $rpl_debug= 1] -# --source include/start_slave_sql.inc -# -# Parameters: -# $slave_timeout -# See include/wait_for_slave_param.inc -# -# $rpl_debug -# See include/rpl_init.inc - - ---let $include_filename= start_slave_sql.inc ---source include/begin_include_file.inc - - -if (!$rpl_debug) -{ - --disable_query_log -} - - -START SLAVE SQL_THREAD; ---source include/wait_for_slave_sql_to_start.inc - - ---let $include_filename= start_slave_sql.inc ---source include/end_include_file.inc diff --git a/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result b/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result deleted file mode 100644 index b11ad4f53bd7e..0000000000000 --- a/mysql-test/suite/rpl/r/rpl_io_thd_wait_for_disk_space.result +++ /dev/null @@ -1,15 +0,0 @@ -include/master-slave.inc -[connection master] -CREATE TABLE t1(a INT); -INSERT INTO t1 VALUES(1); -CALL mtr.add_suppression("Disk is full writing"); -CALL mtr.add_suppression("Retry in 60 secs"); -include/stop_slave_sql.inc -SET @@GLOBAL.DEBUG= 'd,simulate_io_thd_wait_for_disk_space'; -INSERT INTO t1 VALUES(2); -SET DEBUG_SYNC='now WAIT_FOR parked'; -SET @@GLOBAL.DEBUG= '$debug_saved'; -include/assert_grep.inc [Found the disk full error message on the slave] -include/start_slave_sql.inc -DROP TABLE t1; -include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test b/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test deleted file mode 100644 index 6076be60ebc4b..0000000000000 --- a/mysql-test/suite/rpl/t/rpl_io_thd_wait_for_disk_space.test +++ /dev/null @@ -1,71 +0,0 @@ -# ==== Purpose ==== -# -# Check that the execution of SHOW SLAVE STATUS command is not blocked when IO -# thread is blocked waiting for disk space. -# -# ==== Implementation ==== -# -# Simulate a scenario where IO thread is waiting for disk space while writing -# into the relay log. Execute SHOW SLAVE STATUS command after IO thread is -# blocked waiting for space. The command should not be blocked. -# -# ==== References ==== -# -# Bug#21753696: MAKE SHOW SLAVE STATUS NON BLOCKING IF IO THREAD WAITS FOR -# DISK SPACE -# Bug#20685029: SLAVE IO THREAD SHOULD STOP WHEN DISK IS FULL -# -############################################################################### ---source include/have_debug.inc -# Inorder to grep a specific error pattern in error log a fresh error log -# needs to be generated. ---source include/force_restart.inc ---source include/master-slave.inc - -# Generate events to be replicated to the slave -CREATE TABLE t1(a INT); -INSERT INTO t1 VALUES(1); ---sync_slave_with_master - -# Those errors will only happen in the slave -CALL mtr.add_suppression("Disk is full writing"); -CALL mtr.add_suppression("Retry in 60 secs"); - -# Stop the SQL thread to avoid writing on disk ---source include/stop_slave_sql.inc - -# Set the debug option that will simulate disk full ---let $debug_saved= `SELECT @@GLOBAL.DEBUG` -SET @@GLOBAL.DEBUG= 'd,simulate_io_thd_wait_for_disk_space'; - -# Generate events to be replicated to the slave ---connection master -INSERT INTO t1 VALUES(2); - ---connection slave1 -SET DEBUG_SYNC='now WAIT_FOR parked'; - -# Get the relay log file name using SHOW SLAVE STATUS ---let $relay_log_file= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1) - ---connection slave -# Restore the debug options to "simulate" freed space on disk -SET @@GLOBAL.DEBUG= '$debug_saved'; - -# There should be a message in the error log of the slave stating -# that it was waiting for space to write on the relay log. ---let $assert_file=$MYSQLTEST_VARDIR/log/mysqld.2.err -# Grep only after the message that the I/O thread has started ---let $assert_only_after= Slave I/O .* connected to master .*replication started in log .* at position ---let $assert_count= 1 ---let $assert_select=Disk is full writing .*$relay_log_file.* ---let $assert_text= Found the disk full error message on the slave ---source include/assert_grep.inc - -# Start the SQL thread to let the slave to sync and finish gracefully ---source include/start_slave_sql.inc - -# Cleanup ---connection master -DROP TABLE t1; ---source include/rpl_end.inc diff --git a/mysys/errors.c b/mysys/errors.c index b606446053570..a6e2e300a1fa9 100644 --- a/mysys/errors.c +++ b/mysys/errors.c @@ -15,7 +15,7 @@ #include "mysys_priv.h" #include "mysys_err.h" -#include "m_string.h" + #ifndef SHARED_LIBRARY const char *globerrs[GLOBERRS]= @@ -109,7 +109,6 @@ void init_glob_errs() */ void wait_for_free_space(const char *filename, int errors) { - size_t time_to_sleep= MY_WAIT_FOR_USER_TO_FIX_PANIC; if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE)) { my_printf_warning(EE(EE_DISK_FULL), @@ -120,15 +119,10 @@ void wait_for_free_space(const char *filename, int errors) } DBUG_EXECUTE_IF("simulate_no_free_space_error", { - time_to_sleep= 1; - }); - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", - { - time_to_sleep= 1; + (void) sleep(1); + return; }); - - (void) sleep(time_to_sleep); - DEBUG_SYNC_C("disk_full_reached"); + (void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC); } const char **get_global_errmsgs() diff --git a/mysys/my_write.c b/mysys/my_write.c index 2e68a4dcff3a6..f092420756e3f 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -24,7 +24,6 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { size_t writtenbytes, written; uint errors; - size_t ToWriteCount; DBUG_ENTER("my_write"); DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d", Filedes, Buffer, (ulong) Count, MyFlags)); @@ -38,14 +37,11 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) { DBUG_SET("+d,simulate_file_write_error");}); for (;;) { - ToWriteCount= Count; - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { ToWriteCount= 1; }); #ifdef _WIN32 - writtenbytes= my_win_write(Filedes, Buffer, ToWriteCount); + writtenbytes= my_win_write(Filedes, Buffer, Count); #else - writtenbytes= write(Filedes, Buffer, ToWriteCount); + writtenbytes= write(Filedes, Buffer, Count); #endif - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", { errno= ENOSPC; }); DBUG_EXECUTE_IF("simulate_file_write_error", { errno= ENOSPC; diff --git a/sql/log.cc b/sql/log.cc index a7f05905514f7..42937ec16829f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -37,7 +37,6 @@ #include "log_event.h" // Query_log_event #include "rpl_filter.h" #include "rpl_rli.h" -#include "rpl_mi.h" #include "sql_audit.h" #include "sql_show.h" @@ -4378,22 +4377,13 @@ int MYSQL_BIN_LOG::new_file_impl(bool need_lock) } -#ifdef HAVE_REPLICATION -bool MYSQL_BIN_LOG::append(Log_event* ev, Master_info *mi) +bool MYSQL_BIN_LOG::append(Log_event* ev) { bool error = 0; - mysql_mutex_assert_owner(&mi->data_lock); mysql_mutex_lock(&LOCK_log); DBUG_ENTER("MYSQL_BIN_LOG::append"); DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); - /* - Release data_lock by holding LOCK_log, while writing into the relay log. - If slave IO thread waits here for free space, we don't want - SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is - sufficient to block SQL thread when IO thread is updating relay log here. - */ - mysql_mutex_unlock(&mi->data_lock); /* Log_event::write() is smart enough to use my_b_write() or my_b_append() depending on the kind of cache we have. @@ -4408,58 +4398,24 @@ bool MYSQL_BIN_LOG::append(Log_event* ev, Master_info *mi) if (flush_and_sync(0)) goto err; if ((uint) my_b_append_tell(&log_file) > max_size) - { - /* - If rotation is required we must acquire data_lock to protect - description_event from clients executing FLUSH LOGS in parallel. - In order do that we must release the existing LOCK_log so that we - get it once again in proper locking order to avoid dead locks. - i.e data_lock , LOCK_log. - */ - mysql_mutex_unlock(&LOCK_log); - mysql_mutex_lock(&mi->data_lock); - mysql_mutex_lock(&LOCK_log); error= new_file_without_locking(); - /* - After rotation release data_lock, we need the LOCK_log till we signal - the updation. - */ - mysql_mutex_unlock(&mi->data_lock); - } err: - signal_update(); // Safe as we don't call close mysql_mutex_unlock(&LOCK_log); - mysql_mutex_lock(&mi->data_lock); + signal_update(); // Safe as we don't call close DBUG_RETURN(error); } -bool MYSQL_BIN_LOG::appendv(Master_info* mi, const char* buf, uint len,...) +bool MYSQL_BIN_LOG::appendv(const char* buf, uint len,...) { bool error= 0; DBUG_ENTER("MYSQL_BIN_LOG::appendv"); va_list(args); va_start(args,len); - mysql_mutex_assert_owner(&mi->data_lock); - mysql_mutex_lock(&LOCK_log); DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); - /* - Release data_lock by holding LOCK_log, while writing into the relay log. - If slave IO thread waits here for free space, we don't want - SHOW SLAVE STATUS to hang on mi->data_lock. Note LOCK_log mutex is - sufficient to block SQL thread when IO thread is updating relay log here. - */ - mysql_mutex_unlock(&mi->data_lock); - DBUG_EXECUTE_IF("simulate_io_thd_wait_for_disk_space", - { - const char act[]= "disk_full_reached SIGNAL parked"; - DBUG_ASSERT(opt_debug_sync_timeout > 0); - DBUG_ASSERT(!debug_sync_set_action(current_thd, - STRING_WITH_LEN(act))); - };); - + mysql_mutex_assert_owner(&LOCK_log); do { if (my_b_append(&log_file,(uchar*) buf,len)) @@ -4472,34 +4428,13 @@ bool MYSQL_BIN_LOG::appendv(Master_info* mi, const char* buf, uint len,...) DBUG_PRINT("info",("max_size: %lu",max_size)); if (flush_and_sync(0)) goto err; - if ((uint) my_b_append_tell(&log_file) > - DBUG_EVALUATE_IF("rotate_slave_debug_group", 500, max_size)) - { - /* - If rotation is required we must acquire data_lock to protect - description_event from clients executing FLUSH LOGS in parallel. - In order do that we must release the existing LOCK_log so that we - get it once again in proper locking order to avoid dead locks. - i.e data_lock , LOCK_log. - */ - mysql_mutex_unlock(&LOCK_log); - mysql_mutex_lock(&mi->data_lock); - mysql_mutex_lock(&LOCK_log); + if ((uint) my_b_append_tell(&log_file) > max_size) error= new_file_without_locking(); - /* - After rotation release data_lock, we need the LOCK_log till we signal - the updation. - */ - mysql_mutex_unlock(&mi->data_lock); - } err: if (!error) signal_update(); - mysql_mutex_unlock(&LOCK_log); - mysql_mutex_lock(&mi->data_lock); DBUG_RETURN(error); } -#endif bool MYSQL_BIN_LOG::flush_and_sync(bool *synced) { diff --git a/sql/log.h b/sql/log.h index 7d1c3161ac200..4d13e4d0720bb 100644 --- a/sql/log.h +++ b/sql/log.h @@ -20,7 +20,6 @@ #include "handler.h" /* my_xid */ class Relay_log_info; -class Master_info; class Format_description_log_event; @@ -455,8 +454,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG v stands for vector invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0) */ - bool appendv(Master_info* mi, const char* buf,uint len,...); - bool append(Log_event* ev, Master_info* mi); + bool appendv(const char* buf,uint len,...); + bool append(Log_event* ev); void make_log_name(char* buf, const char* log_ident); bool is_active(const char* log_file_name); diff --git a/sql/slave.cc b/sql/slave.cc index 31037c453d317..acf68e231f310 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1660,7 +1660,7 @@ Waiting for the slave SQL thread to free enough relay log space"); #endif if (rli->sql_force_rotate_relay) { - rotate_relay_log(rli->mi, true/*need_data_lock=true*/); + rotate_relay_log(rli->mi); rli->sql_force_rotate_relay= false; } @@ -1705,7 +1705,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, Master_info *mi) if (likely((bool)ev)) { ev->server_id= 0; // don't be ignored by slave SQL thread - if (unlikely(rli->relay_log.append(ev, mi))) + if (unlikely(rli->relay_log.append(ev))) mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), "failed to write a Rotate event" @@ -3605,7 +3605,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) break; Execute_load_log_event xev(thd,0,0); xev.log_pos = cev->log_pos; - if (unlikely(mi->rli.relay_log.append(&xev, mi))) + if (unlikely(mi->rli.relay_log.append(&xev))) { mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), @@ -3619,7 +3619,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) { cev->block = net->read_pos; cev->block_len = num_bytes; - if (unlikely(mi->rli.relay_log.append(cev, mi))) + if (unlikely(mi->rli.relay_log.append(cev))) { mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), @@ -3634,7 +3634,7 @@ static int process_io_create_file(Master_info* mi, Create_file_log_event* cev) aev.block = net->read_pos; aev.block_len = num_bytes; aev.log_pos = cev->log_pos; - if (unlikely(mi->rli.relay_log.append(&aev, mi))) + if (unlikely(mi->rli.relay_log.append(&aev))) { mi->report(ERROR_LEVEL, ER_SLAVE_RELAY_LOG_WRITE_FAILURE, ER(ER_SLAVE_RELAY_LOG_WRITE_FAILURE), @@ -3713,7 +3713,7 @@ static int process_io_rotate(Master_info *mi, Rotate_log_event *rev) Rotate the relay log makes binlog format detection easier (at next slave start or mysqlbinlog) */ - DBUG_RETURN(rotate_relay_log(mi, false/*need_data_lock=false*/)); + DBUG_RETURN(rotate_relay_log(mi) /* will take the right mutexes */); } /* @@ -3819,7 +3819,7 @@ static int queue_binlog_ver_1_event(Master_info *mi, const char *buf, Log_event::Log_event(const char* buf...) in log_event.cc). */ ev->log_pos+= event_len; /* make log_pos be the pos of the end of the event */ - if (unlikely(rli->relay_log.append(ev, mi))) + if (unlikely(rli->relay_log.append(ev))) { delete ev; mysql_mutex_unlock(&mi->data_lock); @@ -3875,7 +3875,7 @@ static int queue_binlog_ver_3_event(Master_info *mi, const char *buf, inc_pos= event_len; break; } - if (unlikely(rli->relay_log.append(ev, mi))) + if (unlikely(rli->relay_log.append(ev))) { delete ev; mysql_mutex_unlock(&mi->data_lock); @@ -4083,6 +4083,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) direct master (an unsupported, useless setup!). */ + mysql_mutex_lock(log_lock); s_id= uint4korr(buf + SERVER_ID_OFFSET); if ((s_id == ::server_id && !mi->rli.replicate_same_server_id) || /* @@ -4115,7 +4116,6 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) IGNORE_SERVER_IDS it increments mi->master_log_pos as well as rli->group_relay_log_pos. */ - mysql_mutex_lock(log_lock); if (!(s_id == ::server_id && !mi->rli.replicate_same_server_id) || (buf[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT && buf[EVENT_TYPE_OFFSET] != ROTATE_EVENT && @@ -4127,14 +4127,13 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) rli->ign_master_log_pos_end= mi->master_log_pos; } rli->relay_log.signal_update(); // the slave SQL thread needs to re-check - mysql_mutex_unlock(log_lock); DBUG_PRINT("info", ("master_log_pos: %lu, event originating from %u server, ignored", (ulong) mi->master_log_pos, uint4korr(buf + SERVER_ID_OFFSET))); } else { /* write the event to the relay log */ - if (likely(!(rli->relay_log.appendv(mi, buf,event_len,0)))) + if (likely(!(rli->relay_log.appendv(buf,event_len,0)))) { mi->master_log_pos+= inc_pos; DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos)); @@ -4144,10 +4143,9 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) { error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE; } - mysql_mutex_lock(log_lock); rli->ign_master_log_name_end[0]= 0; // last event is not ignored - mysql_mutex_unlock(log_lock); } + mysql_mutex_unlock(log_lock); skip_relay_logging: @@ -5007,21 +5005,11 @@ event(errno: %d cur_log->error: %d)", locks; here we don't, so this function is mainly taking locks). Returns nothing as we cannot catch any error (MYSQL_BIN_LOG::new_file() is void). - - @param mi Master_info for the IO thread. - @param need_data_lock If true, mi->data_lock will be acquired otherwise, - mi->data_lock must be held by the caller. */ -int rotate_relay_log(Master_info* mi, bool need_data_lock) +int rotate_relay_log(Master_info* mi) { DBUG_ENTER("rotate_relay_log"); - if (need_data_lock) - mysql_mutex_lock(&mi->data_lock); - else - { - mysql_mutex_assert_owner(&mi->data_lock); - } Relay_log_info* rli= &mi->rli; int error= 0; @@ -5056,8 +5044,6 @@ int rotate_relay_log(Master_info* mi, bool need_data_lock) */ rli->relay_log.harvest_bytes_written(&rli->log_space_total); end: - if (need_data_lock) - mysql_mutex_unlock(&mi->data_lock); DBUG_RETURN(error); } diff --git a/sql/slave.h b/sql/slave.h index 0cf8adb0315e7..7bf136694cce6 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -205,7 +205,7 @@ int purge_relay_logs(Relay_log_info* rli, THD *thd, bool just_reset, const char** errmsg); void set_slave_thread_options(THD* thd); void set_slave_thread_default_charset(THD *thd, Relay_log_info const *rli); -int rotate_relay_log(Master_info* mi, bool need_data_lock); +int rotate_relay_log(Master_info* mi); int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli); pthread_handler_t handle_slave_io(void *arg); diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index f24f31b6399c8..b29cc9a94331f 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -157,7 +157,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, { #ifdef HAVE_REPLICATION mysql_mutex_lock(&LOCK_active_mi); - if (rotate_relay_log(active_mi, true/*need_data_lock=true*/)) + if (rotate_relay_log(active_mi)) *write_to_binlog= -1; mysql_mutex_unlock(&LOCK_active_mi); #endif From c92f2606ea6c9ab519ff1d0313a54f4fac95ce33 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 21 May 2016 12:11:27 +0200 Subject: [PATCH 027/112] Commit changes made from 10.1 --- storage/connect/ha_connect.cc | 34 +- storage/connect/jdbconn.cpp | 589 ++++++++++++++++------------------ storage/connect/jdbconn.h | 28 +- storage/connect/tabjdbc.cpp | 131 +++++++- storage/connect/tabjdbc.h | 3 + 5 files changed, 453 insertions(+), 332 deletions(-) diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index 58a761f442d93..0534884e68413 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -119,6 +119,7 @@ #undef OFFSET #define NOPARSE +#define NJDBC #if defined(UNIX) #include "osutil.h" #endif // UNIX @@ -128,7 +129,7 @@ #include "odbccat.h" #endif // ODBC_SUPPORT #if defined(JDBC_SUPPORT) -#include "jdbccat.h" +#include "tabjdbc.h" #include "jdbconn.h" #endif // JDBC_SUPPORT #include "xtable.h" @@ -5224,7 +5225,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, #endif #if defined(JDBC_SUPPORT) driver= GetListOption(g, "Driver", topt->oplist, NULL); - url= GetListOption(g, "URL", topt->oplist, NULL); +// url= GetListOption(g, "URL", topt->oplist, NULL); tabtyp = GetListOption(g, "Tabtype", topt->oplist, NULL); #endif // JDBC_SUPPORT mxe= atoi(GetListOption(g,"maxerr", topt->oplist, "0")); @@ -5325,18 +5326,31 @@ static int connect_assisted_discovery(handlerton *, THD* thd, case TAB_JDBC: if (fnc & FNC_DRIVER) { ok= true; - } else if (!url && !(url= strz(g, create_info->connect_string))) { + } else if (!(url= strz(g, create_info->connect_string))) { strcpy(g->Message, "Missing URL"); } else { - // Store ODBC additional parameters + // Store JDBC additional parameters + int rc; + PJDBCDEF jdef= new(g) JDBCDEF(); + + jdef->SetName(create_info->alias); sjp= (PJPARM)PlugSubAlloc(g, NULL, sizeof(JDBCPARM)); sjp->Driver= driver; - sjp->Url= url; - sjp->User= (char*)user; - sjp->Pwd= (char*)pwd; sjp->Fsize= 0; sjp->Scrollable= false; - ok= true; + + if ((rc = jdef->ParseURL(g, url, false)) == RC_OK) { + sjp->Url= url; + sjp->User= (char*)user; + sjp->Pwd= (char*)pwd; + ok= true; + } else if (rc == RC_NF) { + if (jdef->GetTabname()) + tab= jdef->GetTabname(); + + ok= jdef->SetParms(sjp); + } // endif rc + } // endif's supfnc |= (FNC_DRIVER | FNC_TABLE); @@ -5775,12 +5789,10 @@ static int connect_assisted_discovery(handlerton *, THD* thd, switch (typ) { case TYPE_DOUBLE: + case TYPE_DECIM: // Some data sources do not count dec in length (prec) prec += (dec + 2); // To be safe break; - case TYPE_DECIM: - prec= len; - break; default: dec= 0; } // endswitch typ diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 88557fdd420d3..286d1141fe804 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -38,7 +38,6 @@ #include "plgdbsem.h" #include "xobject.h" #include "xtable.h" -#include "jdbccat.h" #include "tabjdbc.h" //#include "jdbconn.h" //#include "plgcnx.h" // For DB types @@ -63,6 +62,9 @@ extern char *ClassPath; // The connect_class_path global variable value void *JDBConn::LibJvm = NULL; CRTJVM JDBConn::CreateJavaVM = NULL; GETJVM JDBConn::GetCreatedJavaVMs = NULL; +#if defined(_DEBUG) +GETDEF JDBConn::GetDefaultJavaVMInitArgs = NULL; +#endif // _DEBUG /***********************************************************************/ /* Some macro's (should be defined elsewhere to be more accessible) */ @@ -118,6 +120,7 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) break; case 2: // NUMERIC case 3: // DECIMAL + case -3: // VARBINARY type = TYPE_DECIM; break; case 4: // INTEGER @@ -155,7 +158,6 @@ int TranslateJDBCType(int stp, int prec, int& len, char& v) break; case 0: // NULL case -2: // BINARY - case -3: // VARBINARY case -4: // LONGVARBINARY default: type = TYPE_ERROR; @@ -318,12 +320,15 @@ PQRYRES JDBCColumns(PGLOBAL g, char *db, char *table, char *colpat, /**************************************************************************/ PQRYRES JDBCSrcCols(PGLOBAL g, char *src, PJPARM sjp) { + PQRYRES qrp; JDBConn *jcp = new(g)JDBConn(g, NULL); if (jcp->Open(sjp)) return NULL; - return jcp->GetMetaData(g, src); + qrp = jcp->GetMetaData(g, src); + jcp->Close(); + return qrp; } // end of JDBCSrcCols /**************************************************************************/ @@ -361,14 +366,14 @@ PQRYRES JDBCTables(PGLOBAL g, char *db, char *tabpat, char *tabtyp, n = jcp->GetMaxValue(2); // Max catalog name length - if (n < 0) - return NULL; +// if (n < 0) +// return NULL; - length[0] = (n) ? (n + 1) : 0; + length[0] = (n > 0) ? (n + 1) : 0; n = jcp->GetMaxValue(3); // Max schema name length - length[1] = (n) ? (n + 1) : 0; + length[1] = (n > 0) ? (n + 1) : 0; n = jcp->GetMaxValue(4); // Max table name length - length[2] = (n) ? (n + 1) : 128; + length[2] = (n > 0) ? (n + 1) : 128; } else { maxres = 0; length[0] = 128; @@ -642,11 +647,13 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) env= nullptr; // Pointer to native interface jdi = nullptr; // Pointer to the JdbcInterface class job = nullptr; // The JdbcInterface class object - xqid = xuid = xid = grs = readid = fetchid = typid = nullptr; + xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr; prepid = xpid = pcid = nullptr; + chrfldid = intfldid = dblfldid = fltfldid = datfldid = bigfldid = nullptr; //m_LoginTimeout = DEFAULT_LOGIN_TIMEOUT; //m_QueryTimeout = DEFAULT_QUERY_TIMEOUT; //m_UpdateOptions = 0; + Msg = NULL; m_Driver = NULL; m_Url = NULL; m_User = NULL; @@ -676,10 +683,11 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) /***********************************************************************/ /* Screen for errors. */ /***********************************************************************/ -char *JDBConn::Check(void) +bool JDBConn::Check(jint rc) { + jstring s; + if (env->ExceptionCheck()) { - char *msg; jthrowable exc = env->ExceptionOccurred(); jmethodID tid = env->GetMethodID(env->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;"); @@ -688,17 +696,39 @@ char *JDBConn::Check(void) jstring s = (jstring)env->CallObjectMethod(exc, tid); const char *utf = env->GetStringUTFChars(s, (jboolean)false); env->DeleteLocalRef(s); - msg = PlugDup(m_G, utf); + Msg = PlugDup(m_G, utf); } else - msg = "Exception occured"; + Msg = "Exception occured"; env->ExceptionClear(); - return msg; - } // endif Check + } else if (rc < 0) { + s = (jstring)env->CallObjectMethod(job, errid); + Msg = (char*)env->GetStringUTFChars(s, (jboolean)false); + } else + Msg = NULL; - return NULL; + return (Msg != NULL); } // end of Check +/***********************************************************************/ +/* Get MethodID if not exists yet. */ +/***********************************************************************/ +bool JDBConn::gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig) +{ + if (mid == nullptr) { + mid = env->GetMethodID(jdi, name, sig); + + if (Check()) { + strcpy(g->Message, Msg); + return true; + } else + return false; + + } else + return false; + +} // end of gmID + #if 0 /***********************************************************************/ /* Utility routine. */ @@ -758,15 +788,17 @@ void JDBConn::OnSetOptions(HSTMT hstmt) /***********************************************************************/ int JDBConn::GetMaxValue(int n) { - jmethodID maxid = env->GetMethodID(jdi, "GetMaxValue", "(I)I"); + jint m; + jmethodID maxid = nullptr; - if (maxid == nullptr) { - strcpy(m_G->Message, "ERROR: method GetMaxValue not found !"); + if (gmID(m_G, maxid, "GetMaxValue", "(I)I")) return -1; - } // endif maxid // call method - return (int)env->CallIntMethod(job, maxid, n); + if (Check(m = env->CallIntMethod(job, maxid, n))) + htrc("GetMaxValue: %s", Msg); + + return (int)m; } // end of GetMaxValue /***********************************************************************/ @@ -783,6 +815,9 @@ void JDBConn::ResetJVM(void) LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; +#if defined(_DEBUG) + GetDefaultJavaVMInitArgs = NULL; +#endif // _DEBUG } // endif LibJvm } // end of ResetJVM @@ -823,6 +858,14 @@ bool JDBConn::GetJVM(PGLOBAL g) sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), "JNI_GetCreatedJavaVMs"); FreeLibrary((HMODULE)LibJvm); LibJvm = NULL; +#if defined(_DEBUG) + } else if (!(GetDefaultJavaVMInitArgs = (GETDEF)GetProcAddress((HINSTANCE)LibJvm, + "JNI_GetDefaultJavaVMInitArgs"))) { + sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), + "JNI_GetDefaultJavaVMInitArgs"); + FreeLibrary((HMODULE)LibJvm); + LibJvm = NULL; +#endif // _DEBUG } // endif LibJvm #else // !__WIN__ const char *error = NULL; @@ -846,7 +889,15 @@ bool JDBConn::GetJVM(PGLOBAL g) sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetCreatedJavaVMs", SVP(error)); dlclose(LibJvm); LibJvm = NULL; - } // endif LibJvm +#if defined(_DEBUG) + } else if (!(GetDefaultJavaVMInitArgs = (GETDEF)dlsym(LibJvm, + "JNI_GetDefaultJavaVMInitArgs"))) { + error = dlerror(); + sprintf(g->Message, MSG(GET_FUNC_ERR), "JNI_GetDefaultJavaVMInitArgs", SVP(error)); + dlclose(LibJvm); + LibJvm = NULL; +#endif // _DEBUG + } // endif LibJvm #endif // !__WIN__ } // endif LibJvm @@ -859,6 +910,7 @@ bool JDBConn::GetJVM(PGLOBAL g) /***********************************************************************/ int JDBConn::Open(PJPARM sop) { + bool err = false; PGLOBAL& g = m_G; // Link or check whether jvm library was linked @@ -881,44 +933,59 @@ int JDBConn::Open(PJPARM sop) } // endif rc } else { - // Create a new jvm - PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path="); + /*******************************************************************/ + /* Create a new jvm */ + /*******************************************************************/ + PSTRG jpop = new(g)STRING(g, 512, "-Djava.class.path=."); char *cp = NULL; char sep; #if defined(__WIN__) sep = ';'; +#define N 1 +//#define N 2 +//#define N 3 #else sep = ':'; +#define N 1 #endif //================== prepare loading of Java VM ============================ JavaVMInitArgs vm_args; // Initialization arguments - JavaVMOption* options = new JavaVMOption[1]; // JVM invocation options + JavaVMOption* options = new JavaVMOption[N]; // JVM invocation options // where to find java .class - if ((cp = PlugDup(m_G, getenv("CLASSPATH")))) - jpop->Append(cp); - - if (trace) { - htrc("CLASSPATH=%s\n", getenv("CLASSPATH")); - htrc("ClassPath=%s\n", ClassPath); - } // endif trace - if (ClassPath && *ClassPath) { - if (cp) - jpop->Append(sep); - + jpop->Append(sep); jpop->Append(ClassPath); } // endif ClassPath - if (trace) + if ((cp = getenv("CLASSPATH"))) { + jpop->Append(sep); + jpop->Append(cp); + } // endif cp + + if (trace) { + htrc("ClassPath=%s\n", ClassPath); + htrc("CLASSPATH=%s\n", cp); htrc("%s\n", jpop->GetStr()); + } // endif trace options[0].optionString = jpop->GetStr(); - //options[1].optionString = "-verbose:jni"; +#if N == 2 + options[1].optionString = "-Xcheck:jni"; +#endif +#if N == 3 + options[1].optionString = "-Xms256M"; + options[2].optionString = "-Xmx512M"; +#endif +#if defined(_DEBUG) + vm_args.version = JNI_VERSION_1_2; // minimum Java version + rc = GetDefaultJavaVMInitArgs(&vm_args); +#else vm_args.version = JNI_VERSION_1_6; // minimum Java version - vm_args.nOptions = 1; // number of options +#endif // _DEBUG + vm_args.nOptions = N; // number of options vm_args.options = options; vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail @@ -956,8 +1023,10 @@ int JDBConn::Open(PJPARM sop) } // endif rc //=============== Display JVM version ======================================= -//jint ver = env->GetVersion(); -//cout << ((ver>>16)&0x0f) << "."<<(ver&0x0f) << endl; +#if defined(_DEBUG) + jint ver = env->GetVersion(); + printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); +#endif //_DEBUG // try to find the JdbcInterface class jdi = env->FindClass("JdbcInterface"); @@ -981,7 +1050,7 @@ int JDBConn::Open(PJPARM sop) jstring path = env->NewStringUTF(jpath); rc = env->CallStaticIntMethod(jdi, alp, path); - if ((msg = Check())) { + if ((msg = Check(rc))) { strcpy(g->Message, msg); env->DeleteLocalRef(path); return RC_FX; @@ -1022,33 +1091,36 @@ int JDBConn::Open(PJPARM sop) return RC_FX; } // endif job - if (!sop) // DRIVER catalog table - return RC_OK; - - jmethodID cid = env->GetMethodID(jdi, "JdbcConnect", "([Ljava/lang/String;IZ)I"); + errid = env->GetMethodID(jdi, "GetErrmsg", "()Ljava/lang/String;"); if (env->ExceptionCheck()) { - strcpy(g->Message, "ERROR: method JdbcConnect() not found!"); + strcpy(g->Message, "ERROR: method GetErrmsg() not found!"); env->ExceptionDescribe(); env->ExceptionClear(); return RC_FX; } // endif Check + if (!sop) // DRIVER catalog table + return RC_OK; + + jmethodID cid = nullptr; + + if (gmID(g, cid, "JdbcConnect", "([Ljava/lang/String;IZ)I")) + return RC_FX; + // Build the java string array jobjectArray parms = env->NewObjectArray(4, // constructs java array of 4 env->FindClass("java/lang/String"), NULL); // Strings - if (sop) { - m_Driver = sop->Driver; - m_Url = sop->Url; - m_User = sop->User; - m_Pwd = sop->Pwd; - m_Scrollable = sop->Scrollable; - m_RowsetSize = sop->Fsize; - //m_LoginTimeout = sop->Cto; - //m_QueryTimeout = sop->Qto; - //m_UseCnc = sop->UseCnc; - } // endif sop + m_Driver = sop->Driver; + m_Url = sop->Url; + m_User = sop->User; + m_Pwd = sop->Pwd; + m_Scrollable = sop->Scrollable; + m_RowsetSize = sop->Fsize; + //m_LoginTimeout = sop->Cto; + //m_QueryTimeout = sop->Qto; + //m_UseCnc = sop->UseCnc; // change some elements if (m_Driver) @@ -1065,23 +1137,17 @@ int JDBConn::Open(PJPARM sop) // call method rc = env->CallIntMethod(job, cid, parms, m_RowsetSize, m_Scrollable); + err = Check(rc); + env->DeleteLocalRef(parms); // Not used anymore - // Not used anymore - env->DeleteLocalRef(parms); - - if (rc != (jint)0) { - strcpy(g->Message, "Connection failed"); + if (err) { + sprintf(g->Message, "Connecting: %s rc=%d", Msg, (int)rc); return RC_FX; - } // endif rc + } // endif Msg - typid = env->GetMethodID(jdi, "ColumnType", "(ILjava/lang/String;)I"); - - if (env->ExceptionCheck()) { - strcpy(g->Message, "ERROR: method ColumnType() not found!"); - env->ExceptionDescribe(); - env->ExceptionClear(); + if (gmID(g, typid, "ColumnType", "(ILjava/lang/String;)I")) return RC_FX; - } else + else m_Opened = true; return RC_OK; @@ -1092,43 +1158,37 @@ int JDBConn::Open(PJPARM sop) /***********************************************************************/ int JDBConn::ExecSQLcommand(char *sql) { - int rc = RC_NF; + int rc; jint n; jstring qry; PGLOBAL& g = m_G; - if (xid == nullptr) { - // Get the methods used to execute a query and get the result - xid = env->GetMethodID(jdi, "Execute", "(Ljava/lang/String;)I"); - - if (xid == nullptr) { - strcpy(g->Message, "Cannot find method Execute"); - return RC_FX; - } else - grs = env->GetMethodID(jdi, "GetResult", "()I"); - - if (grs == nullptr) { - strcpy(g->Message, "Cannot find method GetResult"); - return RC_FX; - } // endif grs - - } // endif xid + // Get the methods used to execute a query and get the result + if (gmID(g, xid, "Execute", "(Ljava/lang/String;)I") || + gmID(g, grs, "GetResult", "()I")) + return RC_FX; qry = env->NewStringUTF(sql); n = env->CallIntMethod(job, xid, qry); env->DeleteLocalRef(qry); - if (n < 0) { - sprintf(g->Message, "Error executing %s", sql); + if (Check(n)) { + sprintf(g->Message, "Execute: %s", Msg); return RC_FX; } // endif n - if ((m_Ncol = env->CallIntMethod(job, grs))) { + m_Ncol = env->CallIntMethod(job, grs); + + if (Check(m_Ncol)) { + sprintf(g->Message, "GetResult: %s", Msg); + rc = RC_FX; + } else if (m_Ncol) { strcpy(g->Message, "Result set column number"); rc = RC_OK; // A result set was returned } else { m_Aff = (int)n; // Affected rows strcpy(g->Message, "Affected rows"); + rc = RC_NF; } // endif ncol return rc; @@ -1139,44 +1199,29 @@ int JDBConn::ExecSQLcommand(char *sql) /***********************************************************************/ int JDBConn::Fetch(int pos) { - jint rc; + jint rc = JNI_ERR; + PGLOBAL& g = m_G; if (m_Full) // Result set has one row return 1; if (pos) { if (!m_Scrollable) { - strcpy(m_G->Message, "Cannot fetch(pos) if FORWARD ONLY"); - return -1; - } else if (fetchid == nullptr) { - fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); - - if (fetchid == nullptr) { - strcpy(m_G->Message, "Cannot find method Fetch"); - return -1; - } // endif fetchid - - } // endif's + strcpy(g->Message, "Cannot fetch(pos) if FORWARD ONLY"); + return rc; + } else if (gmID(m_G, fetchid, "Fetch", "(I)Z")) + return rc; if (env->CallBooleanMethod(job, fetchid, pos)) rc = m_Rows; - else - rc = -1; } else { - if (readid == nullptr) { - readid = env->GetMethodID(jdi, "ReadNext", "()I"); - - if (readid == nullptr) { - strcpy(m_G->Message, "Cannot find method ReadNext"); - return -1; - } // endif readid - - } // endif readid + if (gmID(g, readid, "ReadNext", "()I")) + return rc; rc = env->CallBooleanMethod(job, readid); - if (rc >= 0) { + if (!Check(rc)) { if (rc == 0) m_Full = (m_Fetch == 1); else @@ -1184,7 +1229,7 @@ int JDBConn::Fetch(int pos) m_Rows += (int)rc; } else - strcpy(m_G->Message, "Error fetching next row"); + sprintf(g->Message, "Fetch: %s", Msg); } // endif pos @@ -1201,15 +1246,8 @@ int JDBConn::Rewind(char *sql) if (m_Full) rbuf = m_Rows; // No need to "rewind" else if (m_Scrollable) { - if (fetchid == nullptr) { - fetchid = env->GetMethodID(jdi, "Fetch", "(I)Z"); - - if (fetchid == nullptr) { - strcpy(m_G->Message, "Cannot find method Fetch"); - return -1; - } // endif readid - - } // endif readid + if (gmID(m_G, fetchid, "Fetch", "(I)Z")) + return -1; jboolean b = env->CallBooleanMethod(job, fetchid, 0); @@ -1227,15 +1265,15 @@ void JDBConn::Close() { if (m_Opened) { jint rc; - jmethodID did = env->GetMethodID(jdi, "JdbcDisconnect", "()I"); + jmethodID did = nullptr; - if (did == nullptr) - printf("ERROR: method JdbcDisconnect() not found !"); - else if ((rc = env->CallIntMethod(job, did))) - printf("jdbcDisconnect: rc=%d", (int)rc); + if (gmID(m_G, did, "JdbcDisconnect", "()I")) + printf("%s\n", Msg); + else if (Check(env->CallIntMethod(job, did))) + printf("jdbcDisconnect: %s\n", Msg); - if ((rc = jvm->DetachCurrentThread())) - printf("DetachCurrentThread: rc = %d", (int)rc); + if ((rc = jvm->DetachCurrentThread()) != JNI_OK) + printf("DetachCurrentThread: rc=%d\n", (int)rc); //rc = jvm->DestroyJavaVM(); m_Opened = false; @@ -1249,12 +1287,10 @@ void JDBConn::Close() void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) { PGLOBAL& g = m_G; - char *msg; jint ctyp; jlong dtv; jstring cn, jn = nullptr; jobject dob; - jmethodID fldid = nullptr; if (rank == 0) if (!name || (jn = env->NewStringUTF(name)) == nullptr) { @@ -1262,10 +1298,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); } // endif name + // Returns 666 is case of error ctyp = env->CallIntMethod(job, typid, rank, jn); - if ((msg = Check())) { - sprintf(g->Message, "Getting ctyp: %s", msg); + if (Check((ctyp == 666) ? -1 : 1)) { + sprintf(g->Message, "Getting ctyp: %s", Msg); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); } // endif Check @@ -1273,11 +1310,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 12: // VARCHAR case -1: // LONGVARCHAR case 1: // CHAR - fldid = env->GetMethodID(jdi, "StringField", - "(ILjava/lang/String;)Ljava/lang/String;"); - - if (fldid != nullptr) { - cn = (jstring)env->CallObjectMethod(job, fldid, (jint)rank, jn); + if (!gmID(g, chrfldid, "StringField", "(ILjava/lang/String;)Ljava/lang/String;")) { + cn = (jstring)env->CallObjectMethod(job, chrfldid, (jint)rank, jn); if (cn) { const char *field = env->GetStringUTFChars(cn, (jboolean)false); @@ -1294,30 +1328,25 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 4: // INTEGER case 5: // SMALLINT case -6: // TINYINT - fldid = env->GetMethodID(jdi, "IntField", "(ILjava/lang/String;)I"); - - if (fldid != nullptr) - val->SetValue((int)env->CallIntMethod(job, fldid, rank, jn)); + if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I")) + val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn)); else val->Reset(); break; case 8: // DOUBLE + case 2: // NUMERIC case 3: // DECIMAL - fldid = env->GetMethodID(jdi, "DoubleField", "(ILjava/lang/String;)D"); - - if (fldid != nullptr) - val->SetValue((double)env->CallDoubleMethod(job, fldid, rank, jn)); + if (!gmID(g, dblfldid, "DoubleField", "(ILjava/lang/String;)D")) + val->SetValue((double)env->CallDoubleMethod(job, dblfldid, rank, jn)); else val->Reset(); break; case 7: // REAL case 6: // FLOAT - fldid = env->GetMethodID(jdi, "FloatField", "(ILjava/lang/String;)F"); - - if (fldid != nullptr) - val->SetValue((float)env->CallFloatMethod(job, fldid, rank, jn)); + if (!gmID(g, fltfldid, "FloatField", "(ILjava/lang/String;)F")) + val->SetValue((float)env->CallFloatMethod(job, fltfldid, rank, jn)); else val->Reset(); @@ -1325,11 +1354,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 91: // DATE case 92: // TIME case 93: // TIMESTAMP - fldid = env->GetMethodID(jdi, "TimestampField", - "(ILjava/lang/String;)Ljava/sql/Timestamp;"); - - if (fldid != nullptr) { - dob = env->CallObjectMethod(job, fldid, (jint)rank, jn); + if (!gmID(g, datfldid, "TimestampField", + "(ILjava/lang/String;)Ljava/sql/Timestamp;")) { + dob = env->CallObjectMethod(job, datfldid, (jint)rank, jn); if (dob) { jclass jts = env->FindClass("java/sql/Timestamp"); @@ -1355,10 +1382,8 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case -5: // BIGINT - fldid = env->GetMethodID(jdi, "BigintField", "(ILjava/lang/String;)J"); - - if (fldid != nullptr) - val->SetValue((long long)env->CallLongMethod(job, fldid, (jint)rank, jn)); + if (!gmID(g, bigfldid, "BigintField", "(ILjava/lang/String;)J")) + val->SetValue((long long)env->CallLongMethod(job, bigfldid, (jint)rank, jn)); else val->Reset(); @@ -1372,11 +1397,11 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) val->Reset(); } // endswitch Type - if ((msg = Check())) { + if (Check()) { if (rank == 0) env->DeleteLocalRef(jn); - sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", msg, rank, (int)ctyp); + sprintf(g->Message, "SetColumnValue: %s rank=%d ctyp=%d", Msg, rank, (int)ctyp); longjmp(g->jumper[g->jump_level], TYPE_AM_JDBC); } // endif Check @@ -1390,21 +1415,22 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) /***********************************************************************/ bool JDBConn::PrepareSQL(char *sql) { - if (prepid == nullptr) { - prepid = env->GetMethodID(jdi, "CreatePrepStmt", "(Ljava/lang/String;)Z"); + bool b = true; + PGLOBAL& g = m_G; - if (prepid == nullptr) { - strcpy(m_G->Message, "Cannot find method CreatePrepStmt"); - return true; - } // endif prepid + if (!gmID(g, prepid, "CreatePrepStmt", "(Ljava/lang/String;)I")) { + // Create the prepared statement + jstring qry = env->NewStringUTF(sql); + if (Check(env->CallBooleanMethod(job, prepid, qry))) + sprintf(g->Message, "CreatePrepStmt: %s", Msg); + else + b = false; + + env->DeleteLocalRef(qry); } // endif prepid - - // Create the prepared statement - jstring qry = env->NewStringUTF(sql); - jboolean b = env->CallBooleanMethod(job, prepid, qry); - env->DeleteLocalRef(qry); - return (bool)b; + + return b; } // end of PrepareSQL /***********************************************************************/ @@ -1412,32 +1438,25 @@ bool JDBConn::PrepareSQL(char *sql) /***********************************************************************/ int JDBConn::ExecuteQuery(char *sql) { + int rc = RC_FX; jint ncol; jstring qry; PGLOBAL& g = m_G; - if (xqid == nullptr) { - // Get the methods used to execute a query and get the result - xqid = env->GetMethodID(jdi, "ExecuteQuery", "(Ljava/lang/String;)I"); - - if (xqid == nullptr) { - strcpy(g->Message, "Cannot find method ExecuteQuery"); - return RC_FX; - } // endif !xqid - - } // endif xqid + // Get the methods used to execute a query and get the result + if (!gmID(g, xqid, "ExecuteQuery", "(Ljava/lang/String;)I")) { + qry = env->NewStringUTF(sql); + ncol = env->CallIntMethod(job, xqid, qry); - qry = env->NewStringUTF(sql); - ncol = env->CallIntMethod(job, xqid, qry); - env->DeleteLocalRef(qry); + if (!Check(ncol)) { + m_Ncol = (int)ncol; + m_Aff = 0; // Affected rows + rc = RC_OK; + } else + sprintf(g->Message, "ExecuteQuery: %s", Msg); - if (ncol < 0) { - sprintf(g->Message, "Error executing %s: ncol = %d", sql, ncol); - return RC_FX; - } else { - m_Ncol = (int)ncol; - m_Aff = 0; // Affected rows - } // endif ncol + env->DeleteLocalRef(qry); + } // endif xqid return RC_OK; } // end of ExecuteQuery @@ -1447,34 +1466,27 @@ int JDBConn::ExecuteQuery(char *sql) /***********************************************************************/ int JDBConn::ExecuteUpdate(char *sql) { + int rc = RC_FX; jint n; jstring qry; PGLOBAL& g = m_G; - if (xuid == nullptr) { - // Get the methods used to execute a query and get the affected rows - xuid = env->GetMethodID(jdi, "ExecuteUpdate", "(Ljava/lang/String;)I"); - - if (xuid == nullptr) { - strcpy(g->Message, "Cannot find method ExecuteUpdate"); - return RC_FX; - } // endif !xuid - - } // endif xuid + // Get the methods used to execute a query and get the affected rows + if (!gmID(g, xuid, "ExecuteUpdate", "(Ljava/lang/String;)I")) { + qry = env->NewStringUTF(sql); + n = env->CallIntMethod(job, xuid, qry); - qry = env->NewStringUTF(sql); - n = env->CallIntMethod(job, xuid, qry); - env->DeleteLocalRef(qry); + if (!Check(n)) { + m_Ncol = 0; + m_Aff = (int)n; // Affected rows + rc = RC_OK; + } else + sprintf(g->Message, "ExecuteUpdate: %s n=%d", Msg, n); - if (n < 0) { - sprintf(g->Message, "Error executing %s: n = %d", sql, n); - return RC_FX; - } else { - m_Ncol = 0; - m_Aff = (int)n; // Affected rows - } // endif n + env->DeleteLocalRef(qry); + } // endif xuid - return RC_OK; + return rc; } // end of ExecuteUpdate /***********************************************************************/ @@ -1507,32 +1519,21 @@ int JDBConn::ExecuteSQL(void) int rc = RC_FX; PGLOBAL& g = m_G; - if (xpid == nullptr) { - // Get the methods used to execute a prepared statement - xpid = env->GetMethodID(jdi, "ExecutePrep", "()I"); + // Get the methods used to execute a prepared statement + if (!gmID(g, xpid, "ExecutePrep", "()I")) { + jint n = env->CallIntMethod(job, xpid); - if (xpid == nullptr) { - strcpy(g->Message, "Cannot find method ExecutePrep"); - return rc; - } // endif xpid + if (n == -3) + strcpy(g->Message, "SQL statement is not prepared"); + else if (Check(n)) + sprintf(g->Message, "ExecutePrep: %s", Msg); + else { + m_Aff = (int)n; + rc = RC_OK; + } // endswitch n } // endif xpid - jint n = env->CallIntMethod(job, xpid); - - switch ((int)n) { - case -1: - case -2: - strcpy(g->Message, "Exception error thrown while executing SQL"); - break; - case -3: - strcpy(g->Message, "SQL statement is not prepared"); - break; - default: - m_Aff = (int)n; - rc = RC_OK; - } // endswitch n - return rc; } // end of ExecuteSQL @@ -1542,8 +1543,7 @@ int JDBConn::ExecuteSQL(void) bool JDBConn::SetParam(JDBCCOL *colp) { PGLOBAL& g = m_G; - char *msg; - int rc = false; + bool rc = false; PVAL val = colp->GetValue(); jint n, i = (jint)colp->GetRank(); jshort s; @@ -1557,58 +1557,38 @@ bool JDBConn::SetParam(JDBCCOL *colp) switch (val->GetType()) { case TYPE_STRING: - setid = env->GetMethodID(jdi, "SetStringParm", "(ILjava/lang/String;)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetStringParm"); + if (gmID(g, setid, "SetStringParm", "(ILjava/lang/String;)V")) return true; - } // endif setid jst = env->NewStringUTF(val->GetCharValue()); env->CallVoidMethod(job, setid, i, jst); break; case TYPE_INT: - setid = env->GetMethodID(jdi, "SetIntParm", "(II)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetIntParm"); + if (gmID(g, setid, "SetIntParm", "(II)V")) return true; - } // endif setid n = (jint)val->GetIntValue(); env->CallVoidMethod(job, setid, i, n); break; case TYPE_TINY: case TYPE_SHORT: - setid = env->GetMethodID(jdi, "SetShortParm", "(IS)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetShortParm"); + if (gmID(g, setid, "SetShortParm", "(IS)V")) return true; - } // endif setid s = (jshort)val->GetShortValue(); env->CallVoidMethod(job, setid, i, s); break; case TYPE_BIGINT: - setid = env->GetMethodID(jdi, "SetBigintParm", "(IJ)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot fing method SetBigintParm"); + if (gmID(g, setid, "SetBigintParm", "(IJ)V")) return true; - } // endif setid lg = (jlong)val->GetBigintValue(); env->CallVoidMethod(job, setid, i, lg); break; case TYPE_DOUBLE: case TYPE_DECIM: - setid = env->GetMethodID(jdi, "SetDoubleParm", "(ID)V"); - - if (setid == nullptr) { - strcpy(g->Message, "Cannot find method SetDoubleParm"); + if (gmID(g, setid, "SetDoubleParm", "(ID)V")) return true; - } // endif setid d = (jdouble)val->GetFloatValue(); env->CallVoidMethod(job, setid, i, d); @@ -1627,11 +1607,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) if ((datobj = env->NewObject(dat, dtc, lg)) == nullptr) { strcpy(g->Message, "Cannot make Timestamp object"); return true; - } else if ((setid = env->GetMethodID(jdi, "SetTimestampParm", - "(ILjava/sql/Timestamp;)V")) == nullptr) { - strcpy(g->Message, "Cannot find method SetTimestampParm"); + } else if (gmID(g, setid, "SetTimestampParm", "(ILjava/sql/Timestamp;)V")) return true; - } // endif setid env->CallVoidMethod(job, setid, i, datobj); break; @@ -1640,8 +1617,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) return true; } // endswitch Type - if ((msg = Check())) { - sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), msg); + if (Check()) { + sprintf(g->Message, "SetParam: col=%s msg=%s", colp->GetName(), Msg); rc = true; } // endif msg @@ -1707,14 +1684,10 @@ bool JDBConn::SetParam(JDBCCOL *colp) int i, n, size; PCOLRES crp; jstring js; - jmethodID gdid = env->GetMethodID(jdi, "GetDrivers", "([Ljava/lang/String;I)I"); - - if (env->ExceptionCheck()) { - strcpy(m_G->Message, "ERROR: method GetDrivers() not found!"); - env->ExceptionDescribe(); - env->ExceptionClear(); + jmethodID gdid = nullptr; + + if (gmID(m_G, gdid, "GetDrivers", "([Ljava/lang/String;I)I")) return true; - } // endif Check // Build the java string array jobjectArray s = env->NewObjectArray(4 * qrp->Maxres, @@ -1766,7 +1739,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) ushort i; jint *n = nullptr; jstring label; - jmethodID colid; + jmethodID colid = nullptr; int rc = ExecSQLcommand(src); if (rc == RC_NF) { @@ -1779,20 +1752,8 @@ bool JDBConn::SetParam(JDBCCOL *colp) return NULL; } // endif's - colid = env->GetMethodID(jdi, "ColumnDesc", "(I[I)Ljava/lang/String;"); - - if (colid == nullptr) { - strcpy(m_G->Message, "ERROR: method ColumnDesc() not found!"); - return NULL; - } // endif colid - - // Build the java string array - jintArray val = env->NewIntArray(4); - - if (val == nullptr) { - strcpy(m_G->Message, "Cannot allocate jint array"); + if (gmID(g, colid, "ColumnDesc", "(I[I)Ljava/lang/String;")) return NULL; - } // endif colid // Get max column name length len = GetMaxValue(5); @@ -1813,11 +1774,28 @@ bool JDBConn::SetParam(JDBCCOL *colp) case 5: crp->Name = "Nullable"; break; } // endswitch i + // Build the java string array + jintArray val = env->NewIntArray(4); + + if (val == nullptr) { + strcpy(m_G->Message, "Cannot allocate jint array"); + return NULL; + } // endif colid + /************************************************************************/ /* Now get the results into blocks. */ /************************************************************************/ for (i = 0; i < m_Ncol; i++) { - label = (jstring)env->CallObjectMethod(job, colid, i + 1, val); + if (!(label = (jstring)env->CallObjectMethod(job, colid, i + 1, val))) { + if (Check()) + sprintf(g->Message, "ColumnDesc: %s", Msg); + else + strcpy(g->Message, "No result metadata"); + + env->ReleaseIntArrayElements(val, n, 0); + return NULL; + } // endif label + name = env->GetStringUTFChars(label, (jboolean)false); crp = qrp->Colresp; // Column_Name crp->Kdata->SetValue((char*)name, i); @@ -1835,7 +1813,6 @@ bool JDBConn::SetParam(JDBCCOL *colp) /* Cleanup */ env->ReleaseIntArrayElements(val, n, 0); - Close(); /************************************************************************/ /* Return the result pointer for use by GetData routines. */ @@ -1962,7 +1939,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) PVAL *pval = NULL; char* *pbuf = NULL; jobjectArray parms; - jmethodID catid; + jmethodID catid = nullptr; if (qrp->Maxres <= 0) return 0; // 0-sized result" @@ -2008,16 +1985,18 @@ bool JDBConn::SetParam(JDBCCOL *colp) return -1; } // endswitch infotype - catid = env->GetMethodID(jdi, fnc, "([Ljava/lang/String;)I"); - - if (catid == nullptr) { - sprintf(g->Message, "ERROR: method %s not found !", fnc); + if (gmID(g, catid, fnc, "([Ljava/lang/String;)I")) return -1; - } // endif maxid // call method ncol = env->CallIntMethod(job, catid, parms); + if (Check(ncol)) { + sprintf(g->Message, "%s: %s", fnc, Msg); + env->DeleteLocalRef(parms); + return -1; + } // endif Check + // Not used anymore env->DeleteLocalRef(parms); @@ -2061,13 +2040,15 @@ bool JDBConn::SetParam(JDBCCOL *colp) // Now fetch the result for (i = 0; i < qrp->Maxres; i++) { - if ((rc = Fetch(0)) == 0) { + if (Check(rc = Fetch(0))) { + sprintf(g->Message, "Fetch: %s", Msg); + return -1; + } if (rc == 0) { if (trace) htrc("End of fetches i=%d\n", i); break; - } else if (rc < 0) - return -1; + } // endif rc for (n = 0, crp = qrp->Colresp; crp; n++, crp = crp->Next) { SetColumnValue(n + 1, nullptr, pval[n]); diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index 4014a52cdcc2b..a7744ba6ba1ac 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -53,6 +53,9 @@ typedef struct tagJCATPARM { typedef jint(JNICALL *CRTJVM) (JavaVM **, void **, void *); typedef jint(JNICALL *GETJVM) (JavaVM **, jsize, jsize *); +#if defined(_DEBUG) +typedef jint(JNICALL *GETDEF) (void *); +#endif // _DEBUG // JDBC connection to a data source class TDBJDBC; @@ -109,8 +112,15 @@ class JDBConn : public BLOCK { public: // Set static variables - static void SetJVM(void) - { LibJvm = NULL; CreateJavaVM = NULL; GetCreatedJavaVMs = NULL; } + static void SetJVM(void) { + LibJvm = NULL; + CreateJavaVM = NULL; + GetCreatedJavaVMs = NULL; +#if defined(_DEBUG) + GetDefaultJavaVMInitArgs = NULL; +#endif // _DEBUG + } // end of SetJVM + static void ResetJVM(void); static bool GetJVM(PGLOBAL g); @@ -120,7 +130,8 @@ class JDBConn : public BLOCK { // JDBC operations protected: - char *Check(void); + bool gmID(PGLOBAL g, jmethodID& mid, const char *name, const char *sig); + bool Check(jint rc = 0); //void ThrowDJX(int rc, PSZ msg/*, HSTMT hstmt = SQL_NULL_HSTMT*/); //void ThrowDJX(PSZ msg); //void Free(void); @@ -134,6 +145,9 @@ class JDBConn : public BLOCK { #endif // !__WIN__ static CRTJVM CreateJavaVM; static GETJVM GetCreatedJavaVMs; +#if defined(_DEBUG) + static GETDEF GetDefaultJavaVMInitArgs; +#endif // _DEBUG PGLOBAL m_G; TDBJDBC *m_Tdb; JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) @@ -150,9 +164,17 @@ class JDBConn : public BLOCK { jmethodID prepid; // The CreatePrepStmt method ID jmethodID xpid; // The ExecutePrep method ID jmethodID pcid; // The ClosePrepStmt method ID + jmethodID errid; // The GetErrmsg method ID + jmethodID chrfldid; // The StringField method ID + jmethodID intfldid; // The IntField method ID + jmethodID dblfldid; // The DoubleField method ID + jmethodID fltfldid; // The FloatField method ID + jmethodID datfldid; // The TimestampField method ID + jmethodID bigfldid; // The BigintField method ID //DWORD m_LoginTimeout; //DWORD m_QueryTimeout; //DWORD m_UpdateOptions; + char *Msg; char m_IDQuoteChar[2]; PSZ m_Driver; PSZ m_Url; diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index 37850ce6358cc..fa5f093bae65c 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -1,7 +1,7 @@ /************* TabJDBC C++ Program Source Code File (.CPP) *************/ /* PROGRAM NAME: TABJDBC */ /* ------------- */ -/* Version 1.0 */ +/* Version 1.1 */ /* */ /* COPYRIGHT: */ /* ---------- */ @@ -34,8 +34,10 @@ /***********************************************************************/ /* Include relevant MariaDB header file. */ /***********************************************************************/ +#define MYSQL_SERVER 1 #include "my_global.h" #include "sql_class.h" +#include "sql_servers.h" #if defined(__WIN__) #include #include @@ -67,7 +69,6 @@ #include "plgdbsem.h" #include "mycat.h" #include "xtable.h" -#include "jdbccat.h" #include "tabjdbc.h" #include "tabmul.h" #include "reldef.h" @@ -101,11 +102,107 @@ JDBCDEF::JDBCDEF(void) Scrollable = Xsrc = false; } // end of JDBCDEF constructor +/***********************************************************************/ +/* Called on table construction. */ +/***********************************************************************/ +bool JDBCDEF::SetParms(PJPARM sjp) +{ + sjp->Url= Url; + sjp->User= Username; + sjp->Pwd= Password; + return true; +} // end of SetParms + +/***********************************************************************/ +/* Parse connection string */ +/* */ +/* SYNOPSIS */ +/* ParseURL() */ +/* Url The connection string to parse */ +/* */ +/* DESCRIPTION */ +/* This is used to set the Url in case a wrapper server as been */ +/* specified. This is rather experimental yet. */ +/* */ +/* RETURN VALUE */ +/* RC_OK Url was a true URL */ +/* RC_NF Url was a server name/table */ +/* RC_FX Error */ +/* */ +/***********************************************************************/ +int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) +{ + if (strncmp(url, "jdbc:", 5)) { + // No "jdbc:" in connection string. Must be a straight + // "server" or "server/table" + // ok, so we do a little parsing, but not completely! + if ((Tabname= strchr(url, '/'))) { + // If there is a single '/' in the connection string, + // this means the user is specifying a table name + *Tabname++= '\0'; + + // there better not be any more '/'s ! + if (strchr(Tabname, '/')) + return RC_FX; + + } else if (b) { + // Otherwise, straight server name, + Tabname = GetStringCatInfo(g, "Name", NULL); + Tabname = GetStringCatInfo(g, "Tabname", Tabname); + } // endelse + + if (trace) + htrc("server: %s Tabname: %s", url, Tabname); + + // Now make the required URL + FOREIGN_SERVER *server, server_buffer; + + // get_server_by_name() clones the server if exists + if (!(server= get_server_by_name(current_thd->mem_root, url, &server_buffer))) { + sprintf(g->Message, "Server %s does not exist!", url); + return RC_FX; + } // endif server + + if (strncmp(server->host, "jdbc:", 5)) { + // Now make the required URL + Url = (PSZ)PlugSubAlloc(g, NULL, 0); + strcat(strcpy(Url, "jdbc:"), server->scheme); + strcat(strcat(Url, "://"), server->host); + + if (server->port) { + char buf[16]; + + sprintf(buf, "%d", server->port); + strcat(strcat(Url, ":"), buf); + } // endif port + + if (server->db) + strcat(strcat(Url, "/"), server->db); + + PlugSubAlloc(g, NULL, strlen(Url) + 1); + } else // host is a URL + Url = PlugDup(g, server->host); + + if (server->username) + Username = PlugDup(g, server->username); + + if (server->password) + Password = PlugDup(g, server->password); + + return RC_NF; + } // endif + + // Url was a JDBC URL, nothing to do + return RC_OK; +} // end of ParseURL + /***********************************************************************/ /* DefineAM: define specific AM block values from JDBC file. */ /***********************************************************************/ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) { + int rc = RC_OK; + Driver = GetStringCatInfo(g, "Driver", NULL); Desc = Url = GetStringCatInfo(g, "Connect", NULL); @@ -120,28 +217,33 @@ bool JDBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff) } // endif Connect - Tabname = GetStringCatInfo(g, "Name", - (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); - Tabname = GetStringCatInfo(g, "Tabname", Tabname); - Tabschema = GetStringCatInfo(g, "Dbname", NULL); - Tabschema = GetStringCatInfo(g, "Schema", Tabschema); - Tabcat = GetStringCatInfo(g, "Qualifier", NULL); - Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); - Tabtype = GetStringCatInfo(g, "Tabtype", NULL); - Username = GetStringCatInfo(g, "User", NULL); - Password = GetStringCatInfo(g, "Password", NULL); + if (Url) + rc = ParseURL(g, Url); + + if (rc == RC_FX) // Error + return true; + else if (rc == RC_OK) { // Url was not a server name + Tabname = GetStringCatInfo(g, "Name", + (Catfunc & (FNC_TABLE | FNC_COL)) ? NULL : Name); + Tabname = GetStringCatInfo(g, "Tabname", Tabname); + Username = GetStringCatInfo(g, "User", NULL); + Password = GetStringCatInfo(g, "Password", NULL); + } // endif rc if ((Srcdef = GetStringCatInfo(g, "Srcdef", NULL))) Read_Only = true; + Tabcat = GetStringCatInfo(g, "Qualifier", NULL); + Tabcat = GetStringCatInfo(g, "Catalog", Tabcat); + Tabschema = GetStringCatInfo(g, "Dbname", NULL); + Tabschema = GetStringCatInfo(g, "Schema", Tabschema); + Tabtype = GetStringCatInfo(g, "Tabtype", NULL); Qrystr = GetStringCatInfo(g, "Query_String", "?"); Sep = GetStringCatInfo(g, "Separator", NULL); Xsrc = GetBoolCatInfo("Execsrc", FALSE); Maxerr = GetIntCatInfo("Maxerr", 0); Maxres = GetIntCatInfo("Maxres", 0); Quoted = GetIntCatInfo("Quoted", 0); -//Options = JDBConn::noJDBCDialog; -//Options = JDBConn::noJDBCDialog | JDBConn::useCursorLib; //Cto= GetIntCatInfo("ConnectTimeout", DEFAULT_LOGIN_TIMEOUT); //Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT); Scrollable = GetBoolCatInfo("Scrollable", false); @@ -274,6 +376,7 @@ TDBJDBC::TDBJDBC(PJDBCDEF tdp) : TDBASE(tdp) Ncol = 0; Nparm = 0; Placed = false; + Prepared = false; Werr = false; Rerr = false; Ops.Fsize = Ops.CheckSize(Rows); diff --git a/storage/connect/tabjdbc.h b/storage/connect/tabjdbc.h index 1624b9036104e..537276a6a7f1b 100644 --- a/storage/connect/tabjdbc.h +++ b/storage/connect/tabjdbc.h @@ -7,6 +7,7 @@ /***********************************************************************/ #include "colblk.h" #include "resource.h" +#include "jdbccat.h" typedef class JDBCDEF *PJDBCDEF; typedef class TDBJDBC *PTDBJDBC; @@ -44,6 +45,8 @@ class DllExport JDBCDEF : public TABDEF { /* Logical table description */ virtual int Indexable(void) { return 2; } virtual bool DefineAM(PGLOBAL g, LPCSTR am, int poff); virtual PTDB GetTable(PGLOBAL g, MODE m); + int ParseURL(PGLOBAL g, char *url, bool b = true); + bool SetParms(PJPARM sjp); protected: // Members From d25fd437c4cb72da48f2b8d5db997c8090a929a3 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Sat, 21 May 2016 14:56:47 +0200 Subject: [PATCH 028/112] - Fix wrong return from ExecuteQuery modified: storage/connect/jdbconn.cpp - Suppress GCC warning modified: storage/connect/tabjdbc.cpp --- storage/connect/jdbconn.cpp | 2 +- storage/connect/tabjdbc.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 286d1141fe804..23bd64bfb88d7 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -1458,7 +1458,7 @@ int JDBConn::ExecuteQuery(char *sql) env->DeleteLocalRef(qry); } // endif xqid - return RC_OK; + return rc; } // end of ExecuteQuery /***********************************************************************/ diff --git a/storage/connect/tabjdbc.cpp b/storage/connect/tabjdbc.cpp index fa5f093bae65c..f507e3df3ea3a 100644 --- a/storage/connect/tabjdbc.cpp +++ b/storage/connect/tabjdbc.cpp @@ -172,7 +172,7 @@ int JDBCDEF::ParseURL(PGLOBAL g, char *url, bool b) if (server->port) { char buf[16]; - sprintf(buf, "%d", server->port); + sprintf(buf, "%ld", server->port); strcat(strcat(Url, ":"), buf); } // endif port From e905abf91b91cd30c63798b9b60e737a822291e0 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 23 May 2016 15:17:43 +0200 Subject: [PATCH 029/112] - New version of the java JdbcInterface modified: storage/connect/JdbcInterface.class modified: storage/connect/JdbcInterface.java - Ignore *.tlog and .res files modified: .gitignore --- .gitignore | 6 + storage/connect/JdbcInterface.class | Bin 15117 -> 15215 bytes storage/connect/JdbcInterface.java | 229 ++++++++++++++++++---------- 3 files changed, 157 insertions(+), 78 deletions(-) diff --git a/.gitignore b/.gitignore index 433d14db7e9d8..279d3f59dc542 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ Docs/INFO_SRC Makefile TAGS Testing/ +tmp/ VERSION.dep configure client/async_example @@ -115,6 +116,8 @@ scripts/wsrep_sst_mysqldump scripts/wsrep_sst_rsync scripts/wsrep_sst_xtrabackup scripts/wsrep_sst_xtrabackup-v2 +scripts/maria_add_gis_sp.sql +scripts/maria_add_gis_sp_bootstrap.sql sql-bench/bench-count-distinct sql-bench/bench-init.pl sql-bench/compare-results @@ -201,6 +204,7 @@ support-files/config.huge.ini support-files/config.medium.ini support-files/config.small.ini support-files/mariadb.pc +support-files/mariadb@.service support-files/my-huge.cnf support-files/my-innodb-heavy-4G.cnf support-files/my-large.cnf @@ -240,6 +244,8 @@ storage/mroonga/mysql-test/mroonga/storage/r/variable_version.result *.exp *.dep *.idb +*.res +*.tlog # Precompiled Headers *.gch diff --git a/storage/connect/JdbcInterface.class b/storage/connect/JdbcInterface.class index 816f575212b2313bbde48e6b8831a0267f8ffef7..8c5ba6439f3fa073f8fa5f892e9ae84a581bc113 100644 GIT binary patch literal 15215 zcmbtb349dQ8UMc7O?HzENk|AGoXZt*5F)6kKoB8-!4Qxj$f3Awh7j27#@!8l`yUbC8(hw35;E4CsSvV7!a%3l>+6RZvgBhA%wmanox38swN z=~K^`$;6A9GN;F4t?_22g8CF;V%UJ#76$g|z(O{{DIqP+TU0-u;o9ty~WeX}t2Fq1MU z(@!Iq{0-576^lh<(q3wkkNk31W>OYq%Uy*@Ib_P+Xp?$TuH20=DUb5y?iiDLQ-R!# zGpUgJKzGZTvcP{*ef`R`0F|PruM1giN=M}jvgial$ww!4vxLU=acID#2?Y6hqV3R+ zt>czx^;{@F0TZx-tzf8zPWBPRR+usmXL^&S&?!vW%~oQz6^{p-A+A1U>?5<_y#wLXb%lKO2(_7mT>y-m6_R|VTr#>2Nf};mQ;b1(TO)F`Y zk6K{WDL$u3k4dX3j2Tu$V-3Mph_mJ1bo-MXr9u&m{#RggF zJf`wAGp8Trr*Fb`Qm6vr`OwP+&`ZFIBM63D;w!DD9J+`$`sm`M;dfu$q;J!AFpu&d z9Wa>&B^^k~)WhAO(2IZ zr_DaP0#VLUfkR}{m2?#h3h11GIv?Yd1=WcmZV_AlAwq9ia#iJl-JAnUUjwLtP&5*1 zkHxG=XuZAgR+F~L0>$nHAkrk6pMC_-uC-PK5$XdgtVC#KAl|YeiTehVZj|9BhR=}B zM)V0oKQ`%Rx&<9^SBC`ny7C2n`U&LFV6E*wpCp0~la8a~ee_eNz(Ees5KYX8wnv(r zz~`eo04*i5)9alsNohf(RA@X+EJ5!I;Q?W*4uLZsibca=oo9?#2r0v5w#tioERBF| z#4)~DQ;Lx^x|TP;I?>%@|Fo76=QLdR`7=Q_Ga$~n9*q)XBsfRUJM zN%lZonF~3hdd zvqr5R^rlIFp+9M^H3dc>f-}-*K9J3CX_W}m+NKA>=ToNO^w|>ryGifT+u9eLK1>Bh zT?Lub1MA6|zRn7@CoIv0=;%X}{wZ$O%hK&RSa?W! zV26?pYg^**d?^|I^cfbN7L0_fa9FYqc+h2_IPHH-`a%Y0h7^IH{)?C-O9*95ReJ%* zJcsttM?Tu`4p>fb@`EwzogCC{`j6n@>@n$I)a2(3*VHyR)U)CbANd)RWSIz-0z zHn|`f{Dc5;J{)b9^jdF4niDI9rjN-*Lep1I(imE4wFbMB6r0>nNQyLxn!YCY z-EbC5sOclXn{iqyU9Q0?OG4X;z*LR>f9ln2%BjGAgZTqRf8RNkr}ec z-6r3|_iA&q%Qjg<_1!Oh&`{bnP}iALqtUPxj2w0q<>e2W{E&FLBvX5kEdGczLnK)! zDJ*-I5r;8edz)w}#s1vn$N32abId8@5eghb=tlSpA>6|>{LmKQ(EIq8FfezigL$*0 zXgo@ILaN|BXY#N3c@0k*4~FLu{zeFYdqjAO-p4Px;pusE<)W%&8)NwqMCi~fpuacy z75;;cL{5(iUaq|6bf_VJlp(JjG5e$j`S=a+?}*jufH&xqT7_Ip;!TtP!hh99pFG4p zDEjMW1>|o+jhg>RLCGEh1DpwCQ3o$^VKGgef}$7aB>bMq@AE&j#X18@lBvEu(Gsqn z9%*m2VnKEIn9U#ZzkK{pIE&&^5g==X^#O9+BJ(Q)02; z`g+h$%;8V?GarA7Y?hi_dQARYN*u3jv$OdN{;!X}OcJSJJR1SgUwm;Wdp6BU48QwMWNRKPdyXfIj}hd79xjjVw8? z6nB)Qonx?(V;ZIa%tPDk;HqeBffbWHha)^A*EI4Z%lMGR+O0V&{6=q-d1GW)p=tDS zhP6bTVba&vG>WC3=(S26X12D4TY`~<-zWhmi>$cc7=V=65EXvcLB&3OFp0Z-9gmf0 zl~j?8bSFx#RK=uqjhNK8`&l>+gH%xrKRsxoNj(Nn#_;UMXnQP#sG-i)yPcMf5hc=4 zY~Vb2pW(+Jj?VE*a#XIaI4DZ#J$3x(rYb#GR?BXb=s?lg!ZHp5Y2m3hl8K573Yb&;2yCqG0&_ zG_r#4r&01#EQzbvu@-wz#00>jdjlmf|Q9trx;Vj(eVZlB)?Jof#2Y#7(9yQ z0<2D$&4(3xQvfRsb*?Cp8=)L!5^%f=F;hUTF)GKR^pAJ>xp* z%uZS=j44iY&|PpA9?`Xj#wmhj+n@{8>kPII8VtJK)V%N@s#c-$rk1G8z?^mX?Ig@O zMN^k10Y!yc`pzsk7eAGmseu)k1zl*`O>vk<2lbMs-Lzh8ML`>poaP&t22G3o^$ zTPX&mwTmuff^7}jN+lK2(A)Em-kyJU(IyX?D?6yK-TJ<(Rj)8ExxyuSg~~2Mq1s75 zD7YGHfCdfMss^_}hbBi|=Zw1EMKo|Loh?HLcF|1+>4jz|huoTWNC%CckWo>R@c`Xs zjQ4iX;N(;OetFDu9`}v+7I}BTa)$A<{5;*RuCLK{b$uW2ezg7GNtLj(N<3A;i^k9} z8cXHyma*`MDe#DyG@h2xiL` z$b(ULqs@!iv*3gGPzL7CrhDl=+Gu&{Z$=Q+)z;^`l;z4Q{U$AuNk;QIe9+b zH*UvWKH^1E2crZh@*Ke89v`uf&OxLATeHBHM2&~(5u2^^ZMKSFja36ichRFB z>Yyym#@!$ygrHmpx(+>Ka#lY&{HWK-n8ETSg>PDU5elYnJ_I>QAHuiHh$ z86f!u?MaITPV&@IV7UZXF2(GZ0n6qiVtGc1?2uTVrRNTX z^9KDXtz^o&=+8$bnY(~y7kIrJlDW@?CcR|-N^c!bGJm7D(@F-u^v+R8W;d{OK{5|Q zGLN{hq?gQl^#0)_^AEbp#_}Y{q!g^m-#1CjW)F>!OBa2>GzlSVcExB3S-3UzZT|jA z10-Z+14l7JmRyH9eqVuSqQ@}hGeyLUQZ*jJm=z}%CPSlL1rf9;xug!RF{0o1R%C1Sh6`gEIJvV9(mFbyH zfGA|I9x$qlv0-x!@Vkk8AcB~^5Tew-+aZ+cbSkb3DM~S1H_=UW3$D5Xxd_4~dJ|l~ zg%NL~ihc*<{*LVTE{x(mi2Os$@GsOO|3>}sG3NS&>gZFH&!3^z{Q|T8m(HfWs8IG} z{sV-47(R1ge1PD^_XC-Jv9TiNc_@%BMjS65gsfmTE_9~G7|a#JqKs-@y8$F{@S8FcZG3>070nsB)ES9kGn zDcHv1ery+)Dhb$yjLm-?{4!~VstDup;Qu5l;0aX8lV}{{b1j}sb$kj++NmgIr@Q!^ z@9;U_E*!nL}}1)x}jVo<|;%XQwbwTo>URld~MI$78#UZzsU@ER@Lgl+Cj#j~l3n=g~-R zq)B`RP2&Y9dF0)P zC44+CZ>_ioWO8h>u*T$GrS{EA?FecT|76oz$j4zzgdO;qg*-mBu|rg=?BWv*nmlM5 z4T8+@GzrS?Aw3l#Cpwdz>`ZnFCL4&YoZh(|u6{2?RlWhjlk2w~*O`ja0bdY8h)tBm z7M1c!xXvm%o>#+s!Ze4Y*!8s0TDIDz-C?f6z{4PC-(5uG+Df$9jf*%9bw zo`&cmj(WLrBm=v$87jee=sY_XdFVT!kp!bnEkGH20bnnc@d0Gnbk#ogV|G=*C6KgK z1u^6rExGC9GPWC?mENQzkw7gcJCdx^J5}vukYgdA=BVdzrG-I@Xep#A*JekW6XYO@ z&xbTGgehK(uNXGcaQ-$`@g_Qszl(k2rPwoGh5&Rq_J>zsf4CXpq1vy{jm>nZPr>Ex}&y~t2b52>b{e2GK;Rh(R#Wob9F z)RFRD2%pLVmd47z1VW=L)780CDect`;heTE$deDc{|AK*->9nDOLRr zkK}tFs_had^7of=ho2!IKSw3}D}1y4JPqMr(@=g9JcXy& zp*slw&>33*NjMp(0ri#3fG!Rhv_se5o+J`ET~20RjpP*|c@;_Wk5q^Qpnm*15WT68 z1oWJanGNI>%ApHwOxlgHH=Sn#YDWCkfUdFuNqIc>DawOG6>@ciT{L|{?* zKZ1Oq@pS^982Sl4@eLoajdDeRqr14xAPKqxHx5~9AMb5!6Rj4~Xq3lEz`Bb02!KBZ z;7?7Gwg?N$U~<6@GU&px1tu!r&3FSI@V5d zsdj33orHHvly7*bz{sE>Mkb9$;eC?frx|!nbh?30YKj=(}PFdv`TpCb+`_2%V{z3nXQ87?5sQf9ED$n7eT*;e`rhpFE;vG zk!*MAk8?@?YB&0A1~uTYBfF}TuSZDC+Nq5yOU{c6v9p@wsA3pQo{S2xQVCW@gOw_< zGKMA@)l_2~LsN}o6+61@t#u5k)-j}7+ij|;7vF;X=|RSIZv%#rPZYy9?4=z1PVpXq z>q~_u2eRrsR`~r1&cwB~9i_H9-2C2Q&|R9vTq%0eY3l^Acp_Ll2`o+kixZ)(Nzm5G zUqf4-q^;eF+Tbgp-{nSspFwwO^f`AP0{t|guLb()KtBWMX9E4HK!4iTKyM_`Kft@c z8u~6b`iGC~DRY2+F3_J2^z(qe5$NXw{lc$--tm-2QG$G>IQ5tt{gX$IQ%it;DbSw< z^k)P8GN3;P=tKV(dOJ?>Q%UJRjdJ8G;eXbR|JO&x-wgaKfxiX#R{{TO;12_T^lRaN zA&LKY{L)v$|FRqZt4GEk2Y$RFGTMQE4e+l8{&m2A-q*tadJ_MioIJPNj1d0v8v6iwnWUML>TsjW;&ZM8o~& zsKyDeHBNY~vBT^5Zb4P7sIcCZ?cPD1rmTps2BCcHu*EZZH@~}^KbYVhSmN#CkC}G! zf5vBc#%Fd=TZy+Qvy1l|^q9dDe3gSXdbq^bX?QvfU!!`GvxgF2mw`_UcN@L1p(r%+ zu|<=ng5=9wO({)9QhsL@8vQybv(V_D?0}paH)e8CW>LnE4_r}{u>-ig>I(v0%v?f- zaVcdRmr=2C1r0JbQ>F0(6f;*-$hd~SVO&d_(0-+Hol>=W1B$(!KC1+WIDS`eKxvDi z584du66A>8gX8({8-t9&SgjcUm(}NJ%fR{STJ@?Y6NlMLjUhym*O-LI4p$Ff<8BAS&Qv*(|WQ*^Rp!9#-3G zwOVaUZLw8rwNjND z7mF~JwkE=%SZ631m1n!ro8A}&M?+fsiL^059vUMP4lBUaL5uPzU+%_RzE2<5nJ#~BWu?fS!u0xq?6J3hQ^lF zbu9&S6dmoO8U3`{u`LBzTQrl70rW&KG+}EqnwYj6W7C)+66$XB(XkLl#vIJV3wxun zu1L~PvzaPd;=z7!=LEZw(an+Mya3IjMu9ySv)2yhuC7xk=38_;EnvzI_4GvI(Abn* zq=QD=EI_uiXrV=msENs+P8j}R6t#7OhJd!2PV^D1xJ)DJkJX|U;nde7@MCd5eTvBf zxO8$`a9u1BJ}W?Nw9H5C{Uxa-ZP9W%31g$F#oayWZQ7hx`>BH|ur3%)VUFI&xB#u9 zlYJ!Slo9BnSSXdU=oC5?!`CO0?V)a1SM^88K#ywl(;8UlsuivC{B#;BO`v|r&!u8Z9t(&$`JhUN_w5W@)TG56`I^)4iZ8=sSEX~0!w#Wwr1mR+X zthAA-F2~HdNBL7SgBb zJRhBlfZ?jZC9>!<^jTOFxN~FEN{rLy(;}9AzBtDPh+?(Qs#)&sxPYH71gpVtA|CEd zCL{6iHhbYOSah*0P@cU2MCy?F>5K5prpWpbqGoV?Bpu!uOhwOe_`b}dFUfEV!<(hE z1APMMD;901uc9NB)giI6rLNOYUxOUlBU}2mP(KX`w0j=Rw3Rdl>Ynh5WPHGKiX7tl{m*cj?1u4|c>8q z&YHtz4a15c)9_hsp&p$$eY6i6TcmwW(tL+54RWT8)#9FySoA1823hu)n!t4^rs;N*SQ=k!Y-{eo$fYfgh!vglXzB+Laq z<0L7LLekJs0L!2NGi&5Ygwa#}&Z6Jb)5we%f^N{F=(2>RjfrH2y2DWa$)e}!4@iQt zfDnMb!$4RV-GG$lPQTO)c+sN2(O-~tFrYON-vIihX8z__B9tL-Hsr5b^bdN)%&!SR zzaD?hW{svqFX|w7jV3eb-xj?|uN%~c0wcQc2k$BYl9kbJiRIlrW+0+##+2MXn7K&! zU5oxpZ=0y&_F*aj&8i~Z9#~o7;;oTzZ#p8nkQqL-=%6@fQN*;b>ghss$Md3CBBiOs z@<7STVh;_2mxQGU#wis}Q#6GbD|N1)^ReinP&^!o#ZYJkfx*9 z8TD)6gjg)7K|tz-OOOUbTRTIsUSN`N-BQS-d5n*%5QSXR9hed=9xGBCCLuPobx|VL z+Z|7}#I@_n_;D7G7XnE$LVyB4me?SLOlu^*A-z#(CR$uAG$Ra6M|fkTJJg?~#^PEb z8E#1Q^!+L7EpEt~#Bh=!fi1vC152cs(L9R7<_LZU^>mAmVpPSFIb8bFbA*q<9)Bb) zSw(`Y)J9SHOw=Tds(Va!)OSgoDg~s+@@yX;mmO0EQCU1kM_mM; zK3n>YbPT65<0^|g`D8>FNXO-03@E1}{fu&bh@lf-4sHykf_`2Db3z>^##fuF!(=vW z&5@r^hfA9l!Km2?YKUiA9Fi@aW%H`(u>;JZokOq#?=H_k4W@d-VU#NCdt)&mEwb4# zlJYY`{m2X-y*dhJvlB&}msmtdtOsS=g!s$c}4s=i_hmppkE)2cNtz}-p^ZnA&-KEf6PMOI*47FQ#Tu?!e1<%_A9 z4vV)*@ZN9n1N=jy2dB!C?5;Z>l+GU?BJiRN3+Q6*u!}UyA`e@T8YmF0g^5Hg5{e&o6&*32viRo`F(fP7gJkhvqFHi40cw+oJ39i?3xMl7D)AZgzO2aX72@y|IAW{ zgFR^+$ev61q7eS=BiYmRK7KiyJu`2yTy(i@^H}#0B6R6BqyMn@HU6iGL~f4`URg=W z?a)JBmmzO_WG2fD^6{I%?~2v!fJH2U_VnQuc1-2D>N=FOIBVj!Eq;gJH74W^aQE1~ z>1b@);&^X&BpK4@)d7Bw5BT_fSg&4I6Cl{f%y~9a*a!R}!ZwbZkm9D=rZH$5TLilO zgk&EIDGmuXWagG_a$!fvj2u%&ORH-U6Zmf6pI3RFp9KEnPTEtnU z8g8i(attDdDVe%Z6|0e!su0G9psg*mDUs}qBqbr?Y*bZRYP6&SAJR>4WZ8PZ8iN{c zstgNSYMeVP8h3|D-vmodlp>;NlRnSx?ukW1@w8t}0>V=xDZi>k?rKkn9JWIBK6AQ^ zyAl&PwaB%!ku^*w>a0vPYHR@UbVUCndt`E52E(BSOf+}U;Q1IH=t%S?!*FkX{NL}$ zd#Wgx#u0eLixnUKaKevYx%cZUPWSZ{XZ!k!lYM=~xxT*QR3F!gm;rAI@H-q&GfCl& zD8Jr&4~@73cZw?T8^D$D9v}~6M&ZsfR8&c$@gy^hv}d>oltMeD{vN8T_uNfm>-laP zCqEP9r&@k$Ecj;0*qH8}@YJ%3QsZ^R*nC5-7^5g+?t(LjGnYkMBFt`Q3dkKRV80tyR%4>yM z`sS6Mj-Q77%)olgf-W@eqcb79T~s7Z`)IugQUjRiOcTX4Xd1Vd&XTEO86?u$NAO|@ zzUnHfsF#MJp4WzYUhku{2hG*HXoTJRkE~X+!VG7Ht!9PlK01eKFMY1`^H>8kXt+o> zWJ_+GGwKp|)TLQOqpzZ0%Fxk$^kqe6p$DBIm**U^i>{lKcPD*atLqyesmR+)SGq90 zv%I_LJfWCg`faFY7oFnFcb!dqy-V!$++_EBZ&1(o?Veiz)ZmikZkv-=k@v{K@8`*4 zC3-PwzB7N8cer;q9B@3}#rNOL`fg z>G8CHCeVp+!ey}PPO7Ci)zf*@Ko`Qocfp45ffe72@js;*^fNk|Uc(9fe`z*-Kyz5$ za!sQ7JO#Ug#dx1}Dz0m3A%|%ZpHGYVBD{9mPA&WmTFQ6f9a0}H<6qNqaCj0wM=SWR zw2EJ%PI&9dY80KKX3}cah#U4Y!clXdf_?Wcy zflEw;yZhjO9z^{Px*u&`tXf46&<`mOYi^_;(SwwSnG4bOWBBDyAemWIdH^CTt{QV( zX+h1T(qks}`sk{Vk9Hm)3%~Ev%7YMGo{!i^4>2+uu6Iia`YAnZe4L)ZnqJH`*)va@ zbVDEQSI|JsE*jMiy-$Ig!Z!#9%De= z4T?BIZUTDhfu2%YDl>rs>pD`w-Q&;{@&_m+7AcG_(6~JqTcB}!H13h)If%tQ8dsY} zwX+q-f6B$xTD|F(>b|;A3t+M+?)??F2MYs2RC2% zNN%3h#&k$-o})h;ikm+k5jU5Do6Eq>m%z>TBjDzR!^!5)^cS0(3m{;zg$k{yU?2U} z3r!Wx@xuNpyfDB+>FVp?X9o=J3Z%I!v-qiSbyeZ&s)C-Sm%vX6oKalJt4+z)l~~Tp z^h!?YOzfk-ACYvf0XN@|2&*@{zb3nlum6Qy>W!nxe@%_1iZT- zotv}x$t|6?=>HBUo&V6=Ii&-?dgq9wa~rtX1L@oj>HHvzo7~cQkKR9=bPmvGZEhX~ znG|wIm3%N)%x6E<%B7D!V4Ay&D%)T~lVL&%55>+y$%k_*C5QzOV#*Q3hx2dElBc`^diG+0n3J{)D+oCnEA{1E4McKA{l5zscLw9O5d z@KsI<0U{H-r-Let{JG>nv-Tc0RG{OWg@+m1aeX{u0IgrISdM;3)eD@JGzL?LDvG;wfbpWyM1G&gKqpa!l}tKSnA>T)(!G;{B1ry&fS9q&z#5bh1@aR(Q+}Yx z3La&Q6fe${&Ws7qyvmy~`V9O@R+Laa4u4be*NDFp@wW;RpU}sZOsFM}HxEJmFvC1d z&=1w-0ozHCjWiE+`oYcHs6M1dSVs}pu;<7IjZraxrHNcfQ`w@UxR@Gw2&%lHbRw7H z1EFE4+J@69T#k=yDrr5B#`h^>vy41pi;hsI7zb9Mn5DdYeavhc59p~>_- zg{K;^&@-TwimDS8l{Q>UF4|tD!kU0xk-Jan<7s(-QD+FNr5}_>%icpgzM+q2DD?TAob-oT{zBCAi%_>W(Q00TPpwX* z4g4uB2UB}SU5!UwIc%`y;Kj#QCm;cMVAg&u5mPV>A@2uR0`>HeE#e!H%0eunPXTxx z6fdgZp;eFlau5+jHehAkgbh*ywoPT+>~5YQrfR78L`CzfuEwTc_J)iv*#_H<-n$;} zPS);Dwj7gex9d0VAg0v<1 zZ$>IH(pxF6W4lu*w_!=5fNB=G(mVyyM4NFo$g+%AyDIvq3PRDTv=$PTYt)sf2}ox_ zqH&mH4~^inX#yu{3a4o%_u~7(ZTJZA9O~jvQHPS)jkfV|}kc!3?vd*G_(NLN^r z;4;RrB-Kb=WgjOM?RLs-kHd=`2|ER#;pJiQ@(5Drqg2L^fuF}|G(V+z37T15a~p$z zAkJOpI=7T!*qE-cS=!87Y?gM|EXfw9;Sm}Fk(BXP)TeSFi6*djj-uNg_MkSIwn|s6 zraB#ii3x{UKK>1r@NdD~(=>*kp|Sis=;paB25VggYwdDqEXGP{U}BD+JY`G4q0|NE zA$A#|?YB*S$zTqTsl1wsMTnF8__K;63=6{-K%V0KCQV)hL!YvjFE(e0TGM6NY)x^c zYpR{+0pJAy_%i_fh01XvH=h57@cI&Jzn5`>_o@bB4sMpXK$h4*2Vuo9*Z^g! zodWWf6$_?vV7d&E#9(^C#zDP%N7)hvWhYN3_c(=h+Wmm4|%$;p=#? zZ$(i~(9?=4mG9DBoO-jy{{qg}f%6Sm(wk7yTQr&f4`1^Chno3qoJPKbAonhO_Wdlp zYh1i*T)b=e8wh-gR@f>u$rd(N`We6l+A9$c4cfavCP8a9_^fkm>}qXeHI>&=i8KS_ zHA;40@&I*SHxNr1ivMXY7Grb=$)|`)6iiYnnueEZ)0LNwRlY3VXS=-5c6py|>uP#G z-is)&tfa+9Z3}E0-09ljokxb?yV(eCvaL{#J8i2Qgg_MnfdvFbKu`<>Lx7+J2+IB^ z1ce%b4m{#R-$U><8hFv>zj?3*W@c&N=4}3NQ`A0XKLy}BcOYCA-0GNC!L69J4EwOT zt~$o+!+OY z88zYDwvVNg=bp>A%ILuef}`VgoM;v>}9ec6bAq-c)=vUraMIap&80kRq( zCjn#)K-NNIbhdv(vKh5UxO7>L~C(1NmuE+cedF*4w ztlwnw|GOiIS$N;#Q!U_sDfs^s_-_UOZQy_T|HQu?v-mkj1ApW{eLMuuXCwIQksw$J z1gn6c69`TQf>VItR3KRUi4eTxAb5rU{_zmJnvLLJM}pu?AP51$Iv@xGK^G82fMDY% zLhx?~!COeE+KR9{$dky3-TVA~{GWaN-#OmV72ZBR$h1#+XXSZjbPc66jh7O)piEWo zqI|?CrvtC0J1)%U;rYY!u0Obac;0UC6IRMo2ntX59v zAxYm0sf@yTfxPp|#|zfAYO 0) ? rs.getString(n) : rs.getString(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -525,7 +544,7 @@ public int IntField(int n, String name) { } else try { return (n > 0) ? rs.getInt(n) : rs.getInt(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0; @@ -538,7 +557,7 @@ public long BigintField(int n, String name) { BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); return bigDecimal != null ? bigDecimal.longValue() : 0; } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0; @@ -550,7 +569,7 @@ public double DoubleField(int n, String name) { } else try { return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0.; @@ -562,7 +581,7 @@ public float FloatField(int n, String name) { } else try { return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return 0; @@ -574,7 +593,7 @@ public boolean BooleanField(int n, String name) { } else try { return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return false; @@ -586,7 +605,7 @@ public Date DateField(int n, String name) { } else try { return (n > 0) ? rs.getDate(n) : rs.getDate(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -598,7 +617,7 @@ public Time TimeField(int n, String name) { } else try { return (n > 0) ? rs.getTime(n) : rs.getTime(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; @@ -610,12 +629,24 @@ public Timestamp TimestampField(int n, String name) { } else try { return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); } catch (SQLException se) { - System.out.println(se); + SetErrmsg(se); } //end try/catch return null; } // end of TimestampField + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + public int GetDrivers(String[] s, int mxs) { int n = 0; List drivers = Collections.list(DriverManager.getDrivers()); @@ -635,5 +666,47 @@ public int GetDrivers(String[] s, int mxs) { return size; } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ } // end of class JdbcInterface From 18487ed60ecf8d8e8416a45e1f45c3a012662ce7 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 24 May 2016 14:18:55 +0200 Subject: [PATCH 030/112] MDEV-10108 Fix errors in installations by domain user --- win/packaging/extra.wxs.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in index 8ee2909511b96..6e5d1bf0fb286 100644 --- a/win/packaging/extra.wxs.in +++ b/win/packaging/extra.wxs.in @@ -66,6 +66,7 @@ + @@ -463,7 +464,7 @@ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@' Name='DATADIR' Value='[DATADIR]' Type='string' KeyPath='yes'/> - + @@ -851,6 +852,7 @@ + Date: Tue, 24 May 2016 14:20:53 +0200 Subject: [PATCH 031/112] MDEV-10071 Block installation on XP/Windows 2003 Server(they are no more supported) --- win/packaging/extra.wxs.in | 3 +++ 1 file changed, 3 insertions(+) diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in index 6e5d1bf0fb286..b716bbf7e88d6 100644 --- a/win/packaging/extra.wxs.in +++ b/win/packaging/extra.wxs.in @@ -899,6 +899,9 @@ + + + = 600)]]> From 535160b170b3d0b0489193b9863042578cddd826 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 24 May 2016 16:57:03 +0200 Subject: [PATCH 032/112] MDEV-10117 - update HeidiSQL to current version --- win/packaging/heidisql.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake index 5b0cd07cea478..e2636eb4af8c6 100644 --- a/win/packaging/heidisql.cmake +++ b/win/packaging/heidisql.cmake @@ -1,4 +1,4 @@ -SET(HEIDISQL_BASE_NAME "HeidiSQL_9.1_Portable") +SET(HEIDISQL_BASE_NAME "HeidiSQL_9.3_Portable") SET(HEIDISQL_ZIP "${HEIDISQL_BASE_NAME}.zip") SET(HEIDISQL_URL "http://www.heidisql.com/downloads/releases/${HEIDISQL_ZIP}") SET(HEIDISQL_DOWNLOAD_DIR ${THIRD_PARTY_DOWNLOAD_LOCATION}/${HEIDISQL_BASE_NAME}) From 221adbc6feadb51d44b2a16a666f3c78d297c705 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 24 May 2016 17:01:08 +0200 Subject: [PATCH 033/112] Fix warnings on Windows, compiler option -ggdb3 option is nonexistent --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c1ce1c5597898..9ab8870ffb866 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -254,8 +254,10 @@ IF (ENABLE_GCOV AND NOT WIN32 AND NOT APPLE) ENDIF() MY_CHECK_C_COMPILER_FLAG(-ggdb3 HAVE_GGDB3) -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb3") -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") +IF(HAVE_GGDB3) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb3") + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb3") +ENDIF() OPTION(ENABLED_LOCAL_INFILE "If we should should enable LOAD DATA LOCAL by default" ${IF_WIN}) From ff832e0d16f83fa0db64ca76ba756f8e714c7e43 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 24 May 2016 17:37:23 +0200 Subject: [PATCH 034/112] Restore COMPONENT Embedded for Windows embedded libs. --- libmysqld/CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index ee5c88756866c..bd7631c1d6bb2 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -108,8 +108,12 @@ ADD_DEPENDENCIES(sql_embedded GenError GenServerSource) # On Unix, it is libmysqld.a IF(WIN32) SET(MYSQLSERVER_OUTPUT_NAME mysqlserver) + SET(COMPONENT_MYSQLSERVER "Embedded") + SET(COMPONENT_LIBMYSQLD "Embedded") ELSE() SET(MYSQLSERVER_OUTPUT_NAME mysqld) + SET(COMPONENT_MYSQLSERVER "Development") + SET(COMPONENT_LIBMYSQLD "Server") ENDIF() @@ -134,9 +138,9 @@ FOREACH(LIB ${LIBS}) ENDFOREACH() MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS} - OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development) + OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER}) -INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development) +INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT ${COMPONENT_MYSQLSERVER}) # Visual Studio users need debug static library IF(MSVC) @@ -163,7 +167,7 @@ ENDFOREACH() IF(NOT DISABLE_SHARED) MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API} - COMPONENT Server) + COMPONENT ${COMPONENT_LIBMYSQLD}) IF(UNIX) # Name the shared library, handle versioning (provides same api as client # library hence the same version) From b6e826bac2e4d32985e4b90d782dd52d504f0f5b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 24 May 2016 23:15:00 +0200 Subject: [PATCH 035/112] MDEV-10118 : do not suggest upgrade from MySQL 5.7 to MariaDB 10.x in the installer. Do not lauch upgrade wizard after installation --- sql/winservice.c | 13 ++++++++++--- win/packaging/ca/CustomAction.cpp | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/sql/winservice.c b/sql/winservice.c index 1cf9f8d782389..74e9e56acc68f 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -81,8 +81,10 @@ void normalize_path(char *path, size_t size) and services. We do not want to mess up with these installations. We will just ignore such services, pretending it is not MySQL. - ´@return - TRUE, if this service should be excluded from UI lists etc (OEM install) + We also exclude MySQL5.7+ since we cannot upgrade it (and it is not an upgrade anyway) + + @return + TRUE, if this service should be excluded from UI lists etc FALSE otherwise. */ BOOL exclude_service(mysqld_service_properties *props) @@ -104,7 +106,12 @@ BOOL exclude_service(mysqld_service_properties *props) if (strstr(buf, exclude_patterns[i])) return TRUE; } - + if ((props->version_major == 0) || + (props->version_major > 5 && props->version_major < 10) || + (props->version_major == 5 && props->version_minor > 6)) + { + return TRUE; + } return FALSE; } diff --git a/win/packaging/ca/CustomAction.cpp b/win/packaging/ca/CustomAction.cpp index 3cb8520b65d4a..56df4ae791e1e 100644 --- a/win/packaging/ca/CustomAction.cpp +++ b/win/packaging/ca/CustomAction.cpp @@ -886,11 +886,11 @@ extern "C" UINT __stdcall CheckServiceUpgrades(MSIHANDLE hInstall) (QUERY_SERVICE_CONFIGW*)(void *)config_buffer; DWORD needed; BOOL ok= QueryServiceConfigW(service, config,sizeof(config_buffer), - &needed); + &needed) && (config->dwStartType != SERVICE_DISABLED); CloseServiceHandle(service); if (ok) { - mysqld_service_properties props; + mysqld_service_properties props; if (get_mysql_service_properties(config->lpBinaryPathName, &props)) continue; /* From a8422fa241db4779c68df219e48130b11ececc99 Mon Sep 17 00:00:00 2001 From: iangilfillan Date: Fri, 27 May 2016 18:25:14 +0200 Subject: [PATCH 036/112] Update sponsors --- mysql-test/r/contributors.result | 2 +- sql/contributors.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/contributors.result b/mysql-test/r/contributors.result index 1820c0a5f0687..1e01ca819901d 100644 --- a/mysql-test/r/contributors.result +++ b/mysql-test/r/contributors.result @@ -7,7 +7,7 @@ Visma http://visma.com Member of the MariaDB Foundation Nexedi http://www.nexedi.com Member of the MariaDB Foundation Acronis http://www.acronis.com Member of the MariaDB Foundation Verkkokauppa.com Finland Sponsor of the MariaDB Foundation -Webyog Bangalore Sponsor of the MariaDB Foundation +Virtuozzo https://virtuozzo.com/ Sponsor of the MariaDB Foundation Google USA Sponsoring encryption, parallel replication and GTID Facebook USA Sponsoring non-blocking API, LIMIT ROWS EXAMINED etc Ronald Bradford Brisbane, Australia EFF contribution for UC2006 Auction diff --git a/sql/contributors.h b/sql/contributors.h index 04f8b74aa658f..76674d654e5cf 100644 --- a/sql/contributors.h +++ b/sql/contributors.h @@ -46,7 +46,7 @@ struct show_table_contributors_st show_table_contributors[]= { /* Smaller sponsors, newer per year */ {"Verkkokauppa.com", "Finland", "Sponsor of the MariaDB Foundation"}, - {"Webyog", "Bangalore", "Sponsor of the MariaDB Foundation"}, + {"Virtuozzo", "https://virtuozzo.com/", "Sponsor of the MariaDB Foundation"}, /* Sponsors of important features */ {"Google", "USA", "Sponsoring encryption, parallel replication and GTID"}, From f9d453e893c04a648736d46f0059db98b56ab14c Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Sat, 28 May 2016 13:11:09 +0300 Subject: [PATCH 037/112] Follow-up for commit 38b89a61c3ace83b32c079489922a0cae5106b56 Altering a comment or a default field's value needs "NO_LOCK", not EXCLUSIVE - storage_engine test result updated --- .../storage_engine/alter_table_online.rdiff | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff b/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff index 3a7fef61d3b39..5ae99e2035c6e 100644 --- a/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff +++ b/storage/myisam/mysql-test/storage_engine/alter_table_online.rdiff @@ -1,41 +1,5 @@ --- suite/storage_engine/alter_table_online.result 2013-11-08 20:01:16.000000000 +0400 +++ suite/storage_engine/alter_table_online.reject 2013-11-08 20:02:03.000000000 +0400 -@@ -2,8 +2,35 @@ - CREATE TABLE t1 (a , b , c ) ENGINE= ; - INSERT INTO t1 (a,b,c) VALUES (1,100,'a'),(2,200,'b'),(3,300,'c'); - ALTER ONLINE TABLE t1 MODIFY b DEFAULT 5; -+ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE. -+# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed) -+# ------------ UNEXPECTED RESULT ------------ -+# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED. -+# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors. -+# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def. -+# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped. -+# Also, this problem may cause a chain effect (more errors of different kinds in the test). -+# ------------------------------------------- - ALTER ONLINE TABLE t1 CHANGE b new_name ; -+ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE. -+# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed) -+# ------------ UNEXPECTED RESULT ------------ -+# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED. -+# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors. -+# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def. -+# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped. -+# Also, this problem may cause a chain effect (more errors of different kinds in the test). -+# ------------------------------------------- - ALTER ONLINE TABLE t1 COMMENT 'new comment'; -+ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE. -+# ERROR: Statement ended with errno 1845, errname ER_ALTER_OPERATION_NOT_SUPPORTED (expected to succeed) -+# ------------ UNEXPECTED RESULT ------------ -+# The statement|command finished with ER_ALTER_OPERATION_NOT_SUPPORTED. -+# Functionality or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors. -+# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def. -+# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped. -+# Also, this problem may cause a chain effect (more errors of different kinds in the test). -+# ------------------------------------------- - ALTER ONLINE TABLE t1 RENAME TO t2; - ERROR 0A000: LOCK=NONE/SHARED is not supported for this operation. Try LOCK=EXCLUSIVE. - DROP TABLE IF EXISTS t2; @@ -23,12 +50,30 @@ CREATE TABLE t1 (a , b , c ) ENGINE= ; INSERT INTO t1 (a,b,c) VALUES (1,100,'a'),(2,200,'b'),(3,300,'c'); From a9ac3506d21135373f9ced92c79c0d9d7c7dca13 Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Thu, 2 Jun 2016 23:36:19 +0200 Subject: [PATCH 038/112] git90.msg + git91.msg --- storage/connect/.gitattributes | 25 + storage/connect/.gitignore | 264 ++++++++ storage/connect/CMakeLists.txt | 6 +- storage/connect/JdbcApacheInterface.class | Bin 0 -> 15357 bytes storage/connect/JdbcApacheInterface.java | 709 +++++++++++++++++++++ storage/connect/JdbcDSInterface.class | Bin 0 -> 16175 bytes storage/connect/JdbcDSInterface.java | 743 ++++++++++++++++++++++ storage/connect/ha_connect.cc | 30 +- storage/connect/jdbconn.cpp | 23 +- storage/connect/jdbconn.h | 4 +- storage/connect/jsonudf.cpp | 297 +++++++-- storage/connect/myconn.cpp | 8 +- storage/connect/plugutil.c | 4 +- 13 files changed, 2039 insertions(+), 74 deletions(-) create mode 100644 storage/connect/.gitattributes create mode 100644 storage/connect/.gitignore create mode 100644 storage/connect/JdbcApacheInterface.class create mode 100644 storage/connect/JdbcApacheInterface.java create mode 100644 storage/connect/JdbcDSInterface.class create mode 100644 storage/connect/JdbcDSInterface.java diff --git a/storage/connect/.gitattributes b/storage/connect/.gitattributes new file mode 100644 index 0000000000000..d21fdf8f212f6 --- /dev/null +++ b/storage/connect/.gitattributes @@ -0,0 +1,25 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.cc text +*.cpp text +*.h text +*.test text + +# Declare files that will always have LF line endings on checkout. +*.result text eol=lf +mysql-test/connect/std_data/*.txt text eol=lf +mysql-test/connect/std_data/*.dat text eol=lf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary + +*.c diff=cpp +*.h diff=cpp +*.cc diff=cpp +*.ic diff=cpp +*.cpp diff=cpp diff --git a/storage/connect/.gitignore b/storage/connect/.gitignore new file mode 100644 index 0000000000000..e2fa07ee1435a --- /dev/null +++ b/storage/connect/.gitignore @@ -0,0 +1,264 @@ +# Edited by Olivier Bertrand +*-t +*.a +*.ctest +*.o +*.reject +*.so +*.so.* +*.spec +*~ +*.bak +*.log +*.cmake +*.tgz +*.msg +.*.swp +*.ninja +.ninja_* +.gdb_history + +CMakeFiles/ +connect.dir/ +connect.dir-Copie/ +Debug/ +MinSizeRel/ +Release/ +RelWithDebInfo/ + +# C and C++ + +# Compiled Object files +*.slo +*.lo +*.o +*.ko +*.obj +*.elf +*.exp +*.manifest +*.dep +*.idb +*.res + +# Precompiled Headers +*.gch +*.pch + +# Compiled Static libraries +*.lib +*.a +*.la +*.lai +*.lo + +# Compiled Dynamic libraries +*.so +*.so.* +*.dylib +*.dll + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +*.ncb +*.sln + +*.vcproj +*.vcproj.* +*.vcproj.*.* +*.vcproj.*.*.* +*.vcxproj +*.vcxproj.* +*.vcxproj.*.* +*.vcxproj.*.*.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Roslyn cache directories +*.ide/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# If using the old MSBuild-Integrated Package Restore, uncomment this: +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +# sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index ff0060dcc61f4..254d074612a1f 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -37,7 +37,7 @@ user_connect.h valblk.h value.h xindex.h xobject.h xtable.h) # # Definitions that are shared for all OSes # -add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS ) +add_definitions( -DMARIADB -DFORCE_INIT_OF_VARS -Dconnect_EXPORTS) add_definitions( -DHUGE_SUPPORT -DZIP_SUPPORT -DPIVOT_SUPPORT ) @@ -240,7 +240,7 @@ OPTION(CONNECT_WITH_JDBC "Compile CONNECT storage engine with JDBC support" ON) IF(CONNECT_WITH_JDBC) # TODO: detect Java SDK and the presence of JDBC connectors - # TODO: Find how to compile and install the JdbcInterface.java class + # TODO: Find how to compile and install the java wrapper class # Find required libraries and include directories FIND_PACKAGE(Java) @@ -251,6 +251,8 @@ IF(CONNECT_WITH_JDBC) # SET(JDBC_LIBRARY ${JAVA_JVM_LIBRARY}) SET(CONNECT_SOURCES ${CONNECT_SOURCES} JdbcInterface.java JdbcInterface.class + JdbcDSInterface.java JdbcDSInterface.class + JdbcApacheInterface.java JdbcApacheInterface.class jdbconn.cpp tabjdbc.cpp jdbconn.h tabjdbc.h jdbccat.h) add_definitions(-DJDBC_SUPPORT) ELSE() diff --git a/storage/connect/JdbcApacheInterface.class b/storage/connect/JdbcApacheInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..acd4258e3d3ace51a01fe79b5c0dfeb65d6ac87c GIT binary patch literal 15357 zcmbtb349dQ8UMc7O?I;xLP!W9;aaW`5+KScghNOGgCQINl*8I(GbF2<-MG6^@YbqT z>n$Ewt@XrO@HV*Ktrn}cwc1)++uFmct!>rXs#S#kzxQS*v#=ai{AFk69pC$Z_xIk6 zFYJEwNg|qT)cMF@DqYmJK0LQ86z;H^Vks-JAr!WJ!5|MiFNZr$w*lEZ;f{+!dCrktl*y+ zjz(gU)NCeC_1IOw-4Jhsj)p*aO7z+51!yo0Gbu=wP|{2_v4EIHm{djsnEEzHVpdCc z=Xxu#LRb(5#>1iLs!$>#&#Ezi2~|R43|6aNqZUndL?Ftt<{b7?A0Q76lU2r@t~DR#1qnfm`OhJ%iTni3Me3VlT9ilQ|_jk)Q5`X?g*3mQnB34FsUDv$lXkn zN~u4rZoNp`N@WahV6{uK^EZaAE@fR~R~67)YVgs#EE{g!l!Wb=)JXFo$9Oj^%eKx) zylyGXHU;Hap-%9!keYmSR7Sc=aSnNt7SYj6fp#mk*h(ft?GRx9>ai{)wvGd|n3njc zB||2A6_b|IGA3V_EF2Y2aWi9+7`sZaw3@U+mh`9Mx*d|hqBi(!bg-5_u>SCgi$h(u zb{R@5SlBBy4|Kv*C|a~#l4)S|+I<;lS~IrEPhW$5tX$q442NQ|cq+Kw3dXvlQL&G& zn>3r2iM6daDNJxA4}=1{adV<0N4;A(BnNzzI+CL$+W ziH2w>nQRGlTGAagsZ+Z1(Y-POoEF7R>XN2HX-Zm&m_0OMQZm!N6eLcGC)$LYZj(-? zQ@~A^*vJt%xN*s9|NP0)n@l>DPJ>P$nBMruRGu-Iy#iw)ok3^$=**1GWOti%Hk|`L zl9o_ZgB6Cn2v>+`xJ(KajL zr;C{SIfH|#O2e=k1|=yHS+q^Mg06&Pf(a+st^frU+nR*P z)h2DGYoNkVSC58E?n0h~52iAf}H{tF?!it4A*;uv+nH!kKyA_ymESCm# zQ-+*iztNAUd3Mr%U|=_I(pN`*Uu$;hc9388VTNw*0N6Eqe` zXDj-o;|`PVq^;0Zv{$Ihnw_{L2{D9( z4AaTs%jn%8=ny)Z5WJG%L_8YR(cegfA^YwGQk>C-={1L*oG>E^lI2>OO3f}ru%bt^ zBd{tCn2H*dAxgGxRT(~K>}wL+ebS_-=xI>t(y86CI%Jgn>s65Css%jgkN{~(s7IZ$ z6ar%!P~EhTIn<9`RY*Ug=X|u2snQYnK15CWF+GF$3T0}N5O4$n#u6x|H2pmBGDYsE zCjE?F)WHee7>mGf3Y?C3qIYzw9{mfGen~GQ?hA1lfbp#w{=7&#(uPBRk)H4ylU}FS zkW?_CIUYl4#)~xl1<`n@clZK5{0}Dmk$$h~s{t5~kjxA88jbO8R0GZ$je62MCcR5< zX^!;>%z%$_Ba{SARzy0jWGd9zr6(f7^csiLXG`}VCjFD%)2`t3ffN{Z)qGA5a$Dj2 zjaIljWr-d{KOdR&Z}GA|mTq6!)rJU%=Z0uJsYYo7L)o-O#(!$kf2AzS3rjyNQLl|e|pkUjLN zkG<~b=R`U`=flG@ld{Nv3ODBhlm0^=`?=6X+6IThSv=xXKNrEk=0>AI#ROzuxDd5S zXyd9-v>QB0Bxx$-67KKgQl<*Wc=t{YCYOoq`XfSNc0)Yc-5E6Ea!~>T8>z;ug@P!iz{6^O09>=xdz#pYng_+^RY9; z*-jMlc&_vD1b0-~XOzi@i9CuN78>H+5-z;4u%R_8c%lbc-$(Z%*w`-V=U)F5hZy7MSuh!$AXy6wnF6RmGElaBD^aYLB;wpCLhbI zG2X_i#-r}d#eXhI`*|%AY%i<9WOq1>ea8kA;o!874MR)HZ1_TuPP;m{2SHT%Em zalh=Oiu9bILKMV4&%fLXwY69qC4#YK@&@`?Ob!i@tSVJ>a9Jb$CzyO9cVJRzeG*cU zpzBG*Q8fp&(~0|vnsZcc^?vR`c*E{6p@U{8w)}|OA@PlbiTw()Vz2Etht^v#dYi5; z6?3O-L_H6mV)90M9OE}cVr?3W&^^`U)3_J{b9_ou^2QWUn|h;_L@`ue-Ly6rZlQCw z$>#_iF(zc8a3m>l86Dp+`8?_HqoWnuX-gU}F!`I(7>FcWpfFuJa@^!*MK4_v{nzo=x1YD?#5F2}LjVzK0H<|n$zFCVNa~dJEPLV)`V;r5K zR7YKJmx`yi$gEpYj_%)6_MR5t+xbo(-+`Q_lHOkZCU51tAf6~nBRf~3E)PV(_v;NKCe(*bYL2OkQ#n8dp#|Aqgmjb3-{6aDR@ z5;-btl_`IhDgQWlWU}YM3KwRMe3HUvj$#FsZ-77Kk9_A$s_`g2>6x=9sY5>woR3Bw0P5z8OM_!CZl1P&i zY*XEbjI9#YJ~xpFZED7N=;RCD5L%gt4$^n;1`A;hjIK@pAkSAvzG)Qdc!o0K1Pua9O~o@2L>7L6=~I2A25oI z5}(m8L!`IMG)m<(QruUPe4$Zbl$pi=!P^&Yi$f>G6RWI*lq#a(*LxANkMUK=QH!aw z`G7vBUl5Ul^ntRS-0M}!1knKv#}SSPFI@`ohx2j#lAMRDD^A1J6=&hs1V>Ed64jTF(4Zk0c293mTJ_Zqp zjZ!UyC%hxDCr-u~>CLb4?x4}Va{`Ls0Dvx6^GrR8sY>|JgG-Utx*@j@mAxbF*@^vAn_3dm$A zo<>3@)p##39>6DpV_{{0Ue<;L05nUnYRHM14K8ehtE_p5YPV3I2k6M!9$L^t%{90# z2TZ}>QDQ2=>V(yNGz=>Z$J!%Y>r^`HRMJXX1^UORncNRc;5^)3@Hl(H{(8ZHUJ$G0 zSZXwusse-6c+D}^wN!s+ss3~<)a)!(gxl40w7pc5y;L78RoASAUV9%vX{{G2!y5+; zig4>(^!wQK^FVuzqR+IJ)@icFxex;klv_Mgy|vznGxB&wensAMR9I7T+zvY4*!BPo zugL46(9>kCo{|3?O??bEJE$GQ@@qX4d#IxV6ME=GJm%pshHE~qC#i`Q`8||6rbaFs z#Xtc5@HCyy1Vb6Jg(_4-KhNL$dEQUcxgIo6*-8WK*7sbkTEG(_;K%5K)g>41po`Ho zB~6zw_0Ux%*Y?o$y5ZZZp@+UBYFBnJJTvQNXVxvQL4&u@Qkgn9O}87Qr_9MrxhvvFm}5P&loiyb z=?MeWr){P3mYVSpxG`%hnfkVP_pHGpY6BuHg{b8^)Dd-+io-Fqo`m)UB1{rqp2CQ3 z`25LW{S+F5H#Z`J$zTJEW<-FyA1GHbFhbZhFx#hC!y8caNKEi3)&`Pi4;J_MNZ3Qt z16zy0mN@bc=^2}?Gi|oYU|!P(jZ4$B9@117G_4AxP$7VCjKmc0e+Zy0GMy%=`4gfh6-GU1?)^7Q>|C8(;jz zOfj3CG)gXM!p>wSLe}D%aT2m{YwFwL-7^PCpb7v-IYO3PM>u|8gJ+^AK=LWvJ&nE} zAS?Wkh9HoPpl6Xgegv!9i30F>7Z2lYOY=|->`Ux)pdGBFHqgP!P?lCE!K$1Lm|AwE z!s`f|qZe$B>O3|>V>Cmb;E+a&I;3aKi5E;2W^NTv1t47sp5!{(;Yk;JKLy#B(DQRt zrZ1!a6_jmmVl#1{-_x0Q4rGnk&flZ1B^k|u_hO2r@r#q=~AGS=oj zPs9Xr)$XCFhh*rKH2bp1dTV;ve++sK-)llZPdGfyX4VA1n`$2nf}p(+VXW zE)bnc|` z9!2IJu-t37{sBiL(fZV{e~{e!`@*REa^IU$v!r^m;U5OePak%1hF%&39qxmc(&n^(% z1oflF;fWa*VU_tx)9s#F+yXXsQjzxwO1F&n;GtDBvp=rKr+Jc#=h6G+*(nVa*JapU z9p`X8728?7WCzy^@s(v01$YtlMeSV1OK3DNrJ1~(8n~5~@(NnR$I$V7EGqN0N(#Cd zZFi*5?nuG1rQk(1KMggy2WFkG8ouyBzG0uP^19_;vP9Q)<&Z8~fcMH_#Bs4B>1Zl)aDiRE(^5h|PD1Ed;T_ z*qv#D2ddz!P>Y`m;mP%U$93kRcpyF=LJUy>ucs=u;5zLzg*#wA5n94gTE(6Cj4O`s zue$JR_9T1)m7ohaN#EiWzD+vC6@jjB1bPJ&BK5gJmnlaw=x{_oNiiNe&5lJLeE#FE z^MjPP3jlUeHSa;5%~kJ1#dcl5a<(DaCV_0DC5OW_$BmB5ZBmj+pq9+uvy_+U&8K!U z$gz}{IqEr3abaKsxDL{kYr7-O8FJ#pr$L%$!W7TOSEA?8NIsXw^LaFx&!^RV5jKn$ zBLIC1o5M?}gD*vRxs1B_N|$pcY$+OO7nfuheI|N$*b;Lk<#n!@ZEuTU_4aNLD%B>r zeP5GY;aHK&Bt?|4$yKr=oSs{VVxADziy=Pp4%9tehas<_7J9fr6Jt$+`?u=-b>$r=g1-FNZ1mpK#6@w zdTmTw$miWkUe7ih@kw33%_I5VhkCmL#-PitN`w*O=Wqt{JXP=u_?GBJ8pc1N;rw%j zSs!GMw3Sp=8|LK4(89Wxt@a4HU6YGcxFjNR#S8&D_5Y(Q7pfU1C`{yFLk zhbrYb>eHfd>B02;WUj~|-yAr<%Xm3$5zYS>b&`^FCg8B>UmiJun zsvLM#cF{A;E&((=KY2=_L6!eg+->9Q0X{MGY5U?EIp_u|5&@1&^T`HD&=t6wAWQA; z{frw#tEDs!<#7hEu43K?;12-!Lje94mGeh5g8zd6`Z21yPiPW2KK1x?1y4|d#D&5P+}M~%<#}S!%NeRJX&Dn(=x+H%MCvr zV-&i$UF~qY+TnIJUx<`~+AWJ)*i*@wP#9{Hi;-zGuMfENH9ccbmneH0J?J}B4De#` zml@c2$qBe9@5*dWN+H!chZALBMqlz7#o(kLl^P{fhj&_s8U1OBq2F>GTu+B(A@4(Z zrN#Jv2GZi7Qg3c{>4j`(0x&@DBn0p};>3_=CVd(k1x= z*;zLJLWN(27eRjmvXhp+?2W}+8bz|%(x2#({*7+*-!-UZ{7wpt@8R1J5(~C#qbk_0 zT&JF9I;t1}lP6;gSg8gpW5G%dSgEC%#yFZ~jHh|VVTv7H_BJ|()aV#eqwO|z)Q7*v zcOz`g%2Lb-@`+;j_FYtn-y^+yz>HLAawMxxWQAYJuA1LN)Yf)4zxNw-uV%4G&c<_T zYcg1z0v4x&#c5#i2xx0Mv^Dc9Xv>qawTE!{@}zjs3%wnu_@^1^zl735OaBn@zwE~U z>cR210lx+O8-TwZ_&b0<0{qdhg#XtW{IBzGza0MGx$*z;;P|_MA1{fF1n?(;KLz~V zz`yY;;eRuO|7|DF$!V8FTD6JJjsl;~c6t-0zNNIpKAd6JBT8;dN?OP!%gGZFXh5fAafU3w$jG z%2y4WJ+mL-4<6x6pZZ&`lY@EP>9Q82?-JLEhMSNM92 z!XBe@!d--4Cf$;`~Bh z$>rlXdz~>Bna+nyNBF)0-y*5;<1k)MG?x>y)DZF^OX0W%nF?PC;e2wByra)*^BD!$ bLu1Gu*v`IP9_fOXKEv*wkxh|mjS2q)X94nE literal 0 HcmV?d00001 diff --git a/storage/connect/JdbcApacheInterface.java b/storage/connect/JdbcApacheInterface.java new file mode 100644 index 0000000000000..fdbc5bff2033b --- /dev/null +++ b/storage/connect/JdbcApacheInterface.java @@ -0,0 +1,709 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import org.apache.commons.dbcp2.BasicDataSource; + +public class JdbcApacheInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + static Hashtable pool = new Hashtable(); + + // === Constructors/finalize ========================================= + public JdbcApacheInterface() { + this(true); + } // end of default constructor + + public JdbcApacheInterface(boolean b) { + DEBUG = b; + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + BasicDataSource ds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif url + + try { + if ((ds = pool.get(url)) == null) { + ds = new BasicDataSource(); + ds.setDriverClassName(parms[0]); + ds.setUrl(url); + ds.setUsername(parms[2]); + ds.setPassword(parms[3]); + pool.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcApacheInterface diff --git a/storage/connect/JdbcDSInterface.class b/storage/connect/JdbcDSInterface.class new file mode 100644 index 0000000000000000000000000000000000000000..d56c04bd81f1253bc788d6c8556fa9a65c326d15 GIT binary patch literal 16175 zcmbtb34B!5)j#LXBr};jl8}Wkge5?LkPsrfBy5tf1VdN?D7X&E5Q51}n3)K;(Nc%ow7vjCSt9TmTD$%Q#2A`DlqTj>)R@8&;TN>(TKcm zUftfzRMhjjHk1gh4#mR@!-sQ28fTeD2>wnRLbOUh!%%qv1m-%%PjJdU+%_OltBTx8*5P}S#o!hMSUns?#5e` zO*wKm(W1VTD|eGE%AgS^>raWyZsp1LHR4Rc*trk&+6G@}$U+NOuoQ+N4 z4sAK3S7gvEn(d=gQtY#FQyg|-Q4Q5XbkWWpeYHj_7sDhIkbF4Q4#wxwd>_Gt4Hm5x zhrC5~w16ql5>6}($K#<#7*-hsy40YHFW@tBKUXRo~&>d5zsM~forv9a8 z9LYf4s?l|RItzBQd})1gQz#ONCW=>wizA(FZDMcdSTvm$i*7;|t)?bO6+(fjxH&OV zq1r7UyU9l)InnmvRvw@hYW30DRQ2hoVbMAfMP?#eAKeg+)gT!7sSS?az6qWp10xni zsRPnNa7lz(BjCQs4X9>qDApKW-x-d;okk$jxb%290kKHaMvFFST}o3t9Fw*SExJhBGSRj;6pwF+#+vW*kU(Gm-TcOTurR4D*^+BC`Wl~L_yp|;A! zAdXP(CVagRzMd|X9}vD?2;V9u6p43sbVOr`aC32Uto3{m(^R_6qOa38U^pG(jwieI zWLt^LERSwVnbb_TTl6jZHq0M3*po(>3X{Gmk+kPUbtc_O-|^91N%u^BZP9n>Zm3Ut zxk)w%ux?VqbV@D~g7;YTJ-QdMw+WFX5q5HncvxMX?F2HD^QPKIy8!a=>^Qr#wXHcE z^V59@%}(dy#HNmL@$}*V?WFr9G%wDi2kBuSJp>7B5-GGTdW5>*L}0?nS<65{XO21{ zvd^M!dKBgp>gWhZB+Zp3QMz)G4W`;p-v?{OaIB`zSPTxd$;R@8ka?1+!mYq$40CDF zG$qLi_NOiSfnY3jV}zEH69~wqe)QtX zlJpHp-;(;{#}errHH42FBBXDJ^c|-Oe~uV{ktz=E3ytEnMY@CsgMXDNt42GB6l0CL zfa^8=)rn92!=kt89hh;4soWfIKzVU=dy{E2hAvrQE*&eZLF%$_!l-3<#rq!cY zWYWLr10TK5G{7;0BZyk`Z+Z_Y7Di@BLh-FoJf=XcZ0M(n_iJ*WSoA4P47b%6McqcCd8!!`ZpT*vs+tGIXD9r=mDH&aXNdDW-y>W8bRgFNS8u? zZd)|e(|xY#o@ueg8HT>@fc|UnH`mNj8|_4)=*&@T2IX3u$2o>$(*q+AI~a9U4rW@` z+8&N4LhT)9AR=FnB{=VlbUA4804_8x>bwIfFzPDloj0(p%sCswO`VCb=mGlSAr=>l z_xA~#_T?STh`e~NX^X~nFJoXRmRCvt5{pOB061xryoV*~y08OU#!Os;4yfTsWMB0@21j%P|C71a4BzIJHBCwywBl08% zrI1JJWS(U4P#)&zDK64BIIN4{5nSSD6v}~9+S-aW6Oeu8Jd~rMjVnTJo#06#TwNy5 z;8{MN$rN;q_wb};@hKv^d_+!+u8FpFwnyT15nVaT_!^6Ali^u9Am_D3TN*;`;rei- zC9zie%(Zx)^yz1aG&Zdbw}(=@)LFbhx)hi$ntW=HdW#pjh!`Y2U0@OL(g2vWF^bFf z5_=8TOD#CbGW5rEPXDuei4{ls{E4)<(zv74YEk(LR1JI@(_nX<;B;|Tiq1-^Qx@GnMwn ze{W*;^W{jTJ**bTJDZxY?p%XK7Axc2`mkVnj69!b@;l@;_G>s*c%!kSzSMw$g)ao{U(cV<{L36v^ox{NW}HTq8lJ3 z<8k73T^LDr4*N0YzVLLWmQ@{3}uMzSp z`A&=PqPNh0O>3mtU=h0CwfJtH27x&aWhi+g8mLXZHXKKVR#;khMsK)<&Q6PW2^}#e zq@bqOxCCXqxX2Tim~(+|-k0?srQh>g8>jVzD>KeqTee%^>4V`?F^c9B5PF^=|7Vr^y5 zD;-RKBBOqa4W^@e%HhKT{1U(7N9tBprP??(i z@Uc>Om|EwU{MHJ;zqa@{{9B`kWPKzVS-+;bD*@dW@FtR4n>YRi}v!jEq+J5Tr#OWNG5+*nxVlA)DvNwO35*d zSBi1zsulab#UJp$5zIkT8W9Q{LrCfPp>+HR%b=rMfYaZ{pTNM}bq?reNZojX@T9AT z_nE~9`H+DpjfcZac2uaG4=U`79|xZ9?^9kkJVQ52F1k>*F^)ct2%Y`{RQWBHp#mln zId63Ea^*GWg&tzbkUq!FK0SkcDjWPeVs&1?8_aHuMlNV_EtRM8jnSJ|M?`;n|3>ze zm&%Yr8Pfmwk;xthE1U<5(R)Wo|AoEPe<*tcYM>hIQ-hG;9o%Nn!cYXewJ}Q#QK%Kf zq#a_xWG$fgo##Y4+rzPt-b@atVXDNZhJzbTPIo|BX*0(ZaZ8O*Bas)|TIB#>tZk}C zkg-*w+fRwbLYwN*zdBQusxqHKIg!;vT;5o!TxuY%>>~tJg{t(avB^$4S}#Osv(!my z9MW!kE0&OYg;^&ACtx#H<@?kmlre`%0HRk@EOoM)Y63@18@48~i;?7Blh%#Z0adN0 z`xHXIA=2~8QZr-=R@_&Te5RVHW?4$FBeK!9FtjcjTM>>)Uc`Q^sW@CM8(R}??`UfcMG}710ESnF<9@XmDYPLf z>~91MKC`EYyBt$RX-R7#BYByZDA9T`BG?|&6}0TWr0T>zqtPKp8=*do z37CVKxvg@*lCRg2jYyQ{h-|D-prHhmI7rLDAI?zlOLAtSuQ)N$SDcsVD^5%F6=x;- zijxw3#W{(-;*%Ld!(7VY`6R%e;GO-~+nP5c~$vPUw+F1F0By zmgxmt!|)^&2HO;N0H^e=DceiK%RG9r$T-zR@-wBZ zNP0g;Q&;Y#YCQK$KN&|rgekl@0LlPc**N~m2U|fL{tU+5a2)-Vf~^X$HJ*mh6o8x! zaK#wa&%m*v0vJt$0HJx=p|e3Z;YmObD0`SjY^OdC(#-NMn$tz6mf^Yt@CAzplnJwX z@mm7%j{u5Mz)8)cN=4^T?8lcnuyJTyBICvKBm^!wQK z(?ENrrq8sB&M;&l1FzVd%Jxk5mV3unrEyg{SNXUK8w(j+6$qw1OPOW4XYQr5)hJF5BjD3D?z^=a~ZBO=JKFl#w5&`E0SZjV$9W58Nm!`|7tKpkNFy| zGUl3KhK!kI#$1~mb3Mk~2!_B?7i|j$^q8A)l`%I512V=c%e@7h<{YqD4W@U|_S4FO z>D}~A#uj>c8AMRtO?Svc#h~pJ)D3+-@AUP&*G)S-Xs+Br{p{AaU9HAK#=}A$qn#^r zckiV=XsYa{2bj8OZ|-AV^tfqwN;h=TGh(;ekcTEm{m>b;-_>d0c3Lb$2X@nQip-Fi z$ss@Ob;u4HT$NcC%-l;aRjSixQMI|Dsnoo8OhIJj1!>%ClT; zKl%{xOnP!)`;8pbybMm`-rH3J?!6P|nug3W9Mm>PK7Jeo}NaaV^E(FHimJQapm zPffItTBw0G;3V`*w3x1-C3Gz+rvw@W6-RfsesKo`Fxi07HHWM*Ihiev8he z_vkG8h|Z=%bPjvyTu!GDBlU4M&J~NOl}F-SZ~{en3QhwT;*{@PN^lEx@@6`pZ^ZRx z+Q{FeP5c;L$WPM6{2XoOmvJihE^Xlt=raCR&@bVda`!95DG$=EMX#aFOMc~}Uqe=Dl&QS*8~QEYXQ6uh9sM35qAwq$ z*TI>e^7+5?NBR>YWg&k|Z_uA905k#m3;h)%749T5W$MT@m9h>&yqP{?AHB(p-xeP= z`)Iw7Hv4F+565rxUz#&v!UTWjxZFu4oj!U6N78dM0rzhZqRAW20jPw<(VpqrgkkD` zSFq`EJE*XstOC}ero&6jZO*~z19$1Dl!K7=3hr_c#gle1QYX3V(0U`aO2>a{}3taZ&6TosWuZ~~I~5wPqBug^j<&%3bnYBAi0vyLU1Y|iObGNs+z_k<+#BG9}9USEb}e(plk zt7JHz3yvk3eq7kAWX5!J{}YhRuYlz>Naoj&%E&UMPq@1qE z`D~h)&3-D8OE=@wr)daT3(Lkx$il5iBs9lSok_x+QJO3C+sI-9(BB>`;IYvCv-E` zzYgeyza>d=angzyJM3#&S03j}e(3wv?Ihuv&K{Oq)w@<6RDIE3PqSnt_t5X`E{CA z5ODHN7Ct3p9RkZemh10#Dl)B4|N4vM-k%MHSMxMu$ly)sY#H@TFS-{L&cPpqp+o#o zT*uuFU#hH8-)u9qz$RU_pvy0DV4xh{HdRC#wS(?vK|OGAYR4~>SIqj3#OILF2Fh@NG20>eU*eeLYTG1t zA8C@C9V>E~q=*tW`DIxWPUu~TVxADK2P`X z3$&A8bOnIjj=k=7>~*Id0B&`x^sW>u?Mq&<(vPSE?w^$R6^^{cEF}cQj+FP6y~*2% z`zma48maa;`B$CppU26KS&mFGOA{%72BEzQq5T5rUxSnXhEC?+!X$qWlYAW}`3IQf zA7PSzf=Rvs)BCGSP)U;nUyh(UY{yO-r-zcpY1|o+QUoQt5J@pzlk{G?6rO{v6YM+d z^eC|pN$*<5j)Bj+gS?(y^=0K!*zfX4zW1Tv4my#4fRsD@ck=Pu6y$gCiPk?+a=lAK z`F)Mq>?04il{>&zq}g;0khgFazLYYd`v!zFv(6Ae5>5shK>g%W)Xm!z?J^~}Cy7Kh z>64k)Ao&PLK0%WFl=85j(;pFR0C+0~wPHilF|&bui+1Qd8=<*e)8l&gF63z3z5y>>jFM8^eIQ;8(wr9Wr+Z> zbi6~61YLpq9mvwSdtY^%Xf+R;s(BoGPGUs*oyFe;TWTG(nj| z4O6X6aez;;fddZ0tRK+Erc^N* zRi(5?!vWC=9j9Bb;1FKj_legrq&8 zZh$?FD7u|;0A38fTh;|~03pizekvz+mAze}pV#yyXoWeXU3~Rr=#y(tp;C{sl!175gbr(Zw$!BxdY3MwPK! zyG}K#sidzDgUOSs11k%_%Bf(b9;_^+X{v#yt3@Cb5E1kwM=jsCBS?lb5!?>h?m z)j;0_^vysY2KqHX-vadOz5sfaME@2N;^#vD4>$UM9^X?UKpzGA4xnET^f9211O545 z0KMZW@A3cH=ua?C{mYI1KgW+#7XbZ*Kz|X?Ukvn@0R3j5*IPLDHs9xtQ~YsK`kx~4 z8|j}Q{sS)jQVO{`1E@(W#NP9FaE9QI{&% zVe;OXZq-jer)ps$4%w3-)?~Ze!Ns@0#kax59YB94O;&eNwQ?UGO?SfUbSJz{x5Mk? zl%OhF$gA(kb}FdsuRE}^ma}}KZJrtXRM9>)w8}d$=QN=>Ztl@HqD;h?WeP3}@vjrvK>p@Y6|h5r_?PtC@HB2Uf15>1-sB~O=4Piew; zKHDiHPc7U*>3M2V@&)A7xFwwn(hJh=ICO16+AiSoVsBA)_^|V=?j@ymQb6rOxpp57 zQhTUeJ&0oF5o%IhbdlPNW7YfUdiAJQ^-{x^BcyFOSJMZov`sD18&HaF(1P<|hyE(H zR5fC@Lb@0qN&OO18G!u@Ig?Are)gGanOY8&$o{2#=VJPwhW^sBl#rzckq=o)ADH@7 pDKp^&c@_Cn+I*;7P$9pGZ3orME2OzMCCz<`)jcEifMvDv{{f(}{-gi^ literal 0 HcmV?d00001 diff --git a/storage/connect/JdbcDSInterface.java b/storage/connect/JdbcDSInterface.java new file mode 100644 index 0000000000000..09f545bfb7401 --- /dev/null +++ b/storage/connect/JdbcDSInterface.java @@ -0,0 +1,743 @@ +import java.math.*; +import java.sql.*; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; + +import javax.sql.DataSource; + +import org.mariadb.jdbc.MariaDbDataSource; +import org.postgresql.jdbc2.optional.PoolingDataSource; +import com.mysql.cj.jdbc.MysqlDataSource; +import oracle.jdbc.pool.OracleDataSource; + +public class JdbcDSInterface { + boolean DEBUG = false; + String Errmsg = "No error"; + Connection conn = null; + DatabaseMetaData dbmd = null; + Statement stmt = null; + PreparedStatement pstmt = null; + ResultSet rs = null; + ResultSetMetaData rsmd = null; + Hashtable dst = null; + + // === Constructors/finalize ========================================= + public JdbcDSInterface() { + this(true); + } // end of default constructor + + public JdbcDSInterface(boolean b) { + DEBUG = b; + dst = new Hashtable(); + } // end of constructor + + private void SetErrmsg(Exception e) { + if (DEBUG) + System.out.println(e.getMessage()); + + Errmsg = e.toString(); + } // end of SetErrmsg + + private void SetErrmsg(String s) { + if (DEBUG) + System.out.println(s); + + Errmsg = s; + } // end of SetErrmsg + + public String GetErrmsg() { + String err = Errmsg; + + Errmsg = "No error"; + return err; + } // end of GetErrmsg + + public int JdbcConnect(String[] parms, int fsize, boolean scrollable) { + int rc = 0; + String url = parms[1]; + DataSource ds = null; + MysqlDataSource mds = null; + MariaDbDataSource ads = null; + OracleDataSource ods = null; + PoolingDataSource pds = null; + + if (url == null) { + SetErrmsg("URL cannot be null"); + return -1; + } // endif driver + + try { + if ((ds = dst.get(url)) == null) { + if (url.toLowerCase().contains("mysql")) { + mds = new MysqlDataSource(); + mds.setURL(url); + mds.setUser(parms[2]); + mds.setPassword(parms[3]); + ds = mds; + } else if (url.toLowerCase().contains("mariadb")) { + ads = new MariaDbDataSource(); + ads.setUrl(url); + ads.setUser(parms[2]); + ads.setPassword(parms[3]); + ds = ads; + } else if (url.toLowerCase().contains("oracle")) { + ods = new OracleDataSource(); + ods.setURL(url); + ods.setUser(parms[2]); + ods.setPassword(parms[3]); + ds = ods; + } else if (url.toLowerCase().contains("postgresql")) { + pds = new PoolingDataSource(); + pds.setUrl(url); + pds.setUser(parms[2]); + pds.setPassword(parms[3]); + ds = pds; + } else { + SetErrmsg("Unsupported driver"); + return -4; + } // endif driver + + dst.put(url, ds); + } // endif ds + + // Get a connection from the data source + conn = ds.getConnection(); + + // Get the data base meta data object + dbmd = conn.getMetaData(); + + // Get a statement from the connection + if (scrollable) + stmt = conn.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY); + else + stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); + + if (DEBUG) + System.out.println("Statement type = " + stmt.getResultSetType() + + " concurrency = " + stmt.getResultSetConcurrency()); + + if (DEBUG) // Get the fetch size of a statement + System.out.println("Default fetch size = " + stmt.getFetchSize()); + + if (fsize != 0) { + // Set the fetch size + stmt.setFetchSize(fsize); + + if (DEBUG) + System.out.println("New fetch size = " + stmt.getFetchSize()); + + } // endif fsize + + } catch (SQLException se) { + SetErrmsg(se); + rc = -2; + } catch( Exception e ) { + SetErrmsg(e); + rc = -3; + } // end try/catch + + return rc; + } // end of JdbcConnect + + public int CreatePrepStmt(String sql) { + int rc = 0; + + try { + pstmt = conn.prepareStatement(sql); + } catch (SQLException se) { + SetErrmsg(se); + rc = -1; + } catch (Exception e) { + SetErrmsg(e); + rc = -2; + } // end try/catch + + return rc; + } // end of CreatePrepStmt + + public void SetStringParm(int i, String s) { + try { + pstmt.setString(i, s); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetStringParm + + public void SetIntParm(int i, int n) { + try { + pstmt.setInt(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetIntParm + + public void SetShortParm(int i, short n) { + try { + pstmt.setShort(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetShortParm + + public void SetBigintParm(int i, long n) { + try { + pstmt.setLong(i, n); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetBigintParm + + public void SetFloatParm(int i, float f) { + try { + pstmt.setFloat(i, f); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetFloatParm + + public void SetDoubleParm(int i, double d) { + try { + pstmt.setDouble(i, d); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetDoubleParm + + public void SetTimestampParm(int i, Timestamp t) { + try { + pstmt.setTimestamp(i, t); + } catch (Exception e) { + SetErrmsg(e); + } // end try/catch + + } // end of SetTimestampParm + + public int ExecutePrep() { + int n = -3; + + if (pstmt != null) try { + n = pstmt.executeUpdate(); + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecutePrep + + public boolean ClosePrepStmt() { + boolean b = false; + + if (pstmt != null) try { + pstmt.close(); + pstmt = null; + } catch (SQLException se) { + SetErrmsg(se); + b = true; + } catch (Exception e) { + SetErrmsg(e); + b = true; + } // end try/catch + + return b; + } // end of ClosePrepStmt + + public int JdbcDisconnect() { + int rc = 0; + + // Cancel pending statement + if (stmt != null) + try { + System.out.println("Cancelling statement"); + stmt.cancel(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 1; + } // nothing more we can do + + // Close the statement and the connection + if (rs != null) + try { + if (DEBUG) + System.out.println("Closing result set"); + + rs.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc = 2; + } // nothing more we can do + + if (stmt != null) + try { + if (DEBUG) + System.out.println("Closing statement"); + + stmt.close(); + } catch(SQLException se) { + SetErrmsg(se); + rc += 4; + } // nothing more we can do + + ClosePrepStmt(); + + if (conn != null) + try { + if (DEBUG) + System.out.println("Closing connection"); + + conn.close(); + } catch (SQLException se) { + SetErrmsg(se); + rc += 8; + } //end try/catch + + if (DEBUG) + System.out.println("All closed"); + + return rc; + } // end of JdbcDisconnect + + public int GetMaxValue(int n) { + int m = 0; + + try { + switch (n) { + case 1: // Max columns in table + m = dbmd.getMaxColumnsInTable(); + break; + case 2: // Max catalog name length + m = dbmd.getMaxCatalogNameLength(); + break; + case 3: // Max schema name length + m = dbmd.getMaxSchemaNameLength(); + break; + case 4: // Max table name length + m = dbmd.getMaxTableNameLength(); + break; + case 5: // Max column name length + m = dbmd.getMaxColumnNameLength(); + break; + } // endswitch n + + } catch(Exception e) { + SetErrmsg(e); + m = -1; + } // end try/catch + + return m; + } // end of GetMaxValue + + public int GetColumns(String[] parms) { + int ncol = 0; + + try { + if (rs != null) rs.close(); + rs = dbmd.getColumns(parms[0], parms[1], parms[2], parms[3]); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int GetTables(String[] parms) { + int ncol = 0; + String[] typ = null; + + if (parms[3] != null) { + typ = new String[1]; + typ[0] = parms[3]; + } // endif parms + + try { + if (rs != null) rs.close(); + rs = dbmd.getTables(parms[0], parms[1], parms[2], typ); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + } // endif rs + + } catch(SQLException se) { + SetErrmsg(se); + } // end try/catch + + return ncol; + } // end of GetColumns + + public int Execute(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing '" + query + "'"); + + try { + boolean b = stmt.execute(query); + + if (b == false) { + n = stmt.getUpdateCount(); + if (rs != null) rs.close(); + } // endif b + + if (DEBUG) + System.out.println("Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of Execute + + public int GetResult() { + int ncol = 0; + + try { + rs = stmt.getResultSet(); + + if (rs != null) { + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + + } // endif rs + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of GetResult + + public int ExecuteQuery(String query) { + int ncol = 0; + + if (DEBUG) + System.out.println("Executing query '" + query + "'"); + + try { + rs = stmt.executeQuery(query); + rsmd = rs.getMetaData(); + ncol = rsmd.getColumnCount(); + + if (DEBUG) { + System.out.println("Query '" + query + "' executed successfully"); + System.out.println("Result set has " + rsmd.getColumnCount() + " column(s)"); + } // endif DEBUG + + } catch (SQLException se) { + SetErrmsg(se); + ncol = -1; + } catch (Exception e) { + SetErrmsg(e); + ncol = -2; + } //end try/catch + + return ncol; + } // end of ExecuteQuery + + public int ExecuteUpdate(String query) { + int n = 0; + + if (DEBUG) + System.out.println("Executing update query '" + query + "'"); + + try { + n = stmt.executeUpdate(query); + + if (DEBUG) + System.out.println("Update Query '" + query + "' executed: n = " + n); + + } catch (SQLException se) { + SetErrmsg(se); + n = -1; + } catch (Exception e) { + SetErrmsg(e); + n = -2; + } //end try/catch + + return n; + } // end of ExecuteUpdate + + public int ReadNext() { + if (rs != null) { + try { + return rs.next() ? 1 : 0; + } catch (SQLException se) { + SetErrmsg(se); + return -1; + } //end try/catch + + } else + return 0; + + } // end of ReadNext + + public boolean Fetch(int row) { + if (rs != null) { + try { + return rs.absolute(row); + } catch (SQLException se) { + SetErrmsg(se); + return false; + } //end try/catch + + } else + return false; + + } // end of Fetch + + public String ColumnName(int n) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnName + + public int ColumnType(int n, String name) { + if (rsmd == null) { + System.out.println("No result metadata"); + } else try { + if (n == 0) + n = rs.findColumn(name); + + return rsmd.getColumnType(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 666; // Not a type + } // end of ColumnType + + public String ColumnDesc(int n, int[] val) { + if (rsmd == null) { + System.out.println("No result metadata"); + return null; + } else try { + val[0] = rsmd.getColumnType(n); + val[1] = rsmd.getPrecision(n); + val[2] = rsmd.getScale(n); + val[3] = rsmd.isNullable(n); + return rsmd.getColumnLabel(n); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ColumnDesc + + public String StringField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getString(n) : rs.getString(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of StringField + + public int IntField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getInt(n) : rs.getInt(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of IntField + + public long BigintField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + BigDecimal bigDecimal = (n > 0) ? rs.getBigDecimal(n) : rs.getBigDecimal(name); + return bigDecimal != null ? bigDecimal.longValue() : 0; + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of BiginttField + + public double DoubleField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDouble(n) : rs.getDouble(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0.; + } // end of DoubleField + + public float FloatField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getFloat(n) : rs.getFloat(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return 0; + } // end of FloatField + + public boolean BooleanField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getBoolean(n) : rs.getBoolean(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return false; + } // end of BooleanField + + public Date DateField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getDate(n) : rs.getDate(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of DateField + + public Time TimeField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTime(n) : rs.getTime(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimeField + + public Timestamp TimestampField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getTimestamp(n) : rs.getTimestamp(name); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of TimestampField + + public String ObjectField(int n, String name) { + if (rs == null) { + System.out.println("No result set"); + } else try { + return (n > 0) ? rs.getObject(n).toString() : rs.getObject(name).toString(); + } catch (SQLException se) { + SetErrmsg(se); + } //end try/catch + + return null; + } // end of ObjectField + + public int GetDrivers(String[] s, int mxs) { + int n = 0; + List drivers = Collections.list(DriverManager.getDrivers()); + int size = Math.min(mxs, drivers.size()); + + for (int i = 0; i < size; i++) { + Driver driver = (Driver)drivers.get(i); + + // Get name of driver + s[n++] = driver.getClass().getName(); + + // Get version info + s[n++] = driver.getMajorVersion() + "." + driver.getMinorVersion(); + s[n++] = driver.jdbcCompliant() ? "Yes" : "No"; + s[n++] = driver.toString(); + } // endfor i + + return size; + } // end of GetDrivers + + /** + * Adds the specified path to the java library path + * from Fahd Shariff blog + * + * @param pathToAdd the path to add + static public int addLibraryPath(String pathToAdd) { + System.out.println("jpath = " + pathToAdd); + + try { + Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); + usrPathsField.setAccessible(true); + + //get array of paths + String[] paths = (String[])usrPathsField.get(null); + + //check if the path to add is already present + for (String path : paths) { + System.out.println("path = " + path); + + if (path.equals(pathToAdd)) + return -5; + + } // endfor path + + //add the new path + String[] newPaths = Arrays.copyOf(paths, paths.length + 1); + newPaths[paths.length] = pathToAdd; + usrPathsField.set(null, newPaths); + System.setProperty("java.library.path", + System.getProperty("java.library.path") + File.pathSeparator + pathToAdd); + Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); + fieldSysPath.setAccessible(true); + fieldSysPath.set(null, null); + } catch (Exception e) { + SetErrmsg(e); + return -1; + } // end try/catch + + return 0; + } // end of addLibraryPath + */ + +} // end of class JdbcDSInterface diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc index a6e52bdee9aaa..45ad4a484e15d 100644 --- a/storage/connect/ha_connect.cc +++ b/storage/connect/ha_connect.cc @@ -195,6 +195,7 @@ extern "C" { #if defined(JDBC_SUPPORT) char *JvmPath; char *ClassPath; + char *Wrapper; #endif // JDBC_SUPPORT #if defined(__WIN__) @@ -1141,7 +1142,7 @@ int GetIntegerTableOption(PGLOBAL g, PTOS options, char *opname, int idef) else if (!stricmp(opname, "Compressed")) opval= (options->compressed); - if (opval == (ulonglong)NO_IVAL) { + if ((ulonglong) opval == (ulonglong)NO_IVAL) { char *pv; if ((pv= GetListOption(g, opname, options->oplist))) @@ -1960,7 +1961,7 @@ int ha_connect::MakeRecord(char *buf) if (trace > 1) htrc("Maps: read=%08X write=%08X vcol=%08X defr=%08X defw=%08X\n", *table->read_set->bitmap, *table->write_set->bitmap, - *table->vcol_set->bitmap, + (table->vcol_set) ? *table->vcol_set->bitmap : 0, *table->def_read_set.bitmap, *table->def_write_set.bitmap); // Avoid asserts in field::store() for columns that are not updated @@ -4806,7 +4807,11 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) DBUG_RETURN(rc); // Get the share info from the .frm file - if (!open_table_def(thd, share)) { + Dummy_error_handler error_handler; + thd->push_internal_handler(&error_handler); + bool got_error= open_table_def(thd, share); + thd->pop_internal_handler(); + if (!got_error) { // Now we can work if ((pos= share->option_struct)) { if (check_privileges(thd, pos, db)) @@ -4819,12 +4824,6 @@ int ha_connect::delete_or_rename_table(const char *name, const char *to) } // endif open_table_def -// This below was done to avoid DBUG_ASSERT in some case that -// we don't know anymore what they were. It was suppressed because -// it did cause assertion in other cases (see MDEV-7935) -// } else // Avoid infamous DBUG_ASSERT -// thd->get_stmt_da()->reset_diagnostics_area(); - free_table_share(share); } else // Temporary file ok= true; @@ -5156,7 +5155,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, char *nsp= NULL, *cls= NULL; #endif // __WIN__ int port= 0, hdr= 0, mxr= 0, mxe= 0, rc= 0; - int cop __attribute__((unused))= 0; + int cop __attribute__((unused))= 0, lrecl= 0; #if defined(ODBC_SUPPORT) POPARM sop= NULL; char *ucnc= NULL; @@ -5620,7 +5619,7 @@ static int connect_assisted_discovery(handlerton *, THD* thd, len= crp->Length; dec= crp->Prec; flg= crp->Flag; - v= crp->Var; + v= (crp->Kdata->IsUnsigned()) ? 'U' : crp->Var; tm= (crp->Kdata->IsNullable()) ? 0 : NOT_NULL_FLAG; if (!len && typ == TYPE_STRING) @@ -6876,6 +6875,12 @@ static MYSQL_SYSVAR_STR(class_path, ClassPath, "Java class path", // check_class_path, update_class_path, NULL, NULL, NULL); + +static MYSQL_SYSVAR_STR(java_wrapper, Wrapper, + PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, + "Java wrapper class", + // check_class_path, update_class_path, + NULL, NULL, "JdbcInterface"); #endif // JDBC_SUPPORT @@ -6899,6 +6904,7 @@ static struct st_mysql_sys_var* connect_system_variables[]= { #if defined(JDBC_SUPPORT) MYSQL_SYSVAR(jvm_path), MYSQL_SYSVAR(class_path), + MYSQL_SYSVAR(java_wrapper), #endif // JDBC_SUPPORT NULL }; @@ -6917,6 +6923,6 @@ maria_declare_plugin(connect) NULL, /* status variables */ connect_system_variables, /* system variables */ "1.04.0006", /* string version */ - MariaDB_PLUGIN_MATURITY_BETA /* maturity */ + MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ } maria_declare_plugin_end; diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 23bd64bfb88d7..7a508cd989b06 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -53,8 +53,9 @@ extern "C" HINSTANCE s_hModule; // Saved module handle #endif // !__WIN__ int GetConvSize(); -extern char *JvmPath; // The connect_jvm_path global variable value -extern char *ClassPath; // The connect_class_path global variable value +extern char *JvmPath; // The connect_jvm_path global variable value +extern char *ClassPath; // The connect_class_path global variable value +extern char *Wrapper; // The connect_java_wrapper global variable value /***********************************************************************/ /* Static JDBConn objects. */ @@ -645,8 +646,8 @@ JDBConn::JDBConn(PGLOBAL g, TDBJDBC *tdbp) m_Tdb = tdbp; jvm = nullptr; // Pointer to the JVM (Java Virtual Machine) env= nullptr; // Pointer to native interface - jdi = nullptr; // Pointer to the JdbcInterface class - job = nullptr; // The JdbcInterface class object + jdi = nullptr; // Pointer to the java wrapper class + job = nullptr; // The java wrapper class object xqid = xuid = xid = grs = readid = fetchid = typid = errid = nullptr; prepid = xpid = pcid = nullptr; chrfldid = intfldid = dblfldid = fltfldid = datfldid = bigfldid = nullptr; @@ -1028,11 +1029,11 @@ int JDBConn::Open(PJPARM sop) printf("JVM Version %d.%d\n", ((ver>>16)&0x0f), (ver&0x0f)); #endif //_DEBUG - // try to find the JdbcInterface class - jdi = env->FindClass("JdbcInterface"); + // try to find the java wrapper class + jdi = env->FindClass(Wrapper); if (jdi == nullptr) { - strcpy(g->Message, "ERROR: class JdbcInterface not found !"); + sprintf(g->Message, "ERROR: class %s not found!", Wrapper); return RC_FX; } // endif jdi @@ -1078,7 +1079,7 @@ int JDBConn::Open(PJPARM sop) jmethodID ctor = env->GetMethodID(jdi, "", "()V"); if (ctor == nullptr) { - strcpy(g->Message, "ERROR: JdbcInterface constructor not found !"); + sprintf(g->Message, "ERROR: %s constructor not found!", Wrapper); return RC_FX; } else job = env->NewObject(jdi, ctor); @@ -1087,7 +1088,7 @@ int JDBConn::Open(PJPARM sop) // we can then search for the method we want to call, // and invoke it for the object: if (job == nullptr) { - strcpy(g->Message, "JdbcInterface class object not constructed !"); + sprintf(g->Message, "%s class object not constructed!", Wrapper); return RC_FX; } // endif job @@ -1328,6 +1329,7 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) case 4: // INTEGER case 5: // SMALLINT case -6: // TINYINT + case -7: // BIT if (!gmID(g, intfldid, "IntField", "(ILjava/lang/String;)I")) val->SetValue((int)env->CallIntMethod(job, intfldid, rank, jn)); else @@ -1393,6 +1395,9 @@ void JDBConn::SetColumnValue(int rank, PSZ name, PVAL val) break; case java.sql.Types.BOOLEAN: System.out.print(jdi.BooleanField(i)); */ + case 0: // NULL + val->SetNull(true); + // passthru default: val->Reset(); } // endswitch Type diff --git a/storage/connect/jdbconn.h b/storage/connect/jdbconn.h index a7744ba6ba1ac..db8a11716e5d0 100644 --- a/storage/connect/jdbconn.h +++ b/storage/connect/jdbconn.h @@ -152,8 +152,8 @@ class JDBConn : public BLOCK { TDBJDBC *m_Tdb; JavaVM *jvm; // Pointer to the JVM (Java Virtual Machine) JNIEnv *env; // Pointer to native interface - jclass jdi; // Pointer to the JdbcInterface class - jobject job; // The JdbcInterface class object + jclass jdi; // Pointer to the java wrapper class + jobject job; // The java wrapper class object jmethodID xqid; // The ExecuteQuery method ID jmethodID xuid; // The ExecuteUpdate method ID jmethodID xid; // The Execute method ID diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 26965672ba4a2..0bc964d73510e 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1433,7 +1433,7 @@ static my_bool CheckMemory(PGLOBAL g, UDF_INIT *initid, UDF_ARGS *args, uint n, char *p = args->args[0]; // Is this a file name? - if (!strchr("[{ \t\r\n", *p) && (len = GetFileLength(p))) + if (p && !strchr("[{ \t\r\n", *p) && (len = GetFileLength(p))) ml += len * (M + 1); else ml += args->lengths[0] * M; @@ -1805,7 +1805,20 @@ my_bool json_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *messa } else CalcLen(args, false, reslen, memlen); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_add_values_init char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -1850,7 +1863,7 @@ char *json_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, } // endif str // Keep result of constant function - g->Xchk = (initid->const_item) ? str : NULL; + g->Xchk = (g->N) ? str : NULL; } else str = (char*)g->Xchk; @@ -1873,7 +1886,7 @@ void json_array_add_values_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - unsigned long reslen, memlen; + unsigned long reslen, memlen; if (args->arg_count < 2) { strcpy(message, "This function must have at least 2 arguments"); @@ -1884,7 +1897,20 @@ my_bool json_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_add_init char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -1930,7 +1956,7 @@ char *json_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -1966,7 +1992,20 @@ my_bool json_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_array_delete_init char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2008,7 +2047,7 @@ char *json_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2184,7 +2223,20 @@ my_bool json_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, true, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_object_add_init char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2227,7 +2279,7 @@ char *json_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2266,7 +2318,20 @@ my_bool json_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, true, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_object_delete_init char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2307,7 +2372,7 @@ char *json_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -2605,7 +2670,20 @@ my_bool json_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else CalcLen(args, false, reslen, memlen, true); - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + return false; + } else + return true; + } // end of json_item_merge_init char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -2651,7 +2729,7 @@ char *json_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!str) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Xchk = str; @@ -3552,11 +3630,11 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, PGLOBAL g = (PGLOBAL)initid->ptr; PGLOBAL gb = GetMemPtr(g, args, 0); - if (g->N) { + if (g->Alchecked) { str = (char*)g->Activityp; goto fin; - } else if (initid->const_item) - g->N = 1; + } else if (g->N) + g->Alchecked = 1; if (!strcmp(result, "$set")) w = 0; @@ -3632,7 +3710,7 @@ char *handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, if (!(str = MakeResult(g, args, jsp, INT_MAX32))) str = MakePSZ(g, args, 0); - if (initid->const_item) + if (g->N) // Keep result of constant function g->Activityp = (PACTIVITY)str; @@ -3677,7 +3755,21 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } else if (n != 3) memlen += args->lengths[0] * 3; - return JsonInit(initid, args, message, true, reslen, memlen); + if (!JsonInit(initid, args, message, true, reslen, memlen)) { + PGLOBAL g = (PGLOBAL)initid->ptr; + + // This is a constant function + g->N = (initid->const_item) ? 1 : 0; + + // This is to avoid double execution when using prepared statements + if (IsJson(args, 0) > 1) + initid->const_item = 0; + + g->Alchecked = 0; + return false; + } else + return true; + } // end of json_set_item_init char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -3742,8 +3834,8 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count < 1 || args->arg_count > 4) { strcpy(message, "This function only accepts 1 to 4 arguments"); return true; - } else if (!args->args[0] || args->arg_type[0] != STRING_RESULT) { - strcpy(message, "First argument must be a constant string (file name)"); + } else if (args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a string (file name)"); return true; } // endif's args[0] @@ -3761,7 +3853,12 @@ my_bool json_file_init(UDF_INIT *initid, UDF_ARGS *args, char *message) initid->maybe_null = 1; CalcLen(args, false, reslen, memlen); - fl = GetFileLength(args->args[0]); + + if (args->args[0]) + fl = GetFileLength(args->args[0]); + else + fl = 100; // What can be done here? + reslen += fl; if (initid->const_item) @@ -4020,7 +4117,18 @@ void jbin_array_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_add_values_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_add_values_init(initid, args, message); + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0) && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json string or item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + return JsonInit(initid, args, message, true, reslen, memlen); } // end of jbin_array_add_values_init char *jbin_array_add_values(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -4090,7 +4198,18 @@ void jbin_array_add_values_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_add_init(initid, args, message); + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); } // end of jbin_array_add_init char *jbin_array_add(UDF_INIT *initid, UDF_ARGS *args, char *result, @@ -4160,8 +4279,19 @@ void jbin_array_add_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_array_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_array_delete_init(initid, args, message); -} // end of jbin_array_delete_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_array_delete_init char *jbin_array_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4383,8 +4513,19 @@ void jbin_object_key_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_object_add_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_object_add_init(initid, args, message); -} // end of jbin_object_add_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, true, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_object_add_init char *jbin_object_add(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4449,8 +4590,22 @@ void jbin_object_add_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_object_delete_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_object_delete_init(initid, args, message); -} // end of jbin_object_delete_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have 2 or 3 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else if (args->arg_type[1] != STRING_RESULT) { + strcpy(message, "Second argument must be a key string"); + return true; + } else + CalcLen(args, true, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_object_delete_init char *jbin_object_delete(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4659,8 +4814,22 @@ void jbin_get_item_deinit(UDF_INIT* initid) /*********************************************************************************/ my_bool jbin_item_merge_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_item_merge_init(initid, args, message); -} // end of jbin_item_merge_init + unsigned long reslen, memlen; + + if (args->arg_count < 2) { + strcpy(message, "This function must have at least 2 arguments"); + return true; + } else if (!IsJson(args, 0)) { + strcpy(message, "First argument must be a json item"); + return true; + } else if (!IsJson(args, 1)) { + strcpy(message, "Second argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen, true); + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_item_merge_init char *jbin_item_merge(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *error) @@ -4820,8 +4989,31 @@ char *bin_handle_item(UDF_INIT *initid, UDF_ARGS *args, char *result, /*********************************************************************************/ my_bool jbin_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) { - return json_set_item_init(initid, args, message); -} // end of jbin_set_item_init + unsigned long reslen, memlen; + int n = IsJson(args, 0); + + if (!(args->arg_count % 2)) { + strcpy(message, "This function must have an odd number of arguments"); + return true; + } else if (!n && args->arg_type[0] != STRING_RESULT) { + strcpy(message, "First argument must be a json item"); + return true; + } else + CalcLen(args, false, reslen, memlen); + + if (n == 2 && args->args[0]) { + char fn[_MAX_PATH]; + long fl; + + memcpy(fn, args->args[0], args->lengths[0]); + fn[args->lengths[0]] = 0; + fl = GetFileLength(fn); + memlen += fl * 3; + } else if (n != 3) + memlen += args->lengths[0] * 3; + + return JsonInit(initid, args, message, true, reslen, memlen); + } // end of jbin_set_item_init char *jbin_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) @@ -4992,7 +5184,7 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count != 1) { strcpy(message, "This function must have 1 argument"); return true; - } else if (IsJson(args, 0) != 3) { + } else if (args->args[0] && IsJson(args, 0) != 3) { strcpy(message, "Argument must be a Jbin tree"); return true; } else @@ -5002,21 +5194,27 @@ my_bool json_serialize_init(UDF_INIT *initid, UDF_ARGS *args, char *message) } // end of json_serialize_init char *json_serialize(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, char *, char *error) { char *str; PGLOBAL g = (PGLOBAL)initid->ptr; if (!g->Xchk) { - PBSON bsp = (PBSON)args->args[0]; + if (IsJson(args, 0) == 3) { + PBSON bsp = (PBSON)args->args[0]; - JsonSubSet(g); + JsonSubSet(g); - if (!(str = Serialize(g, bsp->Jsp, NULL, 0))) - str = strcpy(result, g->Message); + if (!(str = Serialize(g, bsp->Jsp, NULL, 0))) + str = strcpy(result, g->Message); + + // Keep result of constant function + g->Xchk = (initid->const_item) ? str : NULL; + } else { + *error = 1; + str = strcpy(result, "Argument is not a Jbin tree"); + } // endif - // Keep result of constant function - g->Xchk = (initid->const_item) ? str : NULL; } else str = (char*)g->Xchk; @@ -5037,21 +5235,28 @@ my_bool envar_init(UDF_INIT *initid, UDF_ARGS *args, char *message) if (args->arg_count != 1) { strcpy(message, "Unique argument must be an environment variable name"); return true; - } else + } else { + initid->maybe_null = true; return false; + } // endif count } // end of envar_init char *envar(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *, char *) + unsigned long *res_length, char *is_null, char *) { char *str, name[256]; int n = MY_MIN(args->lengths[0], sizeof(name) - 1); memcpy(name, args->args[0], n); name[n] = 0; - str = getenv(name); - *res_length = (str) ? strlen(str) : 0; + + if (!(str = getenv(name))) { + *res_length = 0; + *is_null = 1; + } else + *res_length = strlen(str); + return str; } // end of envar diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index e9bd64cf8e677..b844d68e1cd66 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -901,8 +901,12 @@ PQRYRES MYSQLC::GetResult(PGLOBAL g, bool pdb) if (fld->flags & NOT_NULL_FLAG) crp->Nulls = NULL; else { - crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); - memset(crp->Nulls, ' ', m_Rows); + if (m_Rows) { + crp->Nulls = (char*)PlugSubAlloc(g, NULL, m_Rows); + memset(crp->Nulls, ' ', m_Rows); + } // endif m_Rows + + crp->Kdata->SetNullable(true); } // endelse fld->flags } // endfor fld diff --git a/storage/connect/plugutil.c b/storage/connect/plugutil.c index 38e28a171b22a..2551b60334979 100644 --- a/storage/connect/plugutil.c +++ b/storage/connect/plugutil.c @@ -516,7 +516,9 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) if (trace) htrc("PlugSubAlloc: %s\n", g->Message); - longjmp(g->jumper[g->jump_level], 1); + /* Nothing we can do if longjmp is not initialized. */ + assert(g->jump_level >= 0); + longjmp(g->jumper[g->jump_level], 1); } /* endif size OS32 code */ /*********************************************************************/ From 0f252702b15dfb5d90446fd49c9e28aa93424eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 8 Jun 2016 08:40:10 +0300 Subject: [PATCH 039/112] MDEV-7139: Sporadic failure in innodb.innodb_corrupt_bit on P8 Use direct persistent index corruption set on InnoDB dictionary for this test. Do not allow creating new indexes if one of the existing indexes is already marked as corrupted. --- .../suite/innodb/r/innodb_corrupt_bit.result | 90 ++++++------------- .../suite/innodb/t/innodb_corrupt_bit.test | 84 ++++++----------- storage/innobase/handler/ha_innodb.cc | 40 ++++++++- storage/innobase/handler/handler0alter.cc | 35 ++++++++ storage/xtradb/handler/ha_innodb.cc | 40 ++++++++- storage/xtradb/handler/handler0alter.cc | 35 ++++++++ 6 files changed, 204 insertions(+), 120 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result index 2ba79ced75f71..bc4334bd219aa 100644 --- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result +++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result @@ -1,83 +1,49 @@ -set names utf8; -CREATE TABLE corrupt_bit_test_Ä( -a INT AUTO_INCREMENT PRIMARY KEY, -b CHAR(100), -c INT, -z INT, -INDEX(b)) -ENGINE=InnoDB; -INSERT INTO corrupt_bit_test_Ä VALUES(0,'x',1, 1); -CREATE UNIQUE INDEX idxÄ ON corrupt_bit_test_Ä(c, b); -CREATE UNIQUE INDEX idxÄ“ ON corrupt_bit_test_Ä(z, b); -SELECT * FROM corrupt_bit_test_Ä; a b c z 1 x 1 1 -select @@unique_checks; -@@unique_checks -0 -select @@innodb_change_buffering_debug; -@@innodb_change_buffering_debug -1 -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+10,z+10 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+20,z+20 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+50,z+50 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+100,z+100 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+200,z+200 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+400,z+400 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+800,z+800 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+1600,z+1600 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+4000,z+4000 FROM corrupt_bit_test_Ä; -select count(*) from corrupt_bit_test_Ä; count(*) -1024 -CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c); -INSERT INTO corrupt_bit_test_Ä VALUES(13000,'x',1,1); -CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z); -check table corrupt_bit_test_Ä; +2 Table Op Msg_type Msg_text -test.corrupt_bit_test_Ä check Warning InnoDB: The B-tree of index "idxÄ" is corrupted. -test.corrupt_bit_test_Ä check Warning InnoDB: The B-tree of index "idxÄ“" is corrupted. +test.corrupt_bit_test_Ä check Warning InnoDB: Index "idx" is marked as corrupted +test.corrupt_bit_test_Ä check Warning InnoDB: Index "idxÄ" is marked as corrupted +test.corrupt_bit_test_Ä check Warning InnoDB: Index "idxÄ“" is marked as corrupted test.corrupt_bit_test_Ä check error Corrupt -select c from corrupt_bit_test_Ä; ERROR HY000: Index corrupt_bit_test_Ä is corrupted -select z from corrupt_bit_test_Ä; ERROR HY000: Index corrupt_bit_test_Ä is corrupted -show warnings; +ERROR HY000: Index corrupt_bit_test_Ä is corrupted +ERROR HY000: Index corrupt_bit_test_Ä is corrupted Level Code Message Warning 179 InnoDB: Index "idxÄ“" for table "test"."corrupt_bit_test_Ä" is marked as corrupted Warning 179 Got error 179 when reading table `test`.`corrupt_bit_test_Ä` Error 1712 Index corrupt_bit_test_Ä is corrupted -insert into corrupt_bit_test_Ä values (10001, "a", 20001, 20001); -select * from corrupt_bit_test_Ä use index(primary) where a = 10001; a b c z 10001 a 20001 20001 -begin; -insert into corrupt_bit_test_Ä values (10002, "a", 20002, 20002); -delete from corrupt_bit_test_Ä where a = 10001; -insert into corrupt_bit_test_Ä values (10001, "a", 20001, 20001); -rollback; -drop index idxÄ on corrupt_bit_test_Ä; -check table corrupt_bit_test_Ä; Table Op Msg_type Msg_text +test.corrupt_bit_test_Ä check Warning InnoDB: Index "idx" is marked as corrupted test.corrupt_bit_test_Ä check Warning InnoDB: Index "idxÄ“" is marked as corrupted test.corrupt_bit_test_Ä check error Corrupt -set names utf8; -select z from corrupt_bit_test_Ä; ERROR HY000: Index corrupt_bit_test_Ä is corrupted -drop index idxÄ“ on corrupt_bit_test_Ä; -select z from corrupt_bit_test_Ä limit 10; +Table Create Table +corrupt_bit_test_Ä CREATE TABLE `corrupt_bit_test_Ä` ( + `a` int(11) NOT NULL AUTO_INCREMENT, + `b` char(100) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `z` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + UNIQUE KEY `idxÄ“` (`z`,`b`), + KEY `idx` (`b`) +) ENGINE=InnoDB AUTO_INCREMENT=10003 DEFAULT CHARSET=latin1 +ERROR HY000: Index corrupt_bit_test_Ä is corrupted +ERROR HY000: Index corrupt_bit_test_Ä is corrupted +Table Create Table +corrupt_bit_test_Ä CREATE TABLE `corrupt_bit_test_Ä` ( + `a` int(11) NOT NULL AUTO_INCREMENT, + `b` char(100) DEFAULT NULL, + `c` int(11) DEFAULT NULL, + `z` int(11) DEFAULT NULL, + PRIMARY KEY (`a`), + KEY `idx` (`b`) +) ENGINE=InnoDB AUTO_INCREMENT=10003 DEFAULT CHARSET=latin1 z 20001 1 -1 2 -11 -12 -21 -22 -31 -32 -drop table corrupt_bit_test_Ä; -DROP DATABASE pad; -SET GLOBAL innodb_change_buffering_debug = 0; diff --git a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test index 88da919bfaae0..f67e2e7e04796 100644 --- a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test +++ b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test @@ -2,45 +2,23 @@ # Test for persistent corrupt bit for corrupted index and table # -- source include/have_innodb.inc - -# Issues with innodb_change_buffering_debug on Windows, so the test scenario -# cannot be created on windows ---source include/not_windows.inc - +-- source include/not_embedded.inc # This test needs debug server ---source include/have_debug.inc +-- source include/have_debug.inc -- disable_query_log call mtr.add_suppression("Flagged corruption of idx.*in CHECK TABLE"); -# This test setup is extracted from bug56680.test: -# The flag innodb_change_buffering_debug is only available in debug builds. -# It instructs InnoDB to try to evict pages from the buffer pool when -# change buffering is possible, so that the change buffer will be used -# whenever possible. -SET @innodb_change_buffering_debug_orig = @@innodb_change_buffering_debug; -SET GLOBAL innodb_change_buffering_debug = 1; - -# Turn off Unique Check to create corrupted index with dup key -SET UNIQUE_CHECKS=0; - -CREATE DATABASE pad; -let $i=338; -while ($i) -{ ---eval CREATE TABLE pad.t$i(a INT PRIMARY KEY)ENGINE=InnoDB; - dec $i; -} - --- enable_query_log set names utf8; +SET UNIQUE_CHECKS=0; + CREATE TABLE corrupt_bit_test_Ä( a INT AUTO_INCREMENT PRIMARY KEY, b CHAR(100), c INT, z INT, - INDEX(b)) + INDEX idx(b)) ENGINE=InnoDB; INSERT INTO corrupt_bit_test_Ä VALUES(0,'x',1, 1); @@ -53,38 +31,21 @@ CREATE UNIQUE INDEX idxÄ“ ON corrupt_bit_test_Ä(z, b); SELECT * FROM corrupt_bit_test_Ä; -select @@unique_checks; -select @@innodb_change_buffering_debug; - -# Create enough rows for the table, so that the insert buffer will be -# used for modifying the secondary index page. There must be multiple -# index pages, because changes to the root page are never buffered. - INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+1,z+1 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+10,z+10 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+20,z+20 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+50,z+50 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+100,z+100 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+200,z+200 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+400,z+400 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+800,z+800 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+1600,z+1600 FROM corrupt_bit_test_Ä; -INSERT INTO corrupt_bit_test_Ä SELECT 0,b,c+4000,z+4000 FROM corrupt_bit_test_Ä; select count(*) from corrupt_bit_test_Ä; -CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c); - -# Create a dup key error on index "idxÄ“" and "idxÄ" by inserting a dup value -INSERT INTO corrupt_bit_test_Ä VALUES(13000,'x',1,1); +# This will flag all secondary indexes corrupted +SET SESSION debug_dbug="+d,dict_set_index_corrupted"; +check table corrupt_bit_test_Ä; +SET SESSION debug_dbug="-d,dict_set_index_corrupted"; -# creating an index should succeed even if other secondary indexes are corrupted +# Cannot create new indexes while corrupted indexes exist +--error ER_INDEX_CORRUPT +CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c); +--error ER_INDEX_CORRUPT CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z); -# Check table will find the unique indexes corrupted -# with dup key -check table corrupt_bit_test_Ä; - # This selection intend to use the corrupted index. Expect to fail -- error ER_INDEX_CORRUPT select c from corrupt_bit_test_Ä; @@ -108,7 +69,6 @@ delete from corrupt_bit_test_Ä where a = 10001; insert into corrupt_bit_test_Ä values (10001, "a", 20001, 20001); rollback; -# Drop one corrupted index before reboot drop index idxÄ on corrupt_bit_test_Ä; check table corrupt_bit_test_Ä; @@ -118,14 +78,26 @@ set names utf8; -- error ER_INDEX_CORRUPT select z from corrupt_bit_test_Ä; +show create table corrupt_bit_test_Ä; + # Drop the corrupted index drop index idxÄ“ on corrupt_bit_test_Ä; +# Cannot create new indexes while a corrupt index exists. +--error ER_INDEX_CORRUPT +CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c); +--error ER_INDEX_CORRUPT +CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z); + +show create table corrupt_bit_test_Ä; +drop index idx on corrupt_bit_test_Ä; + +# Now that there exist no corrupted indexes, we can create new indexes. +CREATE INDEX idx3 ON corrupt_bit_test_Ä(b, c); +CREATE INDEX idx4 ON corrupt_bit_test_Ä(b, z); + # Now select back to normal select z from corrupt_bit_test_Ä limit 10; # Drop table drop table corrupt_bit_test_Ä; -DROP DATABASE pad; - -SET GLOBAL innodb_change_buffering_debug = 0; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index b3e6b3c7310e7..734dbe1cafd69 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2106,7 +2106,6 @@ innobase_convert_name( A wrapper function of innobase_convert_name(), convert a table or index name to the MySQL system_charset_info (UTF-8) and quote it if needed. @return pointer to the end of buf */ -static inline void innobase_format_name( /*==================*/ @@ -8685,6 +8684,36 @@ ha_innobase::check( DBUG_RETURN(HA_ADMIN_CORRUPT); } + if (prebuilt->table->corrupted) { + char index_name[MAX_FULL_NAME_LEN + 1]; + /* If some previous operation has marked the table as + corrupted in memory, and has not propagated such to + clustered index, we will do so here */ + index = dict_table_get_first_index(prebuilt->table); + + if (!dict_index_is_corrupted(index)) { + row_mysql_lock_data_dictionary(prebuilt->trx); + dict_set_corrupted(index); + row_mysql_unlock_data_dictionary(prebuilt->trx); + } + + innobase_format_name(index_name, sizeof index_name, + index->name, TRUE); + + push_warning_printf(thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_INDEX_CORRUPT, + "InnoDB: Index %s is marked as" + " corrupted", + index_name); + + /* Now that the table is already marked as corrupted, + there is no need to check any index of this table */ + prebuilt->trx->op_info = ""; + + DBUG_RETURN(HA_ADMIN_CORRUPT); + } + prebuilt->trx->op_info = "checking table"; old_isolation_level = prebuilt->trx->isolation_level; @@ -8761,6 +8790,15 @@ ha_innobase::check( prebuilt->index_usable = row_merge_is_index_usable( prebuilt->trx, prebuilt->index); + DBUG_EXECUTE_IF( + "dict_set_index_corrupted", + if (!dict_index_is_clust(index)) { + prebuilt->index_usable = FALSE; + row_mysql_lock_data_dictionary(prebuilt->trx); + dict_set_corrupted(index); + row_mysql_unlock_data_dictionary(prebuilt->trx); + }); + if (UNIV_UNLIKELY(!prebuilt->index_usable)) { innobase_format_name( index_name, sizeof index_name, diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 735d9fb95d0b2..ecfda6d626469 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -654,6 +654,19 @@ class ha_innobase_add_index : public handler_add_index ~ha_innobase_add_index() {} }; + +/*****************************************************************//** +A wrapper function of innobase_convert_name(), convert a table or +index name to the MySQL system_charset_info (UTF-8) and quote it if needed. +@return pointer to the end of buf */ +void +innobase_format_name( +/*==================*/ + char* buf, /*!< out: buffer for converted identifier */ + ulint buflen, /*!< in: length of buf, in bytes */ + const char* name, /*!< in: index or table name to format */ + ibool is_index_name); /*!< in: index name */ + /*******************************************************************//** Create indexes. @return 0 or error number */ @@ -715,6 +728,28 @@ ha_innobase::add_index( DBUG_RETURN(-1); } + /* Check if any of the existing indexes are marked as corruption, + and if they are, refuse adding more indexes. */ + for (dict_index_t* check_index = dict_table_get_first_index(indexed_table); + check_index != NULL; + check_index = dict_table_get_next_index(check_index)) { + + if (dict_index_is_corrupted(check_index)) { + char index_name[MAX_FULL_NAME_LEN + 1]; + + innobase_format_name(index_name, sizeof index_name, + check_index->name, TRUE); + + push_warning_printf(user_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_INDEX_CORRUPT, + "InnoDB: Index %s is marked as" + " corrupted", + index_name); + DBUG_RETURN(HA_ERR_INDEX_CORRUPT); + } + } + /* Check that index keys are sensible */ error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index fcf387bd892b5..8148c3e1dd50a 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2409,7 +2409,6 @@ innobase_convert_name( A wrapper function of innobase_convert_name(), convert a table or index name to the MySQL system_charset_info (UTF-8) and quote it if needed. @return pointer to the end of buf */ -static inline void innobase_format_name( /*==================*/ @@ -9859,6 +9858,36 @@ ha_innobase::check( DBUG_RETURN(HA_ADMIN_CORRUPT); } + if (prebuilt->table->corrupted) { + char index_name[MAX_FULL_NAME_LEN + 1]; + /* If some previous operation has marked the table as + corrupted in memory, and has not propagated such to + clustered index, we will do so here */ + index = dict_table_get_first_index(prebuilt->table); + + if (!dict_index_is_corrupted(index)) { + row_mysql_lock_data_dictionary(prebuilt->trx); + dict_set_corrupted(index); + row_mysql_unlock_data_dictionary(prebuilt->trx); + } + + innobase_format_name(index_name, sizeof index_name, + index->name, TRUE); + + push_warning_printf(thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_INDEX_CORRUPT, + "InnoDB: Index %s is marked as" + " corrupted", + index_name); + + /* Now that the table is already marked as corrupted, + there is no need to check any index of this table */ + prebuilt->trx->op_info = ""; + + DBUG_RETURN(HA_ADMIN_CORRUPT); + } + prebuilt->trx->op_info = "checking table"; old_isolation_level = prebuilt->trx->isolation_level; @@ -9935,6 +9964,15 @@ ha_innobase::check( prebuilt->index_usable = row_merge_is_index_usable( prebuilt->trx, prebuilt->index); + DBUG_EXECUTE_IF( + "dict_set_index_corrupted", + if (!dict_index_is_clust(index)) { + prebuilt->index_usable = FALSE; + row_mysql_lock_data_dictionary(prebuilt->trx); + dict_set_corrupted(index); + row_mysql_unlock_data_dictionary(prebuilt->trx); + }); + if (UNIV_UNLIKELY(!prebuilt->index_usable)) { innobase_format_name( index_name, sizeof index_name, diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 65b2c2f58df0c..82902db84124f 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -655,6 +655,19 @@ class ha_innobase_add_index : public handler_add_index ~ha_innobase_add_index() {} }; + +/*****************************************************************//** +A wrapper function of innobase_convert_name(), convert a table or +index name to the MySQL system_charset_info (UTF-8) and quote it if needed. +@return pointer to the end of buf */ +void +innobase_format_name( +/*==================*/ + char* buf, /*!< out: buffer for converted identifier */ + ulint buflen, /*!< in: length of buf, in bytes */ + const char* name, /*!< in: index or table name to format */ + ibool is_index_name); /*!< in: index name */ + /*******************************************************************//** Create indexes. @return 0 or error number */ @@ -720,6 +733,28 @@ ha_innobase::add_index( DBUG_RETURN(-1); } + /* Check if any of the existing indexes are marked as corruption, + and if they are, refuse adding more indexes. */ + for (dict_index_t* check_index = dict_table_get_first_index(indexed_table); + check_index != NULL; + check_index = dict_table_get_next_index(check_index)) { + + if (dict_index_is_corrupted(check_index)) { + char index_name[MAX_FULL_NAME_LEN + 1]; + + innobase_format_name(index_name, sizeof index_name, + check_index->name, TRUE); + + push_warning_printf(user_thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_INDEX_CORRUPT, + "InnoDB: Index %s is marked as" + " corrupted", + index_name); + DBUG_RETURN(HA_ERR_INDEX_CORRUPT); + } + } + /* Check that index keys are sensible */ error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table); From a4848e975d2fe359ff354e767427c01dbe908037 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 8 Jun 2016 19:04:12 +0400 Subject: [PATCH 040/112] MDEV-9972 Least function retuns date in date time format --- mysql-test/r/type_date.result | 7 ++++--- mysql-test/t/type_date.test | 1 + sql/item_func.cc | 5 +++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 7678f038862a8..ecbda1d13e6ff 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -442,6 +442,7 @@ select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1; drop table t1; # # MDEV-9521 Least function returns 0000-00-00 for null date columns instead of null +# MDEV-9972 Least function retuns date in date time format # CREATE TABLE t1 ( id BIGINT NOT NULL, @@ -465,9 +466,9 @@ LEAST(IFNULL(t2.date_fin, IFNULL(t1.date_fin, NULL)), IFNULL(t1.date_fin, IFNULL(t2.date_fin, NULL))) AS date_fin FROM t1 LEFT JOIN t2 ON (t1.id=t2.id); id date_debut date_fin -1 2016-01-01 2016-01-31 00:00:00 -2 2016-02-01 2016-01-28 00:00:00 -3 2016-03-01 2016-03-31 00:00:00 +1 2016-01-01 2016-01-31 +2 2016-02-01 2016-01-28 +3 2016-03-01 2016-03-31 4 2016-04-01 NULL DROP TABLE t1,t2; SELECT diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 4b058171ad22e..8b0c5dcf3303c 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -388,6 +388,7 @@ drop table t1; --echo # --echo # MDEV-9521 Least function returns 0000-00-00 for null date columns instead of null +--echo # MDEV-9972 Least function retuns date in date time format --echo # CREATE TABLE t1 ( id BIGINT NOT NULL, diff --git a/sql/item_func.cc b/sql/item_func.cc index cabba7a666c17..4b5f96cd3e730 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2939,12 +2939,13 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) } unpack_time(min_max, ltime); - if (compare_as_dates->field_type() == MYSQL_TYPE_DATE) + enum_field_types ftype= compare_as_dates->field_type(); + if (ftype == MYSQL_TYPE_DATE || ftype == MYSQL_TYPE_NEWDATE) { ltime->time_type= MYSQL_TIMESTAMP_DATE; ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0; } - else if (compare_as_dates->field_type() == MYSQL_TYPE_TIME) + else if (ftype == MYSQL_TYPE_TIME) { ltime->time_type= MYSQL_TIMESTAMP_TIME; ltime->hour+= (ltime->month * 32 + ltime->day) * 24; From 7adf04e237c41d323b5181c108e7babed3c015fa Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 5 Jan 2016 22:48:50 +0100 Subject: [PATCH 041/112] MDEV-9366 : do_shutdown_server fails to detect server shutdown on Windows. Fix test whether process is alive in mysqltest. Also fix SHUT_RD definition on Windows to be SD_RECEIVE. SD_BOTH was used instead prior to this patch, and this would occasionally make mysql_shutdown() fail - when the socket for the current connection is not able send the COM_SHUTDOWN response anymore. --- client/mysqltest.cc | 5 +++-- include/violite.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 9a1dfaa18efda..3652d1a40e2be 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -5086,12 +5086,13 @@ static int my_kill(int pid, int sig) { #ifdef __WIN__ HANDLE proc; - if ((proc= OpenProcess(PROCESS_TERMINATE, FALSE, pid)) == NULL) + if ((proc= OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE, pid)) == NULL) return -1; if (sig == 0) { + DWORD wait_result= WaitForSingleObject(proc, 0); CloseHandle(proc); - return 0; + return wait_result == WAIT_OBJECT_0?-1:0; } (void)TerminateProcess(proc, 201); CloseHandle(proc); diff --git a/include/violite.h b/include/violite.h index ea7e3d7897c18..da58de4373c7a 100644 --- a/include/violite.h +++ b/include/violite.h @@ -184,7 +184,7 @@ void vio_end(void); /* shutdown(2) flags */ #ifndef SHUT_RD -#define SHUT_RD SD_BOTH +#define SHUT_RD SD_RECEIVE #endif /* From df1448801ceba4d8d8a02db83ba022fea9e6755d Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 10 Jun 2016 15:50:19 +0400 Subject: [PATCH 042/112] MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field --- mysql-test/r/ctype_recoding.result | 33 +++++++++++++++++++++++++++++- mysql-test/t/ctype_recoding.test | 28 ++++++++++++++++++++++++- sql/field.cc | 1 + sql/field.h | 21 +++++++++++-------- sql/sql_select.cc | 6 ++++-- 5 files changed, 76 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result index c84da0d74968d..2555749fa8c1a 100644 --- a/mysql-test/r/ctype_recoding.result +++ b/mysql-test/r/ctype_recoding.result @@ -277,9 +277,40 @@ CREATE TABLE t1 ( a VARCHAR(1) ); INSERT INTO t1 VALUES ('m'),('n'); CREATE VIEW v1 AS SELECT 'w' ; SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); -ERROR HY000: Illegal mix of collations (utf8_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation '<=' +a +m +n drop view v1; drop table t1; SET character_set_connection = default; SET optimizer_switch= default; #End of 5.3 tests +# +# Start of 5.5 tests +# +# +# MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field +# +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('A'),('a'),('B'),('b'); +CREATE VIEW v1 AS SELECT 'a'; +SELECT * FROM v1,t1 where t1.a=v1.a; +a a +a A +a a +DROP VIEW v1; +DROP TABLE t1; +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('a'),('b'),('c'); +CREATE VIEW v1 AS SELECT 'a' AS a UNION SELECT 'b'; +SELECT * FROM v1,t1 WHERE t1.a=v1.a; +a a +a a +b b +DROP VIEW v1; +DROP TABLE t1; +# +# End of 5.5 tests +# diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test index ee07ef24deff7..81c04fc9c309a 100644 --- a/mysql-test/t/ctype_recoding.test +++ b/mysql-test/t/ctype_recoding.test @@ -220,7 +220,6 @@ SET character_set_connection = utf8; CREATE TABLE t1 ( a VARCHAR(1) ); INSERT INTO t1 VALUES ('m'),('n'); CREATE VIEW v1 AS SELECT 'w' ; ---error ER_CANT_AGGREGATE_2COLLATIONS SELECT * FROM t1 WHERE a < ALL ( SELECT * FROM v1 ); drop view v1; drop table t1; @@ -228,3 +227,30 @@ SET character_set_connection = default; SET optimizer_switch= default; --echo #End of 5.3 tests + +--echo # +--echo # Start of 5.5 tests +--echo # + +--echo # +--echo # MDEV-10181 Illegal mix of collation for a field and an ASCII string as a view field +--echo # +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('A'),('a'),('B'),('b'); +CREATE VIEW v1 AS SELECT 'a'; +SELECT * FROM v1,t1 where t1.a=v1.a; +DROP VIEW v1; +DROP TABLE t1; + +SET NAMES utf8; +CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1); +INSERT INTO t1 VALUES ('a'),('b'),('c'); +CREATE VIEW v1 AS SELECT 'a' AS a UNION SELECT 'b'; +SELECT * FROM v1,t1 WHERE t1.a=v1.a; +DROP VIEW v1; +DROP TABLE t1; + +--echo # +--echo # End of 5.5 tests +--echo # diff --git a/sql/field.cc b/sql/field.cc index ceea0893a3f7b..a0686fb2f1974 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1701,6 +1701,7 @@ Field_str::Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, if (charset_arg->state & MY_CS_BINSORT) flags|=BINARY_FLAG; field_derivation= DERIVATION_IMPLICIT; + field_repertoire= my_charset_repertoire(charset_arg); } diff --git a/sql/field.h b/sql/field.h index f761aa8d3ea30..fdf229edfbbe3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -580,11 +580,12 @@ class Field { return binary() ? &my_charset_bin : charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual bool has_charset(void) const { return FALSE; } - virtual void set_charset(CHARSET_INFO *charset_arg) { } virtual enum Derivation derivation(void) const { return DERIVATION_IMPLICIT; } virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; } - virtual void set_derivation(enum Derivation derivation_arg) { } + virtual void set_derivation(enum Derivation derivation_arg, + uint repertoire_arg) + { } virtual int set_time() { return 1; } void set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code, int cuted_increment); @@ -775,8 +776,10 @@ class Field_num :public Field { class Field_str :public Field { protected: + // TODO-10.2: Reuse DTCollation instead of these three members CHARSET_INFO *field_charset; enum Derivation field_derivation; + uint field_repertoire; public: Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, @@ -799,15 +802,15 @@ class Field_str :public Field { int store_decimal(const my_decimal *); int store(const char *to,uint length,CHARSET_INFO *cs)=0; uint size_of() const { return sizeof(*this); } - uint repertoire(void) const - { - return my_charset_repertoire(field_charset); - } + uint repertoire(void) const { return field_repertoire; } CHARSET_INFO *charset(void) const { return field_charset; } - void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; } enum Derivation derivation(void) const { return field_derivation; } - virtual void set_derivation(enum Derivation derivation_arg) - { field_derivation= derivation_arg; } + void set_derivation(enum Derivation derivation_arg, + uint repertoire_arg) + { + field_derivation= derivation_arg; + field_repertoire= repertoire_arg; + } bool binary() const { return field_charset == &my_charset_bin; } uint32 max_display_length() { return field_length; } friend class Create_field; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 91aecadfd0a3c..613cbb2e08699 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14586,7 +14586,8 @@ static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table, item->collation.collation); else new_field= item->make_string_field(table); - new_field->set_derivation(item->collation.derivation); + new_field->set_derivation(item->collation.derivation, + item->collation.repertoire); break; case DECIMAL_RESULT: new_field= Field_new_decimal::create_from_item(item); @@ -14825,7 +14826,8 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, modify_item, convert_blob_length); case Item::TYPE_HOLDER: result= ((Item_type_holder *)item)->make_field_by_type(table); - result->set_derivation(item->collation.derivation); + result->set_derivation(item->collation.derivation, + item->collation.repertoire); return result; default: // Dosen't have to be stored return 0; From 4155d0937b98e57a93adbe5b5dc20d06ceda59e7 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 10 Jun 2016 17:06:38 +0400 Subject: [PATCH 043/112] MDEV-8402 Bug #77473 Truncated data with subquery & UTF8 --- mysql-test/r/ctype_utf8.result | 39 +++++++++++++++++++++++++++++++ mysql-test/r/ctype_utf8mb4.result | 34 +++++++++++++++++++++++++++ mysql-test/t/ctype_utf8.test | 23 ++++++++++++++++++ mysql-test/t/ctype_utf8mb4.test | 20 ++++++++++++++++ sql/field.h | 7 +++--- 5 files changed, 119 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 217d3ca26d8c7..121168c2a2a5c 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -5830,5 +5830,44 @@ OCTET_LENGTH(a) a 255 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA DROP TABLE t1; # +# MDEV-8402 Bug#77473 Bug#21317406 TRUNCATED DATA WITH SUBQUERY & UTF8 +# +# +SET NAMES utf8; +SELECT length(rpad(_utf8 0xD0B1, 65536, _utf8 0xD0B2)) AS data; +data +131072 +SELECT length(data) AS len FROM ( +SELECT rpad(_utf8 0xD0B1, 65536, _utf8 0xD0B2) AS data +) AS sub; +len +131072 +SELECT length(rpad(_utf8 0xD0B1, 65535, _utf8 0xD0B2)) AS data; +data +131070 +SELECT length(data) AS len FROM ( +SELECT rpad(_utf8 0xD0B1, 65535, _utf8 0xD0B2) AS data +) AS sub; +len +131070 +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 36766) AS data) AS sub; +len +73532 +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 36767) AS data) AS sub; +len +73534 +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 36778) AS data) AS sub; +len +73556 +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 65535) AS data) AS sub; +len +131070 +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 65536) AS data) AS sub; +len +131072 +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 65537) AS data) AS sub; +len +131074 +# # End of 5.5 tests # diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index 448645ebbae48..17a1a2f787e83 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -2622,6 +2622,40 @@ OCTET_LENGTH(a) a 252 😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎😎 DROP TABLE t1; # +# MDEV-8402 Bug#77473 Bug#21317406 TRUNCATED DATA WITH SUBQUERY & UTF8 +# +# +SET NAMES utf8mb4; +SELECT length(repeat(_utf8mb4 0xE29883, 21844)) AS data; +data +65532 +SELECT length(data) AS len +FROM ( SELECT repeat(_utf8mb4 0xE29883, 21844) AS data ) AS sub; +len +65532 +SELECT length(repeat(_utf8mb4 0xE29883, 21846)) AS data; +data +65538 +SELECT length(data) AS len +FROM ( SELECT repeat(_utf8mb4 0xE29883, 21846) AS data ) AS sub; +len +65538 +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 21844) AS data ) AS sub; +len +65532 +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 21845) AS data ) AS sub; +len +65535 +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 21846) AS data ) AS sub; +len +65538 +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65535) AS data ) AS sub; +len +196605 +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65536) AS data ) AS sub; +len +196608 +# # End of 5.5 tests # # diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index a9b5cee11ce9e..d6fdc6c6a2ced 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1658,6 +1658,29 @@ ALTER TABLE t1 MODIFY a TINYTEXT CHARACTER SET utf8; SELECT OCTET_LENGTH(a),a FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-8402 Bug#77473 Bug#21317406 TRUNCATED DATA WITH SUBQUERY & UTF8 +--echo # +--echo # + +SET NAMES utf8; +SELECT length(rpad(_utf8 0xD0B1, 65536, _utf8 0xD0B2)) AS data; +SELECT length(data) AS len FROM ( + SELECT rpad(_utf8 0xD0B1, 65536, _utf8 0xD0B2) AS data +) AS sub; + +SELECT length(rpad(_utf8 0xD0B1, 65535, _utf8 0xD0B2)) AS data; +SELECT length(data) AS len FROM ( + SELECT rpad(_utf8 0xD0B1, 65535, _utf8 0xD0B2) AS data +) AS sub; + +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 36766) AS data) AS sub; +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 36767) AS data) AS sub; +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 36778) AS data) AS sub; +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 65535) AS data) AS sub; +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 65536) AS data) AS sub; +SELECT length(data) AS len FROM (SELECT REPEAT('ä', 65537) AS data) AS sub; + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test index 66f5a3ba5ac7a..c240f261af40e 100644 --- a/mysql-test/t/ctype_utf8mb4.test +++ b/mysql-test/t/ctype_utf8mb4.test @@ -1838,6 +1838,26 @@ SELECT OCTET_LENGTH(a),a FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-8402 Bug#77473 Bug#21317406 TRUNCATED DATA WITH SUBQUERY & UTF8 +--echo # +--echo # + +SET NAMES utf8mb4; +SELECT length(repeat(_utf8mb4 0xE29883, 21844)) AS data; +SELECT length(data) AS len +FROM ( SELECT repeat(_utf8mb4 0xE29883, 21844) AS data ) AS sub; + +SELECT length(repeat(_utf8mb4 0xE29883, 21846)) AS data; +SELECT length(data) AS len +FROM ( SELECT repeat(_utf8mb4 0xE29883, 21846) AS data ) AS sub; + +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 21844) AS data ) AS sub; +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 21845) AS data ) AS sub; +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 21846) AS data ) AS sub; +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65535) AS data ) AS sub; +SELECT LENGTH(data) AS len FROM (SELECT REPEAT('☃', 65536) AS data ) AS sub; + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/field.h b/sql/field.h index fdf229edfbbe3..f8fc742761849 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1854,10 +1854,9 @@ class Field_blob :public Field_longstr { packlength= 4; if (set_packlength) { - uint32 l_char_length= len_arg/cs->mbmaxlen; - packlength= l_char_length <= 255 ? 1 : - l_char_length <= 65535 ? 2 : - l_char_length <= 16777215 ? 3 : 4; + packlength= len_arg <= 255 ? 1 : + len_arg <= 65535 ? 2 : + len_arg <= 16777215 ? 3 : 4; } } Field_blob(uint32 packlength_arg) From f853a99a4fad0f390d6b1f6c46648302ca6cf310 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 10 Jun 2016 19:47:58 +0200 Subject: [PATCH 044/112] 5.6.30-76.3 --- storage/tokudb/CMakeLists.txt | 4 +- .../cmake_modules/TokuSetupCompiler.cmake | 28 +- .../tokudb/PerconaFT/ft/logger/log_upgrade.cc | 4 +- storage/tokudb/PerconaFT/ft/logger/recover.h | 2 +- .../tokudb/PerconaFT/ft/tests/CMakeLists.txt | 2 + .../tokudb/PerconaFT/ft/tests/make-tree.cc | 2 +- .../tokudb/PerconaFT/ft/tests/msnfilter.cc | 2 +- .../ft/tests/test-upgrade-recovery-logs.cc | 2 +- .../log000000000000.tokulog24 | Bin 0 -> 131 bytes .../log000000000000.tokulog24 | Bin 0 -> 94 bytes .../log000000000000.tokulog25 | Bin 0 -> 131 bytes .../log000000000000.tokulog25 | Bin 0 -> 94 bytes .../log000000000000.tokulog26 | Bin 0 -> 131 bytes .../log000000000000.tokulog26 | Bin 0 -> 94 bytes .../log000000000000.tokulog27 | Bin 0 -> 131 bytes .../log000000000000.tokulog27 | Bin 0 -> 94 bytes .../log000000000000.tokulog28 | Bin 0 -> 131 bytes .../log000000000000.tokulog28 | Bin 0 -> 94 bytes .../log000000000000.tokulog29 | Bin 0 -> 131 bytes .../log000000000000.tokulog29 | Bin 0 -> 94 bytes .../PerconaFT/ft/tests/verify-bad-msn.cc | 2 +- .../PerconaFT/ft/tests/verify-bad-pivots.cc | 2 +- .../PerconaFT/ft/tests/verify-dup-in-leaf.cc | 2 +- .../PerconaFT/ft/tests/verify-dup-pivots.cc | 2 +- .../ft/tests/verify-misrouted-msgs.cc | 2 +- .../ft/tests/verify-unsorted-leaf.cc | 2 +- .../ft/tests/verify-unsorted-pivots.cc | 2 +- .../tokudb/PerconaFT/ft/txn/txn_manager.cc | 4 +- storage/tokudb/PerconaFT/ft/txn/txn_manager.h | 2 +- .../PerconaFT/ftcxx/tests/CMakeLists.txt | 10 +- .../PerconaFT/scripts/run.stress-tests.py | 26 +- .../tokudb/PerconaFT/src/indexer-undo-do.cc | 2 +- .../src/tests/rollback-inconsistency.cc | 4 +- .../PerconaFT/src/tests/test_db_rowcount.cc | 55 ++-- .../txn_manager_handle_snapshot_atomicity.cc | 20 +- storage/tokudb/PerconaFT/src/ydb.cc | 2 +- storage/tokudb/PerconaFT/src/ydb.h | 2 +- storage/tokudb/ha_tokudb.cc | 285 +++++++++++------- storage/tokudb/ha_tokudb.h | 13 +- storage/tokudb/ha_tokudb_admin.cc | 15 +- storage/tokudb/hatoku_hton.cc | 10 + .../r/i_s_tokudb_lock_waits_released.result | 4 + .../r/i_s_tokudb_lock_waits_timeout.result | 4 +- .../tokudb/r/i_s_tokudb_locks.result | 24 +- .../tokudb/r/i_s_tokudb_locks_released.result | 2 + .../mysql-test/tokudb/r/i_s_tokudb_trx.result | 21 +- .../tokudb/mysql-test/tokudb/t/disabled.def | 22 +- .../t/i_s_tokudb_lock_waits_released.test | 4 + .../t/i_s_tokudb_lock_waits_timeout.test | 11 +- .../mysql-test/tokudb/t/i_s_tokudb_locks.test | 9 +- .../tokudb/t/i_s_tokudb_locks_released.test | 2 + .../mysql-test/tokudb/t/i_s_tokudb_trx.test | 17 +- .../mysql-test/tokudb_bugs/r/5585.result | 6 - .../mysql-test/tokudb_bugs/r/db233.result | 37 +++ .../tokudb_bugs/r/db397_delete_trigger.result | 12 +- .../tokudb_bugs/r/db397_insert_trigger.result | 8 +- .../tokudb_bugs/r/db397_update_trigger.result | 12 +- .../tokudb_bugs/r/db739_replace.result | 2 + .../r/db757_part_alter_analyze.result | 8 +- .../mysql-test/tokudb_bugs/r/db945.result | 12 + .../tokudb_bugs/r/simple_icp.result | 4 +- .../tokudb/mysql-test/tokudb_bugs/t/5585.test | 6 - .../mysql-test/tokudb_bugs/t/db233.test | 70 +++++ .../tokudb_bugs/t/db397_delete_trigger.test | 6 +- .../tokudb_bugs/t/db397_insert_trigger.test | 6 +- .../tokudb_bugs/t/db397_update_trigger.test | 4 +- .../mysql-test/tokudb_bugs/t/db945.test | 24 ++ .../mysql-test/tokudb_parts/t/disabled.def | 2 - .../rpl_rfr_disable_on_expl_pk_absence.result | 47 +++ .../tokudb_rpl/r/rpl_tokudb_mixed_dml.result | 2 + ...l_rfr_disable_on_expl_pk_absence-slave.opt | 1 + .../t/rpl_rfr_disable_on_expl_pk_absence.test | 48 +++ .../r/tokudb_pk_insert_mode_basic.result | 85 ++++++ .../t/tokudb_pk_insert_mode_basic.test | 51 ++++ storage/tokudb/tokudb_sysvars.cc | 38 ++- storage/tokudb/tokudb_sysvars.h | 1 + storage/tokudb/tokudb_thread.h | 49 +++ 77 files changed, 862 insertions(+), 309 deletions(-) create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-24-clean/log000000000000.tokulog24 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-24-dirty/log000000000000.tokulog24 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-25-clean/log000000000000.tokulog25 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-25-dirty/log000000000000.tokulog25 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-26-clean/log000000000000.tokulog26 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-26-dirty/log000000000000.tokulog26 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-27-clean/log000000000000.tokulog27 create mode 100755 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-27-dirty/log000000000000.tokulog27 create mode 100644 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-28-clean/log000000000000.tokulog28 create mode 100644 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-28-dirty/log000000000000.tokulog28 create mode 100644 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-29-clean/log000000000000.tokulog29 create mode 100644 storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-29-dirty/log000000000000.tokulog29 create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/r/db233.result create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/r/db945.result create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/t/db233.test create mode 100644 storage/tokudb/mysql-test/tokudb_bugs/t/db945.test create mode 100644 storage/tokudb/mysql-test/tokudb_rpl/r/rpl_rfr_disable_on_expl_pk_absence.result create mode 100644 storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence-slave.opt create mode 100644 storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence.test create mode 100644 storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_pk_insert_mode_basic.result create mode 100644 storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_pk_insert_mode_basic.test diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt index 7b01c97958f48..b1b5a38fd7582 100644 --- a/storage/tokudb/CMakeLists.txt +++ b/storage/tokudb/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(TOKUDB_VERSION 5.6.29-76.2) +SET(TOKUDB_VERSION 5.6.30-76.3) # PerconaFT only supports x86-64 and cmake-2.8.9+ IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND NOT CMAKE_VERSION VERSION_LESS "2.8.9") @@ -21,7 +21,7 @@ include(CheckCXXCompilerFlag) # pick language dialect check_cxx_compiler_flag(-std=c++11 HAVE_STDCXX11) if (HAVE_STDCXX11) - set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "-std=c++11 -Wno-deprecated-declarations ${CMAKE_CXX_FLAGS}") else () message(FATAL_ERROR "${CMAKE_CXX_COMPILER} doesn't support -std=c++11, you need one that does.") endif () diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake index 87947bb47d233..5f2c9ef2c2aa6 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake @@ -95,8 +95,10 @@ set_cflags_if_supported( -Wno-error=missing-format-attribute -Wno-error=address-of-array-temporary -Wno-error=tautological-constant-out-of-range-compare + -Wno-error=maybe-uninitialized -Wno-ignored-attributes -Wno-error=extern-c-compat + -Wno-pointer-bool-conversion -fno-rtti -fno-exceptions ) @@ -152,13 +154,18 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(CMAKE_C_FLAGS_RELEASE "-g -O3 ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG") else () + if (APPLE) + set(FLTO_OPTS "-fwhole-program") + else () + set(FLTO_OPTS "-fuse-linker-plugin") + endif() # we overwrite this because the default passes -DNDEBUG and we don't want that - set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG") - set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG") - set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}") - set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto ${FLTO_OPTS} ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto ${FLTO_OPTS} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG") + set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto ${FLTO_OPTS} ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto ${FLTO_OPTS} ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG") + set(CMAKE_EXE_LINKER_FLAGS "-g ${FLTO_OPTS} ${CMAKE_EXE_LINKER_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "-g ${FLTO_OPTS} ${CMAKE_SHARED_LINKER_FLAGS}") endif () ## set warnings @@ -192,15 +199,6 @@ endif () set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}") -## need to set -stdlib=libc++ to get real c++11 support on darwin -if (APPLE) - if (CMAKE_GENERATOR STREQUAL Xcode) - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - else () - add_definitions(-stdlib=libc++) - endif () -endif () - # pick language dialect set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}") check_cxx_compiler_flag(-std=c++11 HAVE_STDCXX11) diff --git a/storage/tokudb/PerconaFT/ft/logger/log_upgrade.cc b/storage/tokudb/PerconaFT/ft/logger/log_upgrade.cc index cbe3cc328b43b..efaba49198d9e 100644 --- a/storage/tokudb/PerconaFT/ft/logger/log_upgrade.cc +++ b/storage/tokudb/PerconaFT/ft/logger/log_upgrade.cc @@ -265,8 +265,8 @@ toku_maybe_upgrade_log(const char *env_dir, const char *log_dir, LSN * lsn_of_cl TXNID last_xid = TXNID_NONE; r = verify_clean_shutdown_of_log_version(log_dir, version_of_logs_on_disk, &last_lsn, &last_xid); if (r != 0) { - if (TOKU_LOG_VERSION_25 <= version_of_logs_on_disk && - version_of_logs_on_disk <= TOKU_LOG_VERSION_27 && + if (version_of_logs_on_disk >= TOKU_LOG_VERSION_25 && + version_of_logs_on_disk <= TOKU_LOG_VERSION_29 && TOKU_LOG_VERSION_29 == TOKU_LOG_VERSION) { r = 0; // can do recovery on dirty shutdown } else { diff --git a/storage/tokudb/PerconaFT/ft/logger/recover.h b/storage/tokudb/PerconaFT/ft/logger/recover.h index 0d216c11a8bc1..bdd44d562cdff 100644 --- a/storage/tokudb/PerconaFT/ft/logger/recover.h +++ b/storage/tokudb/PerconaFT/ft/logger/recover.h @@ -67,7 +67,7 @@ int tokuft_recover(DB_ENV *env, // Effect: Check the tokuft logs to determine whether or not we need to run recovery. // If the log is empty or if there is a clean shutdown at the end of the log, then we -// dont need to run recovery. +// don't need to run recovery. // Returns: true if we need recovery, otherwise false. int tokuft_needs_recovery(const char *logdir, bool ignore_empty_log); diff --git a/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt index 0098b6091be6c..270ec97660ac5 100644 --- a/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/ft/tests/CMakeLists.txt @@ -112,11 +112,13 @@ if(BUILD_TESTING OR BUILD_FT_TESTS) declare_custom_tests(test-upgrade-recovery-logs) file(GLOB upgrade_tests "${TOKUDB_DATA}/upgrade-recovery-logs-??-clean") + file(GLOB upgrade_tests "${CMAKE_CURRENT_SOURCE_DIR}/upgrade.data/upgrade-recovery-logs-??-clean") foreach(test ${upgrade_tests}) get_filename_component(test_basename "${test}" NAME) add_ft_test_aux(test-${test_basename} test-upgrade-recovery-logs ${test}) endforeach(test) file(GLOB upgrade_tests "${TOKUDB_DATA}/upgrade-recovery-logs-??-dirty") + file(GLOB upgrade_tests "${CMAKE_CURRENT_SOURCE_DIR}/upgrade.data/upgrade-recovery-logs-??-dirty") foreach(test ${upgrade_tests}) get_filename_component(test_basename "${test}" NAME) add_ft_test_aux(test-${test_basename} test-upgrade-recovery-logs ${test}) diff --git a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc index c83517b5f64ca..761d672539b0c 100644 --- a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc +++ b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc @@ -87,7 +87,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) leafnode->max_msn_applied_to_node_on_disk = msn; - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc index d960825805469..c37dcd089f829 100644 --- a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc +++ b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc @@ -160,7 +160,7 @@ append_leaf(FT_HANDLE ft, FTNODE leafnode, void *key, uint32_t keylen, void *val assert(pair2.call_count==2); } - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/test-upgrade-recovery-logs.cc b/storage/tokudb/PerconaFT/ft/tests/test-upgrade-recovery-logs.cc index 8e006498d7772..7691ffaac2bc2 100644 --- a/storage/tokudb/PerconaFT/ft/tests/test-upgrade-recovery-logs.cc +++ b/storage/tokudb/PerconaFT/ft/tests/test-upgrade-recovery-logs.cc @@ -81,7 +81,7 @@ static void run_recovery(const char *testdir) { bool upgrade_in_progress; r = toku_maybe_upgrade_log(testdir, testdir, &lsn_of_clean_shutdown, &upgrade_in_progress); if (strcmp(shutdown, "dirty") == 0 && log_version <= 24) { - CKERR2(r, TOKUDB_UPGRADE_FAILURE); // we dont support dirty upgrade from versions <= 24 + CKERR2(r, TOKUDB_UPGRADE_FAILURE); // we don't support dirty upgrade from versions <= 24 return; } else { CKERR(r); diff --git a/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-24-clean/log000000000000.tokulog24 b/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-24-clean/log000000000000.tokulog24 new file mode 100755 index 0000000000000000000000000000000000000000..9a56e83e627e84d292cef034924800cdbd720fdc GIT binary patch literal 131 zcmXTP&o0f$PfurHV31G+5*0wqzzD?MjI0d*|GaMn@j<}s_RDP`1-d{S0TN&W5kLS_ h%=8zbc%Ag06(EHm4F(`Z%s>n>krheNKc2T>69F^67f%2H literal 0 HcmV?d00001 diff --git a/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-24-dirty/log000000000000.tokulog24 b/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-24-dirty/log000000000000.tokulog24 new file mode 100755 index 0000000000000000000000000000000000000000..c552cda66731e944c4ee3199b81ba329e503eeb6 GIT binary patch literal 94 zcmXTP&o0f$PfurHV31G+5*0wqzzD?MjI0bb_a)mvd=N0zd-M*ZKo^K3Kmtr40tjG= O>yQ+$z5nt7NFe~}xDTBG literal 0 HcmV?d00001 diff --git a/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-25-clean/log000000000000.tokulog25 b/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-25-clean/log000000000000.tokulog25 new file mode 100755 index 0000000000000000000000000000000000000000..26b8bcfbdcc01db3a4601482c4d3028952d1fb4c GIT binary patch literal 131 zcmXTP&o0f$PfurHV31S=5*0wqzzD?MjI0cg*+l9Ko^K3Kmtr40tjG= g`H>VG*l_296oNDufD|zUF~~$=Bt;V>_JK_V01-A4O8@`> literal 0 HcmV?d00001 diff --git a/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-27-dirty/log000000000000.tokulog27 b/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-27-dirty/log000000000000.tokulog27 new file mode 100755 index 0000000000000000000000000000000000000000..8b658ea4c0a6bb24d7e86af8ee88cecfcdd96825 GIT binary patch literal 94 zcmXTP&o0f$PfurHV31Y?5*0wqzzD?MjI0c)AKvDI_#m)u(&4Ef1-d{S0TN&W5kLS_ OoQ0&=jInJhNFe|$bPsO; literal 0 HcmV?d00001 diff --git a/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-28-clean/log000000000000.tokulog28 b/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-28-clean/log000000000000.tokulog28 new file mode 100644 index 0000000000000000000000000000000000000000..11fecfb94b22fae59dd039f75bee0c849712b893 GIT binary patch literal 131 zcmXTP&o0f$PfurHV31J-5*0wqzzD>_hO7)qNxHj0d=S{5aX_hO7)$TXT1T_#m*k!6gf%Ko^K3Kmtr40tjG= O?U58~3wCFN6aoO!T@65*0wqzzD>_hO7+h_%>bu@j<}Sbn7FK0$m`E00}UG2q1td i-h`xh;kMlmKng(`3_yyQff!`s79>RvclbU8DF6V30Tr15 literal 0 HcmV?d00001 diff --git a/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-29-dirty/log000000000000.tokulog29 b/storage/tokudb/PerconaFT/ft/tests/upgrade.data/upgrade-recovery-logs-29-dirty/log000000000000.tokulog29 new file mode 100644 index 0000000000000000000000000000000000000000..b9e79eeb1c4de6deddb14cd3aa2a8cb7a5aae38f GIT binary patch literal 94 zcmXTP&o0f$PfurHV31V>5*0wqzzD>_hO7+F7XG^c;)8%uZqI3u0$m`E00}UG2q1td Oev71dRpWuvAcX)&5fO0! literal 0 HcmV?d00001 diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc index 40af5dab7ad65..b10885c2e62fe 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc @@ -92,7 +92,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) // Create bad tree (don't do following): // leafnode->max_msn_applied_to_node = msn; - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc index 37054eb119adf..c1d08ce41a6a6 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc @@ -76,7 +76,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) NULL, NULL); - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc index 42e8288443272..22a29c0ff691f 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc @@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) NULL, NULL); - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc index b3e8663ed3ba3..80189dd9804dd 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc @@ -76,7 +76,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) NULL, NULL); - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc index df5c21ca64e16..a84aac1f0638f 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc @@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) NULL, NULL); - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc index 4eccb06c1f352..ca413f52567ff 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc @@ -79,7 +79,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) NULL, NULL); - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc index 4492ea9364a91..6efa06913c2cd 100644 --- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc +++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc @@ -76,7 +76,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen) NULL, NULL); - // dont forget to dirty the node + // don't forget to dirty the node leafnode->dirty = 1; } diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc index 805c60d30beea..88eca36a261b9 100644 --- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc +++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.cc @@ -47,10 +47,10 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #include "util/omt.h" //this is only for testing -static void (* test_txn_sync_callback) (uint64_t, void *) = NULL; +static void (* test_txn_sync_callback) (pthread_t, void *) = NULL; static void * test_txn_sync_callback_extra = NULL; -void set_test_txn_sync_callback(void (*cb) (uint64_t, void *), void *extra) { +void set_test_txn_sync_callback(void (*cb) (pthread_t, void *), void *extra) { test_txn_sync_callback = cb; test_txn_sync_callback_extra = extra; } diff --git a/storage/tokudb/PerconaFT/ft/txn/txn_manager.h b/storage/tokudb/PerconaFT/ft/txn/txn_manager.h index 28fa1ac10b6f9..7cdc52c4f43e8 100644 --- a/storage/tokudb/PerconaFT/ft/txn/txn_manager.h +++ b/storage/tokudb/PerconaFT/ft/txn/txn_manager.h @@ -43,7 +43,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. #include "ft/txn/txn.h" -void set_test_txn_sync_callback(void (*) (uint64_t, void*), void*); +void set_test_txn_sync_callback(void (*) (pthread_t, void*), void*); #define toku_test_txn_sync_callback(a) ((test_txn_sync_callback)? test_txn_sync_callback( a,test_txn_sync_callback_extra) : (void) 0) #if TOKU_DEBUG_TXN_SYNC diff --git a/storage/tokudb/PerconaFT/ftcxx/tests/CMakeLists.txt b/storage/tokudb/PerconaFT/ftcxx/tests/CMakeLists.txt index 8cea16c914d4d..6f9146ce5b231 100644 --- a/storage/tokudb/PerconaFT/ftcxx/tests/CMakeLists.txt +++ b/storage/tokudb/PerconaFT/ftcxx/tests/CMakeLists.txt @@ -2,6 +2,8 @@ include_directories(..) include_directories(../../src) include_directories(../../src/tests) +find_library(JEMALLOC_STATIC_LIBRARY libjemalloc.a) + if (BUILD_TESTING) ## reference implementation with simple size-doubling buffer without ## jemalloc size tricks @@ -24,15 +26,15 @@ if (BUILD_TESTING) cursor_test ) set(_testname ${impl}_${test}) - if (with_jemalloc) + if (with_jemalloc AND JEMALLOC_STATIC_LIBRARY) set(_testname ${_testname}_j) endif () add_executable(${_testname} ${test}) - if (with_jemalloc) + if (with_jemalloc AND JEMALLOC_STATIC_LIBRARY) if (APPLE) - target_link_libraries(${_testname} -Wl,-force_load jemalloc) + target_link_libraries(${_testname} -Wl,-force_load ${JEMALLOC_STATIC_LIBRARY}) else () - target_link_libraries(${_testname} -Wl,--whole-archive jemalloc -Wl,--no-whole-archive) + target_link_libraries(${_testname} -Wl,--whole-archive ${JEMALLOC_STATIC_LIBRARY} -Wl,--no-whole-archive) endif () endif () target_link_libraries(${_testname} ${impl}) diff --git a/storage/tokudb/PerconaFT/scripts/run.stress-tests.py b/storage/tokudb/PerconaFT/scripts/run.stress-tests.py index a8df83a3b55fa..e983fe8ccd908 100755 --- a/storage/tokudb/PerconaFT/scripts/run.stress-tests.py +++ b/storage/tokudb/PerconaFT/scripts/run.stress-tests.py @@ -521,14 +521,16 @@ def email_failure(self, runner, savedtarfile, commands, output): })) def send_mail(toaddrs, subject, body): - m = MIMEText(body) - fromaddr = 'tim@tokutek.com' - m['From'] = fromaddr - m['To'] = ', '.join(toaddrs) - m['Subject'] = subject - s = SMTP('192.168.1.114') - s.sendmail(fromaddr, toaddrs, str(m)) - s.quit() + # m = MIMEText(body) + # fromaddr = 'dev-private@percona.com' + # m['From'] = fromaddr + # m['To'] = ', '.join(toaddrs) + # m['Subject'] = subject + # s = SMTP('192.168.1.114') + # s.sendmail(fromaddr, toaddrs, str(m)) + # s.quit() + info(subject); + info(body); def update(tokudb): info('Updating from git.') @@ -554,12 +556,12 @@ def rebuild(tokudb, builddir, tokudb_data, cc, cxx, tests): env=newenv, cwd=builddir) if r != 0: - send_mail(['leif@tokutek.com'], 'Stress tests on %s failed to build.' % gethostname(), '') + send_mail(['dev-private@percona.com'], 'Stress tests on %s failed to build.' % gethostname(), '') error('Building the tests failed.') sys.exit(r) r = call(['make', '-j8'], cwd=builddir) if r != 0: - send_mail(['leif@tokutek.com'], 'Stress tests on %s failed to build.' % gethostname(), '') + send_mail(['dev-private@percona.com'], 'Stress tests on %s failed to build.' % gethostname(), '') error('Building the tests failed.') sys.exit(r) @@ -671,7 +673,7 @@ def main(opts): sys.exit(0) except Exception, e: exception('Unhandled exception caught in main.') - send_mail(['leif@tokutek.com'], 'Stress tests caught unhandled exception in main, on %s' % gethostname(), format_exc()) + send_mail(['dev-private@percona.com'], 'Stress tests caught unhandled exception in main, on %s' % gethostname(), format_exc()) raise e if __name__ == '__main__': @@ -786,7 +788,7 @@ def main(opts): if not opts.send_emails: opts.email = None elif len(opts.email) == 0: - opts.email.append('tokueng@tokutek.com') + opts.email.append('dev-private@percona.com') if opts.debug: logging.basicConfig(level=logging.DEBUG) diff --git a/storage/tokudb/PerconaFT/src/indexer-undo-do.cc b/storage/tokudb/PerconaFT/src/indexer-undo-do.cc index b93429407ebd7..8d0b080b9fe88 100644 --- a/storage/tokudb/PerconaFT/src/indexer-undo-do.cc +++ b/storage/tokudb/PerconaFT/src/indexer-undo-do.cc @@ -313,7 +313,7 @@ indexer_undo_do_provisional(DB_INDEXER *indexer, DB *hotdb, struct ule_prov_info break; if (outermost_xid_state != TOKUTXN_LIVE && xrindex > num_committed) { - // if the outermost is not live, then the inner state must be retired. thats the way that the txn API works. + // If the outermost is not live, then the inner state must be retired. That's the way that the txn API works. assert(this_xid_state == TOKUTXN_RETIRED); } diff --git a/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc b/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc index 2fc05b23f0d33..f8099c7a639ad 100644 --- a/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc +++ b/storage/tokudb/PerconaFT/src/tests/rollback-inconsistency.cc @@ -54,9 +54,9 @@ populate_table(int start, int end, DB_TXN * parent, DB_ENV * env, DB * db) { char str[220]; memset(kk, 0, sizeof kk); memcpy(kk, &k, sizeof k); - memset(str,'a', sizeof str-1); + memset(str,'a', sizeof str); DBT key = { .data = kk, .size = sizeof kk }; - DBT val = { .data = str, .size = 220 }; + DBT val = { .data = str, .size = sizeof str }; r = db->put(db, txn, &key, &val, 0); assert_zero(r); } diff --git a/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc b/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc index c3ebbd811bb13..c440bdc59e708 100644 --- a/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc +++ b/storage/tokudb/PerconaFT/src/tests/test_db_rowcount.cc @@ -83,7 +83,7 @@ static void add_records(DB* db, DB_TXN* txn, uint64_t start_id, uint64_t num) { for (uint64_t i = 0, j=start_id; i < num; i++,j++) { char key[100], val[256]; DBT k,v; - snprintf(key, 100, "%08lu", j); + snprintf(key, 100, "%08" PRIu64, j); snprintf(val, 256, "%*s", 200, key); r = db->put( @@ -105,7 +105,7 @@ static void delete_records( for (uint64_t i = 0, j=start_id; i < num; i++,j++) { char key[100]; DBT k; - snprintf(key, 100, "%08lu", j); + snprintf(key, 100, "%08" PRIu64, j); r = db->del( db, @@ -143,7 +143,7 @@ static void test_insert_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) - printf("%s : before commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : before commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); r = txn->commit(txn, 0); assert(r == 0); @@ -153,7 +153,7 @@ static void test_insert_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) - printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); db->close(db, 0); } @@ -175,7 +175,7 @@ static void test_insert_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) - printf("%s : before delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : before delete %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); delete_records(db, txn, 0, num_records); @@ -184,7 +184,7 @@ static void test_insert_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) - printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after delete %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); r = txn->commit(txn, 0); assert(r == 0); @@ -194,7 +194,7 @@ static void test_insert_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) - printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); db->close(db, 0); } @@ -217,7 +217,7 @@ static void test_insert_commit_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) printf( - "%s : before insert commit %lu rows\n", + "%s : before insert commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -230,7 +230,7 @@ static void test_insert_commit_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) printf( - "%s : after insert commit %lu rows\n", + "%s : after insert commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -244,7 +244,7 @@ static void test_insert_commit_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) - printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after delete %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); r = txn->commit(txn, 0); assert(r == 0); @@ -255,7 +255,7 @@ static void test_insert_commit_delete_commit(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) printf( - "%s : after delete commit %lu rows\n", + "%s : after delete commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -279,7 +279,7 @@ static void test_insert_rollback(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) - printf("%s : before rollback %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : before rollback %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); r = txn->abort(txn); assert(r == 0); @@ -292,7 +292,7 @@ static void test_insert_rollback(DB_ENV* env) { // MESSAGES ARE "IN-FLIGHT" IN THE TREE AND MUST BE APPLIED IN ORDER TO // CORRECT THE RUNNING LOGICAL COUNT if (verbose) - printf("%s : after rollback %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after rollback %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); full_optimize(db); @@ -302,7 +302,7 @@ static void test_insert_rollback(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) printf( - "%s : after rollback optimize %lu rows\n", + "%s : after rollback optimize %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -326,7 +326,7 @@ static void test_insert_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) - printf("%s : before delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : before delete %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); delete_records(db, txn, 0, num_records); @@ -335,7 +335,7 @@ static void test_insert_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) - printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after delete %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); r = txn->abort(txn); assert(r == 0); @@ -345,7 +345,7 @@ static void test_insert_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) - printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); db->close(db, 0); } @@ -368,7 +368,7 @@ static void test_insert_commit_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) printf( - "%s : before insert commit %lu rows\n", + "%s : before insert commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -381,7 +381,7 @@ static void test_insert_commit_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) printf( - "%s : after insert commit %lu rows\n", + "%s : after insert commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -395,7 +395,7 @@ static void test_insert_commit_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(0, stats); if (verbose) - printf("%s : after delete %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after delete %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); r = txn->abort(txn); assert(r == 0); @@ -409,7 +409,7 @@ static void test_insert_commit_delete_rollback(DB_ENV* env) { // CORRECT THE RUNNING LOGICAL COUNT if (verbose) printf( - "%s : after delete rollback %lu rows\n", + "%s : after delete rollback %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -421,17 +421,12 @@ static void test_insert_commit_delete_rollback(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) printf( - "%s : after delete rollback optimize %lu rows\n", + "%s : after delete rollback optimize %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); db->close(db, 0); } -static inline uint64_t time_in_microsec() { - struct timeval t; - gettimeofday(&t, NULL); - return t.tv_sec * (1UL * 1000 * 1000) + t.tv_usec; -} static int test_recount_insert_commit_progress( uint64_t count, @@ -440,7 +435,7 @@ static int test_recount_insert_commit_progress( if (verbose) printf( - "%s : count[%lu] deleted[%lu]\n", + "%s : count[%" PRIu64 "] deleted[%" PRIu64 "]\n", __FUNCTION__, count, deleted); @@ -469,7 +464,7 @@ static void test_recount_insert_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) printf( - "%s : before commit %lu rows\n", + "%s : before commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); @@ -481,7 +476,7 @@ static void test_recount_insert_commit(DB_ENV* env) { CHECK_NUM_ROWS(num_records, stats); if (verbose) - printf("%s : after commit %lu rows\n", __FUNCTION__, stats.bt_ndata); + printf("%s : after commit %" PRIu64 " rows\n", __FUNCTION__, stats.bt_ndata); // test that recount counted correct # of rows r = db->recount_rows(db, test_recount_insert_commit_progress, NULL); diff --git a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc index b55610757e283..30cc16d73a7c5 100644 --- a/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc +++ b/storage/tokudb/PerconaFT/src/tests/txn_manager_handle_snapshot_atomicity.cc @@ -92,19 +92,19 @@ struct start_txn_arg { static struct test_sync sync_s; -static void test_callback(uint64_t self_tid, void * extra) { +static void test_callback(pthread_t self_tid, void * extra) { pthread_t **p = (pthread_t **) extra; pthread_t tid_1 = *p[0]; pthread_t tid_2 = *p[1]; - assert(self_tid == tid_2); - printf("%s: the thread[%" PRIu64 "] is going to wait...\n", __func__, tid_1); + assert(pthread_equal(self_tid, tid_2)); + printf("%s: the thread[%" PRIu64 "] is going to wait...\n", __func__, reinterpret_cast(tid_1)); test_sync_next_state(&sync_s); sleep(3); //test_sync_sleep(&sync_s,3); //using test_sync_sleep/test_sync_next_state pair can sync threads better, however //after the fix, this might cause a deadlock. just simply use sleep to do a proof- //of-concept test. - printf("%s: the thread[%" PRIu64 "] is resuming...\n", __func__, tid_1); + printf("%s: the thread[%" PRIu64 "] is resuming...\n", __func__, reinterpret_cast(tid_1)); return; } @@ -114,7 +114,7 @@ static void * start_txn2(void * extra) { DB * db = args->db; DB_TXN * parent = args->parent; test_sync_sleep(&sync_s, 1); - printf("start %s [thread %" PRIu64 "]\n", __func__, pthread_self()); + printf("start %s [thread %" PRIu64 "]\n", __func__, reinterpret_cast(pthread_self())); DB_TXN *txn; int r = env->txn_begin(env, parent, &txn, DB_READ_COMMITTED); assert(r == 0); @@ -127,7 +127,7 @@ static void * start_txn2(void * extra) { r = txn->commit(txn, 0); assert(r == 0); - printf("%s done[thread %" PRIu64 "]\n", __func__, pthread_self()); + printf("%s done[thread %" PRIu64 "]\n", __func__, reinterpret_cast(pthread_self())); return extra; } @@ -135,14 +135,14 @@ static void * start_txn1(void * extra) { struct start_txn_arg * args = (struct start_txn_arg *) extra; DB_ENV * env = args -> env; DB * db = args->db; - printf("start %s: [thread %" PRIu64 "]\n", __func__, pthread_self()); + printf("start %s: [thread %" PRIu64 "]\n", __func__, reinterpret_cast(pthread_self())); DB_TXN *txn; int r = env->txn_begin(env, NULL, &txn, DB_READ_COMMITTED); assert(r == 0); - printf("%s: txn began by [thread %" PRIu64 "], will wait\n", __func__, pthread_self()); + printf("%s: txn began by [thread %" PRIu64 "], will wait\n", __func__, reinterpret_cast(pthread_self())); test_sync_next_state(&sync_s); test_sync_sleep(&sync_s,2); - printf("%s: [thread %" PRIu64 "] resumed\n", __func__, pthread_self()); + printf("%s: [thread %" PRIu64 "] resumed\n", __func__, reinterpret_cast(pthread_self())); //do some random things... DBT key, data; dbt_init(&key, "hello", 6); @@ -151,7 +151,7 @@ static void * start_txn1(void * extra) { db->get(db, txn, &key, &data, 0); r = txn->commit(txn, 0); assert(r == 0); - printf("%s: done[thread %" PRIu64 "]\n", __func__, pthread_self()); + printf("%s: done[thread %" PRIu64 "]\n", __func__, reinterpret_cast(pthread_self())); //test_sync_next_state(&sync_s); return extra; } diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc index 61ce5a8476e85..55da418a0decd 100644 --- a/storage/tokudb/PerconaFT/src/ydb.cc +++ b/storage/tokudb/PerconaFT/src/ydb.cc @@ -3148,7 +3148,7 @@ toku_test_get_latest_lsn(DB_ENV *env) { return rval.lsn; } -void toku_set_test_txn_sync_callback(void (* cb) (uint64_t, void *), void * extra) { +void toku_set_test_txn_sync_callback(void (* cb) (pthread_t, void *), void * extra) { set_test_txn_sync_callback(cb, extra); } diff --git a/storage/tokudb/PerconaFT/src/ydb.h b/storage/tokudb/PerconaFT/src/ydb.h index bd2902e6c6e58..facbfdc92524f 100644 --- a/storage/tokudb/PerconaFT/src/ydb.h +++ b/storage/tokudb/PerconaFT/src/ydb.h @@ -60,4 +60,4 @@ extern "C" uint64_t toku_test_get_latest_lsn(DB_ENV *env) __attribute__((__visib extern "C" int toku_test_get_checkpointing_user_data_status(void) __attribute__((__visibility__("default"))); // test-only function -extern "C" void toku_set_test_txn_sync_callback(void (* ) (uint64_t, void *), void * extra) __attribute__((__visibility__("default"))); +extern "C" void toku_set_test_txn_sync_callback(void (* ) (pthread_t, void *), void * extra) __attribute__((__visibility__("default"))); diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index d50273dba295e..25f77301696b2 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -462,19 +462,13 @@ static inline bool do_ignore_flag_optimization( bool opt_eligible) { bool do_opt = false; - if (opt_eligible) { - if (is_replace_into(thd) || is_insert_ignore(thd)) { - uint pk_insert_mode = tokudb::sysvars::pk_insert_mode(thd); - if ((!table->triggers && pk_insert_mode < 2) || - pk_insert_mode == 0) { - if (mysql_bin_log.is_open() && - thd->variables.binlog_format != BINLOG_FORMAT_STMT) { - do_opt = false; - } else { - do_opt = true; - } - } - } + if (opt_eligible && + (is_replace_into(thd) || is_insert_ignore(thd)) && + tokudb::sysvars::pk_insert_mode(thd) == 1 && + !table->triggers && + !(mysql_bin_log.is_open() && + thd->variables.binlog_format != BINLOG_FORMAT_STMT)) { + do_opt = true; } return do_opt; } @@ -504,10 +498,7 @@ ulong ha_tokudb::index_flags(uint idx, uint part, bool all_parts) const { TOKUDB_HANDLER_DBUG_ENTER(""); assert_always(table_share); ulong flags = (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | - HA_KEYREAD_ONLY | HA_READ_RANGE); -#if defined(MARIADB_BASE_VERSION) || (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) - flags |= HA_DO_INDEX_COND_PUSHDOWN; -#endif + HA_KEYREAD_ONLY | HA_READ_RANGE | HA_DO_INDEX_COND_PUSHDOWN); if (key_is_clustering(&table_share->key_info[idx])) { flags |= HA_CLUSTERED_INDEX; } @@ -4890,7 +4881,7 @@ int ha_tokudb::read_full_row(uchar * buf) { // HA_ERR_END_OF_FILE if not found // error otherwise // -int ha_tokudb::index_next_same(uchar * buf, const uchar * key, uint keylen) { +int ha_tokudb::index_next_same(uchar* buf, const uchar* key, uint keylen) { TOKUDB_HANDLER_DBUG_ENTER(""); ha_statistic_increment(&SSV::ha_read_next_count); @@ -4908,8 +4899,16 @@ int ha_tokudb::index_next_same(uchar * buf, const uchar * key, uint keylen) { // // now do the comparison // - create_dbt_key_from_table(&found_key,tokudb_active_index,key_buff3,buf,&has_null); - cmp = tokudb_prefix_cmp_dbt_key(share->key_file[tokudb_active_index], &curr_key, &found_key); + create_dbt_key_from_table( + &found_key, + tokudb_active_index, + key_buff3,buf, + &has_null); + cmp = + tokudb_prefix_cmp_dbt_key( + share->key_file[tokudb_active_index], + &curr_key, + &found_key); if (cmp) { error = HA_ERR_END_OF_FILE; } @@ -5168,17 +5167,27 @@ int ha_tokudb::read_data_from_range_query_buff(uchar* buf, bool need_val, bool d return error; } -static int -smart_dbt_bf_callback(DBT const *key, DBT const *row, void *context) { +static int smart_dbt_bf_callback( + DBT const* key, + DBT const* row, + void* context) { SMART_DBT_BF_INFO info = (SMART_DBT_BF_INFO)context; - return info->ha->fill_range_query_buf(info->need_val, key, row, info->direction, info->thd, info->buf, info->key_to_compare); + return + info->ha->fill_range_query_buf( + info->need_val, + key, + row, + info->direction, + info->thd, + info->buf, + info->key_to_compare); } -#if defined(MARIADB_BASE_VERSION) || (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) -enum icp_result ha_tokudb::toku_handler_index_cond_check(Item* pushed_idx_cond) -{ +enum icp_result ha_tokudb::toku_handler_index_cond_check( + Item* pushed_idx_cond) { + enum icp_result res; - if (end_range ) { + if (end_range) { int cmp; #ifdef MARIADB_BASE_VERSION cmp = compare_key2(end_range); @@ -5188,27 +5197,27 @@ enum icp_result ha_tokudb::toku_handler_index_cond_check(Item* pushed_idx_cond) if (cmp > 0) { return ICP_OUT_OF_RANGE; } - } + } res = pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH; return res; } -#endif // fill in the range query buf for bulk fetch int ha_tokudb::fill_range_query_buf( bool need_val, - DBT const *key, - DBT const *row, + DBT const* key, + DBT const* row, int direction, THD* thd, uchar* buf, - DBT* key_to_compare - ) { + DBT* key_to_compare) { + int error; // // first put the value into range_query_buf // - uint32_t size_remaining = size_range_query_buff - bytes_used_in_range_query_buff; + uint32_t size_remaining = + size_range_query_buff - bytes_used_in_range_query_buff; uint32_t size_needed; uint32_t user_defined_size = tokudb::sysvars::read_buf_size(thd); uchar* curr_pos = NULL; @@ -5217,8 +5226,7 @@ int ha_tokudb::fill_range_query_buf( int cmp = tokudb_prefix_cmp_dbt_key( share->key_file[tokudb_active_index], key_to_compare, - key - ); + key); if (cmp) { icp_went_out_of_range = true; error = 0; @@ -5226,26 +5234,38 @@ int ha_tokudb::fill_range_query_buf( } } -#if defined(MARIADB_BASE_VERSION) || (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) // if we have an index condition pushed down, we check it - if (toku_pushed_idx_cond && (tokudb_active_index == toku_pushed_idx_cond_keyno)) { + if (toku_pushed_idx_cond && + (tokudb_active_index == toku_pushed_idx_cond_keyno)) { unpack_key(buf, key, tokudb_active_index); - enum icp_result result = toku_handler_index_cond_check(toku_pushed_idx_cond); + enum icp_result result = + toku_handler_index_cond_check(toku_pushed_idx_cond); + // If we have reason to stop, we set icp_went_out_of_range and get out + // otherwise, if we simply see that the current key is no match, + // we tell the cursor to continue and don't store + // the key locally if (result == ICP_OUT_OF_RANGE || thd_killed(thd)) { icp_went_out_of_range = true; error = 0; + DEBUG_SYNC(ha_thd(), "tokudb_icp_asc_scan_out_of_range"); goto cleanup; - } - // otherwise, if we simply see that the current key is no match, - // we tell the cursor to continue and don't store - // the key locally - else if (result == ICP_NO_MATCH) { + } else if (result == ICP_NO_MATCH) { + // if we are performing a DESC ICP scan and have no end_range + // to compare to stop using ICP filtering as there isn't much more + // that we can do without going through contortions with remembering + // and comparing key parts. + if (!end_range && + direction < 0) { + + cancel_pushed_idx_cond(); + DEBUG_SYNC(ha_thd(), "tokudb_icp_desc_scan_invalidate"); + } + error = TOKUDB_CURSOR_CONTINUE; goto cleanup; } } -#endif // at this point, if ICP is on, we have verified that the key is one // we are interested in, so we proceed with placing the data @@ -5254,57 +5274,63 @@ int ha_tokudb::fill_range_query_buf( if (need_val) { if (unpack_entire_row) { size_needed = 2*sizeof(uint32_t) + key->size + row->size; - } - else { + } else { // this is an upper bound - size_needed = sizeof(uint32_t) + // size of key length - key->size + row->size + //key and row - num_var_cols_for_query*(sizeof(uint32_t)) + //lengths of varchars stored - sizeof(uint32_t); //length of blobs + size_needed = + // size of key length + sizeof(uint32_t) + + // key and row + key->size + row->size + + // lengths of varchars stored + num_var_cols_for_query * (sizeof(uint32_t)) + + // length of blobs + sizeof(uint32_t); } - } - else { + } else { size_needed = sizeof(uint32_t) + key->size; } if (size_remaining < size_needed) { - range_query_buff = (uchar *)tokudb::memory::realloc( - (void *)range_query_buff, - bytes_used_in_range_query_buff+size_needed, - MYF(MY_WME) - ); + range_query_buff = + static_cast(tokudb::memory::realloc( + static_cast(range_query_buff), + bytes_used_in_range_query_buff + size_needed, + MYF(MY_WME))); if (range_query_buff == NULL) { error = ENOMEM; invalidate_bulk_fetch(); goto cleanup; } - size_range_query_buff = bytes_used_in_range_query_buff+size_needed; + size_range_query_buff = bytes_used_in_range_query_buff + size_needed; } // // now we know we have the size, let's fill the buffer, starting with the key // curr_pos = range_query_buff + bytes_used_in_range_query_buff; - *(uint32_t *)curr_pos = key->size; + *reinterpret_cast(curr_pos) = key->size; curr_pos += sizeof(uint32_t); memcpy(curr_pos, key->data, key->size); curr_pos += key->size; if (need_val) { if (unpack_entire_row) { - *(uint32_t *)curr_pos = row->size; + *reinterpret_cast(curr_pos) = row->size; curr_pos += sizeof(uint32_t); memcpy(curr_pos, row->data, row->size); curr_pos += row->size; - } - else { + } else { // need to unpack just the data we care about - const uchar* fixed_field_ptr = (const uchar *) row->data; + const uchar* fixed_field_ptr = static_cast(row->data); fixed_field_ptr += table_share->null_bytes; const uchar* var_field_offset_ptr = NULL; const uchar* var_field_data_ptr = NULL; - var_field_offset_ptr = fixed_field_ptr + share->kc_info.mcp_info[tokudb_active_index].fixed_field_size; - var_field_data_ptr = var_field_offset_ptr + share->kc_info.mcp_info[tokudb_active_index].len_of_offsets; + var_field_offset_ptr = + fixed_field_ptr + + share->kc_info.mcp_info[tokudb_active_index].fixed_field_size; + var_field_data_ptr = + var_field_offset_ptr + + share->kc_info.mcp_info[tokudb_active_index].len_of_offsets; // first the null bytes memcpy(curr_pos, row->data, table_share->null_bytes); @@ -5318,8 +5344,7 @@ int ha_tokudb::fill_range_query_buf( memcpy( curr_pos, fixed_field_ptr + share->kc_info.cp_info[tokudb_active_index][field_index].col_pack_val, - share->kc_info.field_lengths[field_index] - ); + share->kc_info.field_lengths[field_index]); curr_pos += share->kc_info.field_lengths[field_index]; } @@ -5328,7 +5353,8 @@ int ha_tokudb::fill_range_query_buf( // for (uint32_t i = 0; i < num_var_cols_for_query; i++) { uint field_index = var_cols_for_query[i]; - uint32_t var_field_index = share->kc_info.cp_info[tokudb_active_index][field_index].col_pack_val; + uint32_t var_field_index = + share->kc_info.cp_info[tokudb_active_index][field_index].col_pack_val; uint32_t data_start_offset; uint32_t field_len; @@ -5337,11 +5363,13 @@ int ha_tokudb::fill_range_query_buf( &data_start_offset, var_field_index, var_field_offset_ptr, - share->kc_info.num_offset_bytes - ); + share->kc_info.num_offset_bytes); memcpy(curr_pos, &field_len, sizeof(field_len)); curr_pos += sizeof(field_len); - memcpy(curr_pos, var_field_data_ptr + data_start_offset, field_len); + memcpy( + curr_pos, + var_field_data_ptr + data_start_offset, + field_len); curr_pos += field_len; } @@ -5355,9 +5383,12 @@ int ha_tokudb::fill_range_query_buf( &blob_offset, share->kc_info.mcp_info[tokudb_active_index].len_of_offsets, var_field_data_ptr, - share->kc_info.num_offset_bytes - ); - data_size = row->size - blob_offset - (uint32_t)(var_field_data_ptr - (const uchar *)row->data); + share->kc_info.num_offset_bytes); + data_size = + row->size - + blob_offset - + static_cast((var_field_data_ptr - + static_cast(row->data))); memcpy(curr_pos, &data_size, sizeof(data_size)); curr_pos += sizeof(data_size); memcpy(curr_pos, var_field_data_ptr + blob_offset, data_size); @@ -5391,7 +5422,9 @@ int ha_tokudb::fill_range_query_buf( } } - if (bytes_used_in_range_query_buff + table_share->rec_buff_length > user_defined_size) { + if (bytes_used_in_range_query_buff + + table_share->rec_buff_length > + user_defined_size) { error = 0; goto cleanup; } @@ -5409,11 +5442,9 @@ int ha_tokudb::fill_range_query_buf( int cmp = tokudb_cmp_dbt_key( share->key_file[tokudb_active_index], key, - &right_range - ); + &right_range); error = (cmp > 0) ? 0 : TOKUDB_CURSOR_CONTINUE; - } - else { + } else { // compare what we got to the left endpoint of prelocked range // because we are searching keys in descending order if (prelocked_left_range_size == 0) { @@ -5427,15 +5458,19 @@ int ha_tokudb::fill_range_query_buf( int cmp = tokudb_cmp_dbt_key( share->key_file[tokudb_active_index], key, - &left_range - ); + &left_range); error = (cmp < 0) ? 0 : TOKUDB_CURSOR_CONTINUE; } cleanup: return error; } -int ha_tokudb::get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_key_read) { +int ha_tokudb::get_next( + uchar* buf, + int direction, + DBT* key_to_compare, + bool do_key_read) { + int error = 0; HANDLE_INVALID_CURSOR(); @@ -5452,17 +5487,18 @@ int ha_tokudb::get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_ // we need to read the val of what we retrieve if // we do NOT have a covering index AND we are using a clustering secondary // key - bool need_val = (do_key_read == 0) && - (tokudb_active_index == primary_key || key_is_clustering(&table->key_info[tokudb_active_index])); + bool need_val = + (do_key_read == 0) && + (tokudb_active_index == primary_key || + key_is_clustering(&table->key_info[tokudb_active_index])); - if ((bytes_used_in_range_query_buff - curr_range_query_buff_offset) > 0) { + if ((bytes_used_in_range_query_buff - + curr_range_query_buff_offset) > 0) { error = read_data_from_range_query_buff(buf, need_val, do_key_read); - } - else if (icp_went_out_of_range) { + } else if (icp_went_out_of_range) { icp_went_out_of_range = false; error = HA_ERR_END_OF_FILE; - } - else { + } else { invalidate_bulk_fetch(); if (doing_bulk_fetch) { struct smart_dbt_bf_info bf_info; @@ -5483,16 +5519,28 @@ int ha_tokudb::get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_ // this while loop. icp_out_of_range will be set if we hit a row that // the index condition states is out of our range. When that hits, // we know all the data in the buffer is the last data we will retrieve - while (bytes_used_in_range_query_buff == 0 && !icp_went_out_of_range && error == 0) { + while (bytes_used_in_range_query_buff == 0 && + !icp_went_out_of_range && error == 0) { if (direction > 0) { - error = cursor->c_getf_next(cursor, flags, smart_dbt_bf_callback, &bf_info); + error = + cursor->c_getf_next( + cursor, + flags, + smart_dbt_bf_callback, + &bf_info); } else { - error = cursor->c_getf_prev(cursor, flags, smart_dbt_bf_callback, &bf_info); + error = + cursor->c_getf_prev( + cursor, + flags, + smart_dbt_bf_callback, + &bf_info); } } // if there is no data set and we went out of range, // then there is nothing to return - if (bytes_used_in_range_query_buff == 0 && icp_went_out_of_range) { + if (bytes_used_in_range_query_buff == 0 && + icp_went_out_of_range) { icp_went_out_of_range = false; error = HA_ERR_END_OF_FILE; } @@ -5500,26 +5548,46 @@ int ha_tokudb::get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_ bulk_fetch_iteration++; } - error = handle_cursor_error(error, HA_ERR_END_OF_FILE,tokudb_active_index); - if (error) { goto cleanup; } + error = + handle_cursor_error( + error, + HA_ERR_END_OF_FILE, + tokudb_active_index); + if (error) { + goto cleanup; + } // // now that range_query_buff is filled, read an element // - error = read_data_from_range_query_buff(buf, need_val, do_key_read); - } - else { + error = + read_data_from_range_query_buff(buf, need_val, do_key_read); + } else { struct smart_dbt_info info; info.ha = this; info.buf = buf; info.keynr = tokudb_active_index; if (direction > 0) { - error = cursor->c_getf_next(cursor, flags, SMART_DBT_CALLBACK(do_key_read), &info); + error = + cursor->c_getf_next( + cursor, + flags, + SMART_DBT_CALLBACK(do_key_read), + &info); } else { - error = cursor->c_getf_prev(cursor, flags, SMART_DBT_CALLBACK(do_key_read), &info); + error = + cursor->c_getf_prev( + cursor, + flags, + SMART_DBT_CALLBACK(do_key_read), + &info); } - error = handle_cursor_error(error, HA_ERR_END_OF_FILE, tokudb_active_index); + error = + handle_cursor_error( + error, + HA_ERR_END_OF_FILE, + tokudb_active_index); } } } @@ -5532,13 +5600,17 @@ int ha_tokudb::get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_ // read the full row by doing a point query into the // main table. // - if (!error && !do_key_read && (tokudb_active_index != primary_key) && !key_is_clustering(&table->key_info[tokudb_active_index])) { + if (!error && + !do_key_read && + (tokudb_active_index != primary_key) && + !key_is_clustering(&table->key_info[tokudb_active_index])) { error = read_full_row(buf); } if (!error) { THD *thd = ha_thd(); - tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); + tokudb_trx_data* trx = + static_cast(thd_get_ha_data(thd, tokudb_hton)); trx->stmt_progress.queried++; track_progress(thd); if (thd_killed(thd)) @@ -8768,6 +8840,11 @@ Item* ha_tokudb::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) { return idx_cond_arg; } +void ha_tokudb::cancel_pushed_idx_cond() { + invalidate_icp(); + handler::cancel_pushed_idx_cond(); +} + void ha_tokudb::cleanup_txn(DB_TXN *txn) { if (transaction == txn && cursor) { int r = cursor->c_close(cursor); diff --git a/storage/tokudb/ha_tokudb.h b/storage/tokudb/ha_tokudb.h index 91b96425ce5d0..a022edd499e0b 100644 --- a/storage/tokudb/ha_tokudb.h +++ b/storage/tokudb/ha_tokudb.h @@ -903,9 +903,8 @@ class ha_tokudb : public handler { #endif - // ICP introduced in MariaDB 5.5 Item* idx_cond_push(uint keyno, class Item* idx_cond); - + void cancel_pushed_idx_cond(); #if TOKU_INCLUDE_ALTER_56 public: @@ -991,13 +990,13 @@ class ha_tokudb : public handler { int fill_range_query_buf( bool need_val, - DBT const *key, - DBT const *row, + DBT const* key, + DBT const* row, int direction, THD* thd, uchar* buf, - DBT* key_to_compare - ); + DBT* key_to_compare); + #if TOKU_INCLUDE_ROW_TYPE_COMPRESSION enum row_type get_row_type() const; #endif @@ -1007,9 +1006,7 @@ class ha_tokudb : public handler { int get_next(uchar* buf, int direction, DBT* key_to_compare, bool do_key_read); int read_data_from_range_query_buff(uchar* buf, bool need_val, bool do_key_read); // for ICP, only in MariaDB and MySQL 5.6 -#if defined(MARIADB_BASE_VERSION) || (50600 <= MYSQL_VERSION_ID && MYSQL_VERSION_ID <= 50699) enum icp_result toku_handler_index_cond_check(Item* pushed_idx_cond); -#endif void invalidate_bulk_fetch(); void invalidate_icp(); int delete_all_rows_internal(); diff --git a/storage/tokudb/ha_tokudb_admin.cc b/storage/tokudb/ha_tokudb_admin.cc index dad9da8eac605..db3d6c112d499 100644 --- a/storage/tokudb/ha_tokudb_admin.cc +++ b/storage/tokudb/ha_tokudb_admin.cc @@ -612,8 +612,8 @@ int standard_t::analyze_key(uint64_t* rec_per_key_part) { analyze_standard_cursor_callback, this); - memset(&key, 0, sizeof(DBT)); key.flags = DB_DBT_REALLOC; - memset(&prev_key, 0, sizeof(DBT)); prev_key.flags = DB_DBT_REALLOC; + memset(&key, 0, sizeof(DBT)); + memset(&prev_key, 0, sizeof(DBT)); copy_key = true; } @@ -681,7 +681,6 @@ int standard_t::analyze_key(uint64_t* rec_per_key_part) { _key_elapsed_time >= _half_time && _rows < _half_rows)) { - tokudb::memory::free(key.data); key.data = NULL; tokudb::memory::free(prev_key.data); prev_key.data = NULL; close_error = cursor->c_close(cursor); assert_always(close_error == 0); @@ -690,7 +689,6 @@ int standard_t::analyze_key(uint64_t* rec_per_key_part) { } } // cleanup - if (key.data) tokudb::memory::free(key.data); if (prev_key.data) tokudb::memory::free(prev_key.data); if (cursor) close_error = cursor->c_close(cursor); assert_always(close_error == 0); @@ -772,10 +770,11 @@ int TOKUDB_SHARE::analyze_standard(THD* thd, DB_TXN* txn) { int result = HA_ADMIN_OK; // stub out analyze if optimize is remapped to alter recreate + analyze - // when not auto analyze - if (txn && - thd_sql_command(thd) != SQLCOM_ANALYZE && - thd_sql_command(thd) != SQLCOM_ALTER_TABLE) { + // when not auto analyze or if this is an alter + if ((txn && + thd_sql_command(thd) != SQLCOM_ANALYZE && + thd_sql_command(thd) != SQLCOM_ALTER_TABLE) || + thd_sql_command(thd) == SQLCOM_ALTER_TABLE) { TOKUDB_HANDLER_DBUG_RETURN(result); } diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 67151fa67df10..a8876cddcf0f1 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -406,6 +406,16 @@ static int tokudb_init_func(void *p) { db_env->set_errcall(db_env, tokudb_print_error); db_env->set_errpfx(db_env, tokudb_hton_name); + // Handle deprecated options + if (tokudb::sysvars::pk_insert_mode(NULL) != 1) { + TOKUDB_TRACE("Using tokudb_pk_insert_mode is deprecated and the " + "parameter may be removed in future releases. " + "tokudb_pk_insert_mode=0 is now forbidden. " + "See documentation and release notes for details"); + if (tokudb::sysvars::pk_insert_mode(NULL) < 1) + tokudb::sysvars::set_pk_insert_mode(NULL, 1); + } + // // set default comparison functions // diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result index 190581eddae15..6f9592ddc1fc0 100644 --- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result +++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_released.result @@ -10,8 +10,10 @@ select * from information_schema.tokudb_lock_waits; requesting_trx_id blocking_trx_id lock_waits_dname lock_waits_key_left lock_waits_key_right lock_waits_start_time lock_waits_table_schema lock_waits_table_name lock_waits_table_dictionary_name set autocommit=0; set tokudb_prelock_empty=OFF; +set tokudb_lock_timeout=600000; insert into t values (1); set autocommit=0; +set tokudb_lock_timeout=600000; insert into t values (1); select * from information_schema.tokudb_locks; locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name @@ -38,9 +40,11 @@ locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right lo select * from information_schema.tokudb_lock_waits; requesting_trx_id blocking_trx_id lock_waits_dname lock_waits_key_left lock_waits_key_right lock_waits_start_time lock_waits_table_schema lock_waits_table_name lock_waits_table_dictionary_name set autocommit=0; +set tokudb_lock_timeout=600000; set tokudb_prelock_empty=OFF; replace into t values (1); set autocommit=0; +set tokudb_lock_timeout=600000; replace into t values (1); select * from information_schema.tokudb_locks; locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result index 13cdad7a43801..ce8f7d2d7ec5b 100644 --- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result +++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_lock_waits_timeout.result @@ -12,7 +12,9 @@ set autocommit=0; set tokudb_prelock_empty=OFF; insert into t values (1); set autocommit=0; -insert into t values (1); +set tokudb_prelock_empty=OFF; +set tokudb_lock_timeout=60000; +replace into t values (1); select * from information_schema.tokudb_locks; locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000 test t main diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result index a07f7ba52fe25..070f42b30de0c 100644 --- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result +++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks.result @@ -3,8 +3,8 @@ set tokudb_prelock_empty=false; drop table if exists t; create table t (id int primary key); set autocommit=0; -select * from information_schema.tokudb_locks; -locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name +select locks_dname,locks_key_left,locks_key_right,locks_table_schema,locks_table_name,locks_table_dictionary_name from information_schema.tokudb_locks where locks_table_schema='test' and locks_table_name='t' and locks_table_dictionary_name='main' order by locks_key_left, locks_key_right; +locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name insert into t values (1); insert into t values (3); insert into t values (5); @@ -12,17 +12,17 @@ set autocommit=0; insert into t values (2); insert into t values (4); insert into t values (6); -select * from information_schema.tokudb_locks order by locks_trx_id,locks_key_left; -locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name -TRX_ID MYSQL_ID ./test/t-main 0001000000 0001000000 test t main -TRX_ID MYSQL_ID ./test/t-main 0003000000 0003000000 test t main -TRX_ID MYSQL_ID ./test/t-main 0005000000 0005000000 test t main -TRX_ID MYSQL_ID ./test/t-main 0002000000 0002000000 test t main -TRX_ID MYSQL_ID ./test/t-main 0004000000 0004000000 test t main -TRX_ID MYSQL_ID ./test/t-main 0006000000 0006000000 test t main +select locks_dname,locks_key_left,locks_key_right,locks_table_schema,locks_table_name,locks_table_dictionary_name from information_schema.tokudb_locks where locks_table_schema='test' and locks_table_name='t' and locks_table_dictionary_name='main' order by locks_key_left, locks_key_right; +locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name +./test/t-main 0001000000 0001000000 test t main +./test/t-main 0002000000 0002000000 test t main +./test/t-main 0003000000 0003000000 test t main +./test/t-main 0004000000 0004000000 test t main +./test/t-main 0005000000 0005000000 test t main +./test/t-main 0006000000 0006000000 test t main commit; commit; -select * from information_schema.tokudb_locks; -locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name +select locks_dname,locks_key_left,locks_key_right,locks_table_schema,locks_table_name,locks_table_dictionary_name from information_schema.tokudb_locks where locks_table_schema='test' and locks_table_name='t' and locks_table_dictionary_name='main' order by locks_key_left, locks_key_right; +locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name commit; drop table t; diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result index 0a5862e9322b5..aa58437fc69f9 100644 --- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result +++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_locks_released.result @@ -9,6 +9,8 @@ set autocommit=0; set tokudb_prelock_empty=OFF; insert into t values (1); set autocommit=0; +set tokudb_prelock_empty=OFF; +set tokudb_lock_timeout=600000; insert into t values (1); select * from information_schema.tokudb_locks; locks_trx_id locks_mysql_thread_id locks_dname locks_key_left locks_key_right locks_table_schema locks_table_name locks_table_dictionary_name diff --git a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_trx.result b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_trx.result index 63e4816e16e9a..3a9a936a7a6f2 100644 --- a/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_trx.result +++ b/storage/tokudb/mysql-test/tokudb/r/i_s_tokudb_trx.result @@ -1,23 +1,26 @@ set default_storage_engine='tokudb'; set tokudb_prelock_empty=false; drop table if exists t; -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); trx_id trx_mysql_thread_id set autocommit=0; create table t (id int primary key); insert into t values (1); -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; -trx_id trx_mysql_thread_id -TXN_ID_DEFAULT CLIENT_ID_DEFAULT +select count(trx_mysql_thread_id) from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); +count(trx_mysql_thread_id) +1 commit; -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); trx_id trx_mysql_thread_id set autocommit=0; insert into t values (2); -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; -trx_id trx_mysql_thread_id -TXN_ID_A CLIENT_ID_A +select count(trx_mysql_thread_id) from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); +count(trx_mysql_thread_id) +1 +select count(trx_mysql_thread_id) from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); +count(trx_mysql_thread_id) +0 commit; -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); trx_id trx_mysql_thread_id drop table t; diff --git a/storage/tokudb/mysql-test/tokudb/t/disabled.def b/storage/tokudb/mysql-test/tokudb/t/disabled.def index 36e63bddab044..f7413a0edc5db 100644 --- a/storage/tokudb/mysql-test/tokudb/t/disabled.def +++ b/storage/tokudb/mysql-test/tokudb/t/disabled.def @@ -2,25 +2,27 @@ mvcc-19: tokutek mvcc-20: tokutek mvcc-27: tokutek storage_engine_default: tokudb is not the default storage engine -fast_update_blobs : https://tokutek.atlassian.net/browse/DB-871 +fast_update_binlog_mixed : https://tokutek.atlassian.net/browse/DB-871 +fast_update_binlog_row : https://tokutek.atlassian.net/browse/DB-871 +fast_update_binlog_statement : https://tokutek.atlassian.net/browse/DB-871 fast_update_blobs_fixed_varchar : https://tokutek.atlassian.net/browse/DB-871 +fast_update_blobs : https://tokutek.atlassian.net/browse/DB-871 fast_update_blobs_with_varchar : https://tokutek.atlassian.net/browse/DB-871 fast_update_char : https://tokutek.atlassian.net/browse/DB-871 -fast_update_decr_floor : https://tokutek.atlassian.net/browse/DB-871 -fast_update_int : https://tokutek.atlassian.net/browse/DB-871 -fast_update_int_bounds : https://tokutek.atlassian.net/browse/DB-871 -fast_update_uint_bounds : https://tokutek.atlassian.net/browse/DB-871 -fast_update_varchar : https://tokutek.atlassian.net/browse/DB-871 -fast_upsert_char : https://tokutek.atlassian.net/browse/DB-871 -fast_upsert_int : https://tokutek.atlassian.net/browse/DB-871 -fast_update_binlog_statement : https://tokutek.atlassian.net/browse/DB-871 fast_update_deadlock : https://tokutek.atlassian.net/browse/DB-871 -fast_update_error : https://tokutek.atlassian.net/browse/DB-871 +fast_update_decr_floor : https://tokutek.atlassian.net/browse/DB-871 fast_update_disable_slow_update : https://tokutek.atlassian.net/browse/DB-871 +fast_update_error : https://tokutek.atlassian.net/browse/DB-871 +fast_update_int_bounds : https://tokutek.atlassian.net/browse/DB-871 +fast_update_int : https://tokutek.atlassian.net/browse/DB-871 fast_update_key : https://tokutek.atlassian.net/browse/DB-871 fast_update_sqlmode : https://tokutek.atlassian.net/browse/DB-871 +fast_update_uint_bounds : https://tokutek.atlassian.net/browse/DB-871 +fast_update_varchar : https://tokutek.atlassian.net/browse/DB-871 fast_upsert_bin_pad : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_char : https://tokutek.atlassian.net/browse/DB-871 fast_upsert_deadlock : https://tokutek.atlassian.net/browse/DB-871 +fast_upsert_int : https://tokutek.atlassian.net/browse/DB-871 fast_upsert_key : https://tokutek.atlassian.net/browse/DB-871 fast_upsert_sqlmode : https://tokutek.atlassian.net/browse/DB-871 fast_upsert_values : https://tokutek.atlassian.net/browse/DB-871 diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test index bd2257fbaed95..1e9eecb98cfbf 100644 --- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test +++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test @@ -20,10 +20,12 @@ select * from information_schema.tokudb_lock_waits; connect (conn_a,localhost,root,,); set autocommit=0; set tokudb_prelock_empty=OFF; # disable the bulk loader +set tokudb_lock_timeout=600000; # set lock wait timeout to 10 minutes insert into t values (1); connect (conn_b,localhost,root,,); set autocommit=0; +set tokudb_lock_timeout=600000; # set lock wait timeout to 10 minutes send insert into t values (1); # should find the presence of a lock on 1st transaction @@ -69,11 +71,13 @@ select * from information_schema.tokudb_lock_waits; connect (conn_a,localhost,root,,); set autocommit=0; +set tokudb_lock_timeout=600000; # set lock wait timeout to 10 minutes set tokudb_prelock_empty=OFF; # disable the bulk loader replace into t values (1); connect (conn_b,localhost,root,,); set autocommit=0; +set tokudb_lock_timeout=600000; # set lock wait timeout to 10 minutes send replace into t values (1); # should find the presence of a lock on 1st transaction diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test index 06923d4ca5852..42fb548814f23 100644 --- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test +++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_timeout.test @@ -21,11 +21,14 @@ insert into t values (1); connect (conn_b,localhost,root,,); set autocommit=0; -send insert into t values (1); +set tokudb_prelock_empty=OFF; +set tokudb_lock_timeout=60000; # set lock wait timeout to 1 minute + +send replace into t values (1); # should find the presence of a lock on 1st transaction connection default; -let $wait_condition= select count(*)=1 from information_schema.processlist where info='insert into t values (1)' and state='update'; +let $wait_condition= select count(*)=1 from information_schema.processlist where info='replace into t values (1)' and state='update'; source include/wait_condition.inc; real_sleep 1; # delay a little to shorten the update -> write row -> lock wait race @@ -41,7 +44,9 @@ replace_column 1 TRX_ID 2 MYSQL_ID; select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; connection conn_a; -sleep 5; # sleep longer than the lock timer to force a lock timeout on txn_b +real_sleep 45; # sleep till we get close to timeout since wait_condidion will timeout @ 30 seconds +let $wait_condition= select count(*)=0 from information_schema.processlist where info='replace into t values (1)' and state='update'; +source include/wait_condition.inc; commit; # verify that the lock on the 1st transaction is released and replaced by the lock for the 2nd transaction diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test index e5a67559b1a51..8f205ad7f4566 100644 --- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test +++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks.test @@ -12,7 +12,7 @@ set autocommit=0; let $default_id=`select connection_id()`; # should be empty -select * from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right,locks_table_schema,locks_table_name,locks_table_dictionary_name from information_schema.tokudb_locks where locks_table_schema='test' and locks_table_name='t' and locks_table_dictionary_name='main' order by locks_key_left, locks_key_right; insert into t values (1); insert into t values (3); @@ -28,8 +28,7 @@ insert into t values (6); # should find 3 locks for 2 transactions connection default; -replace_column 1 TRX_ID 2 MYSQL_ID; -eval select * from information_schema.tokudb_locks order by locks_trx_id,locks_key_left; +eval select locks_dname,locks_key_left,locks_key_right,locks_table_schema,locks_table_name,locks_table_dictionary_name from information_schema.tokudb_locks where locks_table_schema='test' and locks_table_name='t' and locks_table_dictionary_name='main' order by locks_key_left, locks_key_right; connection conn_a; commit; @@ -37,9 +36,9 @@ connection default; commit; # should be empty -select * from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right,locks_table_schema,locks_table_name,locks_table_dictionary_name from information_schema.tokudb_locks where locks_table_schema='test' and locks_table_name='t' and locks_table_dictionary_name='main' order by locks_key_left, locks_key_right; commit; disconnect conn_a; -drop table t; \ No newline at end of file +drop table t; diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test index 4d6542446828f..52a40e470ab43 100644 --- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test +++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test @@ -22,6 +22,8 @@ insert into t values (1); connect (conn_b,localhost,root,,); set autocommit=0; +set tokudb_prelock_empty=OFF; +set tokudb_lock_timeout=600000; # set lock wait timeout to 10 minutes send insert into t values (1); diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_trx.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_trx.test index d3c2636ba545f..517280391c44b 100644 --- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_trx.test +++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_trx.test @@ -8,35 +8,32 @@ drop table if exists t; enable_warnings; # should be empty -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); # should have my txn -let $default_id=`select connection_id()`; set autocommit=0; create table t (id int primary key); insert into t values (1); -replace_column 1 TXN_ID_DEFAULT 2 CLIENT_ID_DEFAULT; -eval select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select count(trx_mysql_thread_id) from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); # should be empty commit; -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); connect(conn_a,localhost,root,,); -let a_id=`select connection_id()`; set autocommit=0; insert into t values (2); +select count(trx_mysql_thread_id) from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); connection default; -replace_column 1 TXN_ID_A 2 CLIENT_ID_A; -eval select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select count(trx_mysql_thread_id) from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); connection conn_a; commit; connection default; # should be empty -select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx; +select trx_id,trx_mysql_thread_id from information_schema.tokudb_trx where trx_mysql_thread_id in(connection_id()); disconnect conn_a; -drop table t; \ No newline at end of file +drop table t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/5585.result b/storage/tokudb/mysql-test/tokudb_bugs/r/5585.result index 608afa00370a7..1008764148b60 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/5585.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/5585.result @@ -10,12 +10,6 @@ insert into t1 select t1.file_id+40, t1.file_number+40 from t1; insert into t1 select t1.file_id+100, t1.file_number+100 from t1; insert into t1 select t1.file_id+200, t1.file_number+200 from t1; insert into t1 select t1.file_id+400, t1.file_number+400 from t1; -insert into t1 select t1.file_id+1000, t1.file_number+1000 from t1; -insert into t1 select t1.file_id+10000, t1.file_number+10000 from t1; -insert into t1 select t1.file_id+100000, t1.file_number+100000 from t1; -insert into t1 select t1.file_id+1000000, t1.file_number+1000000 from t1; -insert into t1 select t1.file_id+10000000, t1.file_number+10000000 from t1; -insert into t1 select t1.file_id+100000000, t1.file_number+100000000 from t1; create table t2 ( file_id bigint unsigned not null, country char(2) not null, diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db233.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db233.result new file mode 100644 index 0000000000000..e5808f52e6958 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db233.result @@ -0,0 +1,37 @@ +SET SESSION tokudb_auto_analyze = 0; +SET SESSION tokudb_analyze_in_background = 0; +CREATE TABLE t1( +`id` int(10) unsigned NOT NULL, +`k` int(10) unsigned NOT NULL DEFAULT '0', +`c` char(120) NOT NULL DEFAULT '', +`pad` char(60) NOT NULL DEFAULT '', +KEY `xid` (`id`), +KEY `k` (`k`) +) ENGINE=TokuDB DEFAULT CHARSET=latin1; +INSERT INTO t1 VALUES(1, 1, '1', '1'), (2, 2, '2', '2'), (3, 3, '3', '3'), (4, 4, '4', '4'), +(5, 5, '5', '5'), (6, 6, '6', '6'), (6, 6, '6', '6'), (7, 7, '7', '7'), +(8, 8, '8', '8'), (9, 9, '9', '9'), (10, 10, '10', '10'), (11, 11, '11', '11'); +ANALYZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +set DEBUG_SYNC = 'tokudb_icp_desc_scan_invalidate SIGNAL hit1 WAIT_FOR done1'; +SELECT c FROM t1 WHERE id BETWEEN 5 AND 8 ORDER BY id DESC; +set DEBUG_SYNC = 'now WAIT_FOR hit1'; +set DEBUG_SYNC = 'now SIGNAL done1'; +c +8 +7 +6 +6 +5 +set DEBUG_SYNC = 'tokudb_icp_asc_scan_out_of_range SIGNAL hit2 WAIT_FOR done2'; +SELECT c FROM t1 WHERE id BETWEEN 5 AND 8 ORDER BY id ASC; +set DEBUG_SYNC = 'now WAIT_FOR hit2'; +set DEBUG_SYNC = 'now SIGNAL done2'; +c +5 +6 +6 +7 +8 +drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db397_delete_trigger.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_delete_trigger.result index da82fa445e877..c8565fb4b2bc2 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db397_delete_trigger.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_delete_trigger.result @@ -25,11 +25,11 @@ select col1,action from t1_audit; col1 action 0 DUMMY 1 BEFORE DEL -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; locks_dname locks_key_left locks_key_right -./test/t1_audit-main 0200000000000000 0200000000000000 -./test/t1-main ff01000000 0101000000 ./test/t1-main 0001000000 0001000000 +./test/t1-main ff01000000 0101000000 +./test/t1_audit-main 0200000000000000 0200000000000000 commit; drop trigger t1_trigger; create trigger t1_trigger after delete on t1 @@ -46,11 +46,11 @@ col1 action 0 DUMMY 1 BEFORE DEL 2 AFTER DELE -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; locks_dname locks_key_left locks_key_right -./test/t1_audit-main 0300000000000000 0300000000000000 -./test/t1-main ff02000000 0102000000 ./test/t1-main 0002000000 0002000000 +./test/t1-main ff02000000 0102000000 +./test/t1_audit-main 0300000000000000 0300000000000000 commit; drop trigger t1_trigger; drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db397_insert_trigger.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_insert_trigger.result index 41765a6fcd3d9..aef99a9adcd80 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db397_insert_trigger.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_insert_trigger.result @@ -25,10 +25,10 @@ select col1,action from t1_audit; col1 action 0 DUMMY 1 BEFORE INSERT -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; locks_dname locks_key_left locks_key_right -./test/t1_audit-main 0200000000000000 0200000000000000 ./test/t1-main 0001000000 0001000000 +./test/t1_audit-main 0200000000000000 0200000000000000 commit; drop trigger t1_trigger; create trigger t1_trigger after insert on t1 @@ -46,10 +46,10 @@ col1 action 0 DUMMY 1 BEFORE INSERT 2 AFTER INSERT -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; locks_dname locks_key_left locks_key_right -./test/t1_audit-main 0300000000000000 0300000000000000 ./test/t1-main 0002000000 0002000000 +./test/t1_audit-main 0300000000000000 0300000000000000 commit; drop trigger t1_trigger; drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db397_update_trigger.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_update_trigger.result index c197430ad253c..d9b944d3849ff 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db397_update_trigger.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db397_update_trigger.result @@ -25,11 +25,11 @@ select col1,action from t1_audit; col1 action 0 DUMMY 1 BEFORE UPDATE -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; locks_dname locks_key_left locks_key_right -./test/t1_audit-main 0200000000000000 0200000000000000 -./test/t1-main ff01000000 0101000000 ./test/t1-main 0001000000 0001000000 +./test/t1-main ff01000000 0101000000 +./test/t1_audit-main 0200000000000000 0200000000000000 commit; drop trigger t1_trigger; create trigger t1_trigger after update on t1 @@ -48,11 +48,11 @@ col1 action 0 DUMMY 1 BEFORE UPDATE 2 AFTER UPDATE -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; locks_dname locks_key_left locks_key_right -./test/t1_audit-main 0300000000000000 0300000000000000 -./test/t1-main ff02000000 0102000000 ./test/t1-main 0002000000 0002000000 +./test/t1-main ff02000000 0102000000 +./test/t1_audit-main 0300000000000000 0300000000000000 commit; drop trigger t1_trigger; drop table t1, t1_audit; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db739_replace.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db739_replace.result index 2bf141add9ae0..58a4ed6708a23 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db739_replace.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db739_replace.result @@ -100010,5 +100010,7 @@ insert into t (id,a) values (999,98); insert into t (id,a) values (999,99); delete from t where id=404; set tokudb_pk_insert_mode=2; +Warnings: +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. replace into t values (404,0,0,0); drop table t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result index aa207e448071f..623378026883a 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result @@ -15,7 +15,7 @@ test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 5 NULL NULL BTREE -t 1 x 1 x A 2 NULL NULL YES BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE t 1 y 1 y A 5 NULL NULL YES BTREE alter table t analyze partition p1; Table Op Msg_type Msg_text @@ -23,13 +23,13 @@ test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 5 NULL NULL BTREE -t 1 x 1 x A 2 NULL NULL YES BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE t 1 y 1 y A 5 NULL NULL YES BTREE insert into t values (100,1,1),(200,2,1),(300,3,1),(400,4,1),(500,5,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 9 NULL NULL BTREE -t 1 x 1 x A 4 NULL NULL YES BTREE +t 1 x 1 x A 9 NULL NULL YES BTREE t 1 y 1 y A 9 NULL NULL YES BTREE alter table t analyze partition p0; Table Op Msg_type Msg_text @@ -46,5 +46,5 @@ show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t 0 PRIMARY 1 id A 9 NULL NULL BTREE t 1 x 1 x A 9 NULL NULL YES BTREE -t 1 y 1 y A 4 NULL NULL YES BTREE +t 1 y 1 y A 9 NULL NULL YES BTREE drop table t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result new file mode 100644 index 0000000000000..b576ce3150d17 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result @@ -0,0 +1,12 @@ +set default_storage_engine='tokudb'; +drop table if exists t1; +set session tokudb_auto_analyze = 1; +set session tokudb_analyze_in_background = true; +set session tokudb_analyze_mode = TOKUDB_ANALYZE_STANDARD; +set session tokudb_analyze_throttle = 0; +set session tokudb_analyze_time = 0; +create table t1(a int, b text(1), c text(1), filler text(1), primary key(a, b(1)), unique key (a, c(1))); +lock tables t1 write, t1 as a read, t1 as b read; +insert into t1(a) values(1); +alter table t1 drop key a; +unlock tables; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result index 2975d7d311626..6cc499389bb77 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result @@ -110,7 +110,7 @@ a b c d e 5 1 10 NULL NULL show status like '%Handler_read_prev%'; Variable_name Value -Handler_read_prev 41 +Handler_read_prev 799 flush status; show status like '%Handler_read_prev%'; Variable_name Value @@ -142,7 +142,7 @@ a b c d e 20 1 10 NULL NULL show status like '%Handler_read_prev%'; Variable_name Value -Handler_read_prev 21 +Handler_read_prev 399 flush status; show status like '%Handler_read_next%'; Variable_name Value diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/5585.test b/storage/tokudb/mysql-test/tokudb_bugs/t/5585.test index 6cc5fb223c03d..2489748dfa1d8 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/5585.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/5585.test @@ -19,12 +19,6 @@ insert into t1 select t1.file_id+40, t1.file_number+40 from t1; insert into t1 select t1.file_id+100, t1.file_number+100 from t1; insert into t1 select t1.file_id+200, t1.file_number+200 from t1; insert into t1 select t1.file_id+400, t1.file_number+400 from t1; -insert into t1 select t1.file_id+1000, t1.file_number+1000 from t1; -insert into t1 select t1.file_id+10000, t1.file_number+10000 from t1; -insert into t1 select t1.file_id+100000, t1.file_number+100000 from t1; -insert into t1 select t1.file_id+1000000, t1.file_number+1000000 from t1; -insert into t1 select t1.file_id+10000000, t1.file_number+10000000 from t1; -insert into t1 select t1.file_id+100000000, t1.file_number+100000000 from t1; create table t2 ( file_id bigint unsigned not null, diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db233.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db233.test new file mode 100644 index 0000000000000..8e4c3b73c090f --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db233.test @@ -0,0 +1,70 @@ +# This test for DB-233 tests that icp descending range scans stop properly once +# it fails to find a key match instead of continuing to scan all the way to the +# beginning of the index. + +-- source include/have_tokudb.inc +-- source include/have_debug.inc +-- source include/have_debug_sync.inc + +-- enable_query_log + +SET SESSION tokudb_auto_analyze = 0; +SET SESSION tokudb_analyze_in_background = 0; + +CREATE TABLE t1( + `id` int(10) unsigned NOT NULL, + `k` int(10) unsigned NOT NULL DEFAULT '0', + `c` char(120) NOT NULL DEFAULT '', + `pad` char(60) NOT NULL DEFAULT '', + KEY `xid` (`id`), + KEY `k` (`k`) +) ENGINE=TokuDB DEFAULT CHARSET=latin1; + +INSERT INTO t1 VALUES(1, 1, '1', '1'), (2, 2, '2', '2'), (3, 3, '3', '3'), (4, 4, '4', '4'), +(5, 5, '5', '5'), (6, 6, '6', '6'), (6, 6, '6', '6'), (7, 7, '7', '7'), +(8, 8, '8', '8'), (9, 9, '9', '9'), (10, 10, '10', '10'), (11, 11, '11', '11'); + +ANALYZE TABLE t1; + +# lets flip to another connection +connect(conn1, localhost, root); + +# set up the DEBUG_SYNC point +set DEBUG_SYNC = 'tokudb_icp_desc_scan_invalidate SIGNAL hit1 WAIT_FOR done1'; + +# send the query +send SELECT c FROM t1 WHERE id BETWEEN 5 AND 8 ORDER BY id DESC; + +# back to default connection +connection default; + +# wait for the ICP reverse scan to invalidate +set DEBUG_SYNC = 'now WAIT_FOR hit1'; + +# lets release and clean up +set DEBUG_SYNC = 'now SIGNAL done1'; + +connection conn1; +reap; + +# set up the DEBUG_SYNC point again, but for the out of range +set DEBUG_SYNC = 'tokudb_icp_asc_scan_out_of_range SIGNAL hit2 WAIT_FOR done2'; + +# send the query +send SELECT c FROM t1 WHERE id BETWEEN 5 AND 8 ORDER BY id ASC; + +# back to default connection +connection default; + +# wait for the ICP reverse scan to invalidate +set DEBUG_SYNC = 'now WAIT_FOR hit2'; + +# lets release and clean up +set DEBUG_SYNC = 'now SIGNAL done2'; + +connection conn1; +reap; + +connection default; +disconnect conn1; +drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db397_delete_trigger.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_delete_trigger.test index 00751ed23460a..7904366460770 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/db397_delete_trigger.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_delete_trigger.test @@ -28,7 +28,7 @@ start transaction; delete from t1 where col1 = 1; select col1,col2 from t1; select col1,action from t1_audit; -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; # note the locks on t1 and t1_audit commit; drop trigger t1_trigger; @@ -41,10 +41,10 @@ start transaction; delete from t1 where col1 = 2; select col1,col2 from t1; select col1,action from t1_audit; -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; # note the locks on t1 and t1_audit commit; drop trigger t1_trigger; drop table t1; -drop table t1_audit; \ No newline at end of file +drop table t1_audit; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db397_insert_trigger.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_insert_trigger.test index f32496e524dd5..ffe2face9f2b9 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/db397_insert_trigger.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_insert_trigger.test @@ -27,7 +27,7 @@ start transaction; insert into t1 (col1, col2) values (1,1); select col1,col2 from t1; select col1,action from t1_audit; -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; # note the locks on t1 and t1_audit commit; drop trigger t1_trigger; @@ -39,10 +39,10 @@ start transaction; insert into t1 (col1, col2) values (2,2); select col1,col2 from t1; select col1,action from t1_audit; -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; # note the locks on t1 and t1_audit commit; drop trigger t1_trigger; drop table t1; -drop table t1_audit; \ No newline at end of file +drop table t1_audit; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db397_update_trigger.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_update_trigger.test index f1407e6488a58..063a88cb4abb2 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/db397_update_trigger.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db397_update_trigger.test @@ -29,7 +29,7 @@ start transaction; update t1 set col2=1000 where col1 = 1; select col1,col2 from t1; select col1,action from t1_audit; -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; # check locks on t1 and t1_audit commit; drop trigger t1_trigger; @@ -43,7 +43,7 @@ start transaction; update t1 set col2=1001 where col1 = 2; select col1,col2 from t1; select col1,action from t1_audit; -select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks; +select locks_dname,locks_key_left,locks_key_right from information_schema.tokudb_locks order by locks_dname,locks_key_left,locks_key_right; # check locks on t1 and t1_audit commit; drop trigger t1_trigger; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db945.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db945.test new file mode 100644 index 0000000000000..27b0d284484d2 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db945.test @@ -0,0 +1,24 @@ +source include/have_tokudb.inc; +set default_storage_engine='tokudb'; +disable_warnings; +drop table if exists t1; +enable_warnings; + +set session tokudb_auto_analyze = 1; +set session tokudb_analyze_in_background = true; +set session tokudb_analyze_mode = TOKUDB_ANALYZE_STANDARD; +set session tokudb_analyze_throttle = 0; +set session tokudb_analyze_time = 0; + +create table t1(a int, b text(1), c text(1), filler text(1), primary key(a, b(1)), unique key (a, c(1))); +lock tables t1 write, t1 as a read, t1 as b read; +insert into t1(a) values(1); +alter table t1 drop key a; +unlock tables; + +# wait for the bjm queue to empty +-- disable_query_log +let $wait_condition=select count(*)=0 from information_schema.tokudb_background_job_status; +-- source include/wait_condition.inc + +drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_parts/t/disabled.def b/storage/tokudb/mysql-test/tokudb_parts/t/disabled.def index 68d7693612ff9..90e599cd0353e 100644 --- a/storage/tokudb/mysql-test/tokudb_parts/t/disabled.def +++ b/storage/tokudb/mysql-test/tokudb_parts/t/disabled.def @@ -1,4 +1,2 @@ partition_basic_symlink_tokudb : tokudb_file_per_table is not supported partition_reorganize_tokudb : tokudb_file_per_table is not supported -partition_mgm_lc0_tokudb : https://tokutek.atlassian.net/browse/DB-637 -partition_mgm_lc1_tokudb : https://tokutek.atlassian.net/browse/DB-637 diff --git a/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_rfr_disable_on_expl_pk_absence.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_rfr_disable_on_expl_pk_absence.result new file mode 100644 index 0000000000000..981a833aea5db --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_rfr_disable_on_expl_pk_absence.result @@ -0,0 +1,47 @@ +include/master-slave.inc +Warnings: +Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. +Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. +[connection master] +call mtr.add_suppression("read free replication is disabled for tokudb table"); +CREATE TABLE t (a int(11), b char(20)) ENGINE = TokuDB; +INSERT INTO t (a, b) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'); +SELECT * FROM t; +a b +1 a +2 b +3 c +4 d +5 e +UPDATE t SET a = a + 10 WHERE b = 'b'; +SELECT * FROM t; +a b +1 a +12 b +3 c +4 d +5 e +SELECT * FROM t; +a b +1 a +12 b +3 c +4 d +5 e +UPDATE t SET a = a + 10 WHERE b = 'b'; +SELECT * FROM t; +a b +1 a +22 b +3 c +4 d +5 e +SELECT * FROM t; +a b +1 a +22 b +3 c +4 d +5 e +DROP TABLE t; +include/rpl_end.inc diff --git a/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_dml.result b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_dml.result index c11ae61b3caa7..ba9c06106cab3 100644 --- a/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_dml.result +++ b/storage/tokudb/mysql-test/tokudb_rpl/r/rpl_tokudb_mixed_dml.result @@ -1,4 +1,6 @@ SET SESSION tokudb_pk_insert_mode = 2; +Warnings: +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. include/master-slave.inc Warnings: Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. diff --git a/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence-slave.opt b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence-slave.opt new file mode 100644 index 0000000000000..fb12af6c5bd2c --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence-slave.opt @@ -0,0 +1 @@ +--read-only=true --tokudb-rpl-unique-checks=false --tokudb-rpl-lookup-rows=false diff --git a/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence.test b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence.test new file mode 100644 index 0000000000000..67e77c1511c02 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_rpl/t/rpl_rfr_disable_on_expl_pk_absence.test @@ -0,0 +1,48 @@ +# Test case for bug#1536663 +# +# When read-free-replication is enabled for tokudb and there is no explicit +# pk for replicated table there can be dublicated records in the table on +# update operation. +# +# Consider this update operation: +# UPDATE t SET a = a + 10 WHERE b = 'b'; +# The master does rows lookup and updates the rows which values correspond to +# the condition. The update events are written to binary log with +# rows values from the master. As rows lookup is forbidden for slave +# the new rows are added instead of updating corresponding rows. +# +# Without the fix there will be several rows with b = 'b' in the table on slave +# instead of one updated row. +# + +--source include/have_tokudb.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +call mtr.add_suppression("read free replication is disabled for tokudb table"); + +--connection master +CREATE TABLE t (a int(11), b char(20)) ENGINE = TokuDB; +INSERT INTO t (a, b) VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e'); + +--sync_slave_with_master +--sorted_result +SELECT * FROM t; + +--let $i = 2 +--while($i) { + --dec $i + --connection master + UPDATE t SET a = a + 10 WHERE b = 'b'; + --sorted_result + SELECT * FROM t; + --sync_slave_with_master + --sorted_result + SELECT * FROM t; +} + +--connection master +DROP TABLE t; +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_pk_insert_mode_basic.result b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_pk_insert_mode_basic.result new file mode 100644 index 0000000000000..268c403262694 --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_sys_vars/r/tokudb_pk_insert_mode_basic.result @@ -0,0 +1,85 @@ +SET @orig_global = @@global.tokudb_pk_insert_mode; +SELECT @orig_global; +@orig_global +1 +SET @orig_session = @@session.tokudb_pk_insert_mode; +SELECT @orig_session; +@orig_session +1 +SET GLOBAL tokudb_pk_insert_mode = 10; +Warnings: +Warning 1292 Truncated incorrect tokudb_pk_insert_mode value: '10' +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@global.tokudb_pk_insert_mode; +@@global.tokudb_pk_insert_mode +2 +SET GLOBAL tokudb_pk_insert_mode = 0; +Warnings: +Warning 131 Using tokudb_pk_insert_mode=0 is deprecated and the parameter may be removed in future releases. Only tokudb_pk_insert_mode=1|2 is allowed.Resettig the value to 1. +SELECT @@global.tokudb_pk_insert_mode; +@@global.tokudb_pk_insert_mode +1 +SET GLOBAL tokudb_pk_insert_mode = DEFAULT; +Warnings: +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@global.tokudb_pk_insert_mode; +@@global.tokudb_pk_insert_mode +1 +SET GLOBAL tokudb_pk_insert_mode = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_pk_insert_mode' +SELECT @@global.tokudb_pk_insert_mode; +@@global.tokudb_pk_insert_mode +1 +SET SESSION tokudb_pk_insert_mode = 10; +Warnings: +Warning 1292 Truncated incorrect tokudb_pk_insert_mode value: '10' +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@session.tokudb_pk_insert_mode; +@@session.tokudb_pk_insert_mode +2 +SET SESSION tokudb_pk_insert_mode = 0; +Warnings: +Warning 131 Using tokudb_pk_insert_mode=0 is deprecated and the parameter may be removed in future releases. Only tokudb_pk_insert_mode=1|2 is allowed.Resettig the value to 1. +SELECT @@session.tokudb_pk_insert_mode; +@@session.tokudb_pk_insert_mode +1 +SET SESSION tokudb_pk_insert_mode = DEFAULT; +Warnings: +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@session.tokudb_pk_insert_mode; +@@session.tokudb_pk_insert_mode +1 +SET SESSION tokudb_pk_insert_mode = 'foobar'; +ERROR 42000: Incorrect argument type to variable 'tokudb_pk_insert_mode' +SELECT @@session.tokudb_pk_insert_mode; +@@session.tokudb_pk_insert_mode +1 +SET GLOBAL tokudb_pk_insert_mode = 12; +Warnings: +Warning 1292 Truncated incorrect tokudb_pk_insert_mode value: '12' +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SET SESSION tokudb_pk_insert_mode = 13; +Warnings: +Warning 1292 Truncated incorrect tokudb_pk_insert_mode value: '13' +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@global.tokudb_pk_insert_mode; +@@global.tokudb_pk_insert_mode +2 +SELECT @@session.tokudb_pk_insert_mode; +@@session.tokudb_pk_insert_mode +2 +SHOW VARIABLES LIKE 'tokudb_pk_insert_mode'; +Variable_name Value +tokudb_pk_insert_mode 2 +SET SESSION tokudb_pk_insert_mode = @orig_session; +Warnings: +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@session.tokudb_pk_insert_mode; +@@session.tokudb_pk_insert_mode +1 +SET GLOBAL tokudb_pk_insert_mode = @orig_global; +Warnings: +Warning 131 Using tokudb_pk_insert_mode is deprecated and the parameter may be removed in future releases. +SELECT @@global.tokudb_pk_insert_mode; +@@global.tokudb_pk_insert_mode +1 diff --git a/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_pk_insert_mode_basic.test b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_pk_insert_mode_basic.test new file mode 100644 index 0000000000000..1669c7842a9ae --- /dev/null +++ b/storage/tokudb/mysql-test/tokudb_sys_vars/t/tokudb_pk_insert_mode_basic.test @@ -0,0 +1,51 @@ +--source include/have_tokudb.inc +--enable_warnings + +# Check the default value +SET @orig_global = @@global.tokudb_pk_insert_mode; +SELECT @orig_global; + +SET @orig_session = @@session.tokudb_pk_insert_mode; +SELECT @orig_session; + +# Test global +SET GLOBAL tokudb_pk_insert_mode = 10; +SELECT @@global.tokudb_pk_insert_mode; + +SET GLOBAL tokudb_pk_insert_mode = 0; +SELECT @@global.tokudb_pk_insert_mode; + +SET GLOBAL tokudb_pk_insert_mode = DEFAULT; +SELECT @@global.tokudb_pk_insert_mode; + +-- error ER_WRONG_TYPE_FOR_VAR +SET GLOBAL tokudb_pk_insert_mode = 'foobar'; +SELECT @@global.tokudb_pk_insert_mode; + +# Test session +SET SESSION tokudb_pk_insert_mode = 10; +SELECT @@session.tokudb_pk_insert_mode; + +SET SESSION tokudb_pk_insert_mode = 0; +SELECT @@session.tokudb_pk_insert_mode; + +SET SESSION tokudb_pk_insert_mode = DEFAULT; +SELECT @@session.tokudb_pk_insert_mode; + +-- error ER_WRONG_TYPE_FOR_VAR +SET SESSION tokudb_pk_insert_mode = 'foobar'; +SELECT @@session.tokudb_pk_insert_mode; + +# both +SET GLOBAL tokudb_pk_insert_mode = 12; +SET SESSION tokudb_pk_insert_mode = 13; +SELECT @@global.tokudb_pk_insert_mode; +SELECT @@session.tokudb_pk_insert_mode; +SHOW VARIABLES LIKE 'tokudb_pk_insert_mode'; + +# Clean up +SET SESSION tokudb_pk_insert_mode = @orig_session; +SELECT @@session.tokudb_pk_insert_mode; + +SET GLOBAL tokudb_pk_insert_mode = @orig_global; +SELECT @@global.tokudb_pk_insert_mode; diff --git a/storage/tokudb/tokudb_sysvars.cc b/storage/tokudb/tokudb_sysvars.cc index 168fb0cc647e2..b3f598f845f18 100644 --- a/storage/tokudb/tokudb_sysvars.cc +++ b/storage/tokudb/tokudb_sysvars.cc @@ -734,12 +734,45 @@ static MYSQL_THDVAR_ULONGLONG( ~0ULL, 1); +static const char* deprecated_tokudb_pk_insert_mode = + "Using tokudb_pk_insert_mode is deprecated and the " + "parameter may be removed in future releases."; +static const char* deprecated_tokudb_pk_insert_mode_zero = + "Using tokudb_pk_insert_mode=0 is deprecated and the " + "parameter may be removed in future releases. " + "Only tokudb_pk_insert_mode=1|2 is allowed." + "Resettig the value to 1."; + +static void pk_insert_mode_update( + THD* thd, + st_mysql_sys_var* var, + void* var_ptr, + const void* save) { + const uint* new_pk_insert_mode = static_cast(save); + uint* pk_insert_mode = static_cast(var_ptr); + if (*new_pk_insert_mode == 0) { + push_warning( + thd, + Sql_condition::WARN_LEVEL_WARN, + HA_ERR_WRONG_COMMAND, + deprecated_tokudb_pk_insert_mode_zero); + *pk_insert_mode = 1; + } else { + push_warning( + thd, + Sql_condition::WARN_LEVEL_WARN, + HA_ERR_WRONG_COMMAND, + deprecated_tokudb_pk_insert_mode); + *pk_insert_mode = *new_pk_insert_mode; + } +} + static MYSQL_THDVAR_UINT( pk_insert_mode, 0, "set the primary key insert mode", NULL, - NULL, + pk_insert_mode_update, 1, 0, 2, @@ -1064,6 +1097,9 @@ ulonglong optimize_throttle(THD* thd) { uint pk_insert_mode(THD* thd) { return THDVAR(thd, pk_insert_mode); } +void set_pk_insert_mode(THD* thd, uint mode) { + THDVAR(thd, pk_insert_mode) = mode; +} my_bool prelock_empty(THD* thd) { return (THDVAR(thd, prelock_empty) != 0); } diff --git a/storage/tokudb/tokudb_sysvars.h b/storage/tokudb/tokudb_sysvars.h index a7490c7b47374..adc5a50c0a73b 100644 --- a/storage/tokudb/tokudb_sysvars.h +++ b/storage/tokudb/tokudb_sysvars.h @@ -128,6 +128,7 @@ double optimize_index_fraction(THD* thd); const char* optimize_index_name(THD* thd); ulonglong optimize_throttle(THD* thd); uint pk_insert_mode(THD* thd); +void set_pk_insert_mode(THD* thd, uint mode); my_bool prelock_empty(THD* thd); uint read_block_size(THD* thd); uint read_buf_size(THD* thd); diff --git a/storage/tokudb/tokudb_thread.h b/storage/tokudb/tokudb_thread.h index ab1633a16cab9..dcb1fd6ec635b 100644 --- a/storage/tokudb/tokudb_thread.h +++ b/storage/tokudb/tokudb_thread.h @@ -34,6 +34,55 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. namespace tokudb { namespace thread { +#if (defined(__MACH__) || defined(__APPLE__)) && _POSIX_TIMERS <= 0 + +#define _x_min(a, b) ((a) < (b) ? (a) : (b)) + +#define timed_lock_define(timed_func_name, lock_type_name, lock_func_name) \ +inline int timed_func_name(lock_type_name *mutex, \ + const struct timespec *abs_timeout) { \ + int pthread_rc; \ + struct timespec remaining, slept, ts; \ + static const int sleep_step = 1000000; \ + \ + remaining = *abs_timeout; \ + while ((pthread_rc = lock_func_name(mutex)) == EBUSY) { \ + ts.tv_sec = 0; \ + ts.tv_nsec = (remaining.tv_sec > 0 ? \ + sleep_step : \ + _x_min(remaining.tv_nsec,sleep_step)); \ + nanosleep(&ts, &slept); \ + ts.tv_nsec -= slept.tv_nsec; \ + if (ts.tv_nsec <= remaining.tv_nsec) { \ + remaining.tv_nsec -= ts.tv_nsec; \ + } else { \ + remaining.tv_sec--; \ + remaining.tv_nsec = \ + (sleep_step - (ts.tv_nsec - remaining.tv_nsec)); \ + } \ + if (remaining.tv_sec < 0 || \ + (!remaining.tv_sec && remaining.tv_nsec <= 0)) { \ + return ETIMEDOUT; \ + } \ + } \ + \ + return pthread_rc; \ +} + +timed_lock_define(pthread_mutex_timedlock, + pthread_mutex_t, + pthread_mutex_trylock); + +timed_lock_define(pthread_rwlock_timedrdlock, + pthread_rwlock_t, + pthread_rwlock_tryrdlock); + +timed_lock_define(pthread_rwlock_timedwrlock, + pthread_rwlock_t, + pthread_rwlock_trywrlock); + +#endif //(defined(__MACH__) || defined(__APPLE__)) && _POSIX_TIMERS <= 0 + uint my_tid(void); // Your basic mutex From 87007dc2f71634cc460271eb277ad851ec69c04b Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 8 Jun 2016 15:03:18 +0400 Subject: [PATCH 045/112] MDEV-9994 - Aria service threads are not "joined" Aria service threads are created "joinable", but they're not "joined" on completion. This causes memory leaks around thread local storage. Fixed by joining service thread. Simplified relevant code and cleaned up relevant valgrind suppressions. --- mysql-test/valgrind.supp | 70 -------------------------------- storage/maria/ma_checkpoint.c | 18 ++++---- storage/maria/ma_loghandler.c | 11 +++-- storage/maria/ma_servicethread.c | 51 +++++------------------ storage/maria/ma_servicethread.h | 7 +--- 5 files changed, 26 insertions(+), 131 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 29897e4bd6c3f..16b59b8a06fa3 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -19,36 +19,6 @@ # Suppress some common (not fatal) errors in system libraries found by valgrind # -# -# Pthread doesn't free all thread specific memory before program exists -# -{ - pthread allocate_tls memory loss - Memcheck:Leak - fun:calloc - fun:_dl_allocate_tls - fun:allocate_stack - fun:pthread_create* -} - -{ - pthread allocate_tls memory loss - Memcheck:Leak - fun:calloc - fun:_dl_allocate_tls - fun:pthread_create* - -} - -{ - pthread allocate_tls memory loss - Memcheck:Leak - fun:calloc - obj:/lib*/ld*.so - fun:_dl_allocate_tls - fun:pthread_create* -} - { pthead_exit memory loss 1 Memcheck:Leak @@ -89,34 +59,6 @@ fun:_dl_map_object_from_fd } -{ - pthread allocate_dtv memory loss - Memcheck:Leak - fun:calloc - fun:allocate_dtv - fun:_dl_allocate_tls_storage - fun:__GI__dl_allocate_tls - fun:pthread_create -} - -{ - pthread allocate_dtv memory loss second - Memcheck:Leak - fun:calloc - fun:allocate_dtv - fun:_dl_allocate_tls - fun:pthread_create* -} - -{ - pthread memalign memory loss - Memcheck:Leak - fun:memalign - fun:_dl_allocate_tls_storage - fun:__GI__dl_allocate_tls - fun:pthread_create -} - { pthread pthread_key_create Memcheck:Leak @@ -972,18 +914,6 @@ fun:nptl_pthread_exit_hack_handler } -# -# Pthread doesn't free all thread specific memory before program exists -# -{ - pthread allocate_tls memory loss in 2.6.1. - Memcheck:Leak - fun:calloc - obj:*/ld-*.so - fun:_dl_allocate_tls - fun:pthread_create* -} - { memory "leak" in backtrace() of glibc 2.9 (not present in 2.13) Memcheck:Leak diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index 1e8adb6498125..f01af164aa6e9 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -46,7 +46,7 @@ static mysql_mutex_t LOCK_checkpoint; static mysql_cond_t COND_checkpoint; /** @brief control structure for checkpoint background thread */ static MA_SERVICE_THREAD_CONTROL checkpoint_control= - {THREAD_DEAD, FALSE, &LOCK_checkpoint, &COND_checkpoint}; + {0, FALSE, FALSE, &LOCK_checkpoint, &COND_checkpoint}; /* is ulong like pagecache->blocks_changed */ static ulong pages_to_flush_before_next_checkpoint; static PAGECACHE_FILE *dfiles, /**< data files to flush in background */ @@ -326,7 +326,6 @@ static int really_execute_checkpoint(void) int ma_checkpoint_init(ulong interval) { - pthread_t th; int res= 0; DBUG_ENTER("ma_checkpoint_init"); if (ma_service_thread_control_init(&checkpoint_control)) @@ -334,14 +333,14 @@ int ma_checkpoint_init(ulong interval) else if (interval > 0) { compile_time_assert(sizeof(void *) >= sizeof(ulong)); - if (!(res= mysql_thread_create(key_thread_checkpoint, - &th, NULL, ma_checkpoint_background, - (void *)interval))) - { - /* thread lives, will have to be killed */ - checkpoint_control.status= THREAD_RUNNING; - } + if ((res= mysql_thread_create(key_thread_checkpoint, + &checkpoint_control.thread, NULL, + ma_checkpoint_background, + (void*) interval))) + checkpoint_control.killed= TRUE; } + else + checkpoint_control.killed= TRUE; DBUG_RETURN(res); } @@ -717,7 +716,6 @@ pthread_handler_t ma_checkpoint_background(void *arg) DBUG_EXECUTE_IF("maria_checkpoint_indirect", level= CHECKPOINT_INDIRECT;); ma_checkpoint_execute(level, FALSE); } - my_service_thread_signal_end(&checkpoint_control); my_thread_end(); return 0; } diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 54f67eb1ab3f5..bf2205f5a4c0a 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -54,7 +54,7 @@ static mysql_mutex_t LOCK_soft_sync; static mysql_cond_t COND_soft_sync; /** @brief control structure for checkpoint background thread */ static MA_SERVICE_THREAD_CONTROL soft_sync_control= - {THREAD_DEAD, FALSE, &LOCK_soft_sync, &COND_soft_sync}; + {0, FALSE, FALSE, &LOCK_soft_sync, &COND_soft_sync}; /* transaction log file descriptor */ @@ -8819,7 +8819,6 @@ ma_soft_sync_background( void *arg __attribute__((unused))) if (my_service_thread_sleep(&soft_sync_control, sleep)) break; } - my_service_thread_signal_end(&soft_sync_control); my_thread_end(); DBUG_RETURN(0); } @@ -8832,7 +8831,6 @@ ma_soft_sync_background( void *arg __attribute__((unused))) int translog_soft_sync_start(void) { - pthread_t th; int res= 0; uint32 min, max; DBUG_ENTER("translog_soft_sync_start"); @@ -8847,9 +8845,10 @@ int translog_soft_sync_start(void) soft_need_sync= 1; if (!(res= ma_service_thread_control_init(&soft_sync_control))) - if (!(res= mysql_thread_create(key_thread_soft_sync, - &th, NULL, ma_soft_sync_background, NULL))) - soft_sync_control.status= THREAD_RUNNING; + if ((res= mysql_thread_create(key_thread_soft_sync, + &soft_sync_control.thread, NULL, + ma_soft_sync_background, NULL))) + soft_sync_control.killed= TRUE; DBUG_RETURN(res); } diff --git a/storage/maria/ma_servicethread.c b/storage/maria/ma_servicethread.c index e5c949a7571fa..d92c531593325 100644 --- a/storage/maria/ma_servicethread.c +++ b/storage/maria/ma_servicethread.c @@ -33,7 +33,7 @@ int ma_service_thread_control_init(MA_SERVICE_THREAD_CONTROL *control) DBUG_ENTER("ma_service_thread_control_init"); DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); control->inited= TRUE; - control->status= THREAD_DEAD; /* not yet born == dead */ + control->killed= FALSE; res= (mysql_mutex_init(key_SERVICE_THREAD_CONTROL_lock, control->LOCK_control, MY_MUTEX_INIT_SLOW) || mysql_cond_init(key_SERVICE_THREAD_CONTROL_cond, @@ -60,20 +60,17 @@ void ma_service_thread_control_end(MA_SERVICE_THREAD_CONTROL *control) DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); DBUG_ASSERT(control->inited); mysql_mutex_lock(control->LOCK_control); - if (control->status != THREAD_DEAD) /* thread was started OK */ + if (!control->killed) { DBUG_PRINT("info",("killing Maria background thread")); - control->status= THREAD_DYING; /* kill it */ - do /* and wait for it to be dead */ - { - /* wake it up if it was in a sleep */ - mysql_cond_broadcast(control->COND_control); - DBUG_PRINT("info",("waiting for Maria background thread to die")); - mysql_cond_wait(control->COND_control, control->LOCK_control); - } - while (control->status != THREAD_DEAD); + control->killed= TRUE; /* kill it */ + mysql_cond_broadcast(control->COND_control); + mysql_mutex_unlock(control->LOCK_control); + DBUG_PRINT("info", ("waiting for Maria background thread to die")); + pthread_join(control->thread, NULL); } - mysql_mutex_unlock(control->LOCK_control); + else + mysql_mutex_unlock(control->LOCK_control); mysql_mutex_destroy(control->LOCK_control); mysql_cond_destroy(control->COND_control); control->inited= FALSE; @@ -100,7 +97,7 @@ my_bool my_service_thread_sleep(MA_SERVICE_THREAD_CONTROL *control, DBUG_ENTER("my_service_thread_sleep"); DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); mysql_mutex_lock(control->LOCK_control); - if (control->status == THREAD_DYING) + if (control->killed) { mysql_mutex_unlock(control->LOCK_control); DBUG_RETURN(TRUE); @@ -119,34 +116,8 @@ my_bool my_service_thread_sleep(MA_SERVICE_THREAD_CONTROL *control, control->LOCK_control, &abstime); } #endif - if (control->status == THREAD_DYING) + if (control->killed) res= TRUE; mysql_mutex_unlock(control->LOCK_control); DBUG_RETURN(res); } - - -/** - inform about thread exiting - - @param control control block -*/ - -void my_service_thread_signal_end(MA_SERVICE_THREAD_CONTROL *control) -{ - DBUG_ENTER("my_service_thread_signal_end"); - DBUG_PRINT("init", ("control 0x%lx", (ulong) control)); - mysql_mutex_lock(control->LOCK_control); - control->status = THREAD_DEAD; /* indicate that we are dead */ - /* - wake up ma_service_thread_control_end which may be waiting for - our death - */ - mysql_cond_broadcast(control->COND_control); - /* - broadcast was inside unlock because ma_service_thread_control_end - destroys mutex - */ - mysql_mutex_unlock(control->LOCK_control); - DBUG_VOID_RETURN; -} diff --git a/storage/maria/ma_servicethread.h b/storage/maria/ma_servicethread.h index ed578d93c247b..254225bd60843 100644 --- a/storage/maria/ma_servicethread.h +++ b/storage/maria/ma_servicethread.h @@ -16,12 +16,10 @@ #include -enum ma_service_thread_state {THREAD_RUNNING, THREAD_DYING, THREAD_DEAD}; - typedef struct st_ma_service_thread_control { - /** 'kill' flag for the background thread */ - enum ma_service_thread_state status; + pthread_t thread; + my_bool killed; /** if thread module was inited or not */ my_bool inited; /** for killing the background thread */ @@ -35,4 +33,3 @@ int ma_service_thread_control_init(MA_SERVICE_THREAD_CONTROL *control); void ma_service_thread_control_end(MA_SERVICE_THREAD_CONTROL *control); my_bool my_service_thread_sleep(MA_SERVICE_THREAD_CONTROL *control, ulonglong sleep_time); -void my_service_thread_signal_end(MA_SERVICE_THREAD_CONTROL *control); From 22d7860d78a8c52602c2b9e8cab6b459c0ee18a1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 11 Jun 2016 22:47:30 +0200 Subject: [PATCH 046/112] fix tokudb tests after the merge --- .../tokudb/r/card_auto_analyze_lots.result | 5 +++++ .../tokudb/mysql-test/tokudb_bugs/disabled.def | 1 + .../tokudb_bugs/r/checkpoint_lock.result | 9 +++------ .../tokudb_bugs/r/checkpoint_lock_3.result | 9 +++------ .../tokudb_bugs/r/db756_card_part_hash.result | 4 ++-- .../r/db756_card_part_hash_1.result | 12 ++++++------ .../r/db756_card_part_hash_1_pick.result | 4 ++-- .../r/db756_card_part_hash_2.result | 12 ++++++------ .../r/db756_card_part_hash_2_pick.result | 4 ++-- .../r/db757_part_alter_analyze.result | 18 +++++++++--------- .../mysql-test/tokudb_bugs/r/db945.result | 1 + .../mysql-test/tokudb_bugs/r/simple_icp.result | 4 ++-- .../tokudb_bugs/t/checkpoint_lock.test | 6 +++--- .../tokudb_bugs/t/checkpoint_lock_3.test | 6 +++--- .../tokudb/mysql-test/tokudb_bugs/t/db917.test | 1 + .../tokudb_mariadb/r/mdev5426.result | 2 +- 16 files changed, 50 insertions(+), 48 deletions(-) diff --git a/storage/tokudb/mysql-test/tokudb/r/card_auto_analyze_lots.result b/storage/tokudb/mysql-test/tokudb/r/card_auto_analyze_lots.result index c665ef758a459..662ffbade250d 100644 --- a/storage/tokudb/mysql-test/tokudb/r/card_auto_analyze_lots.result +++ b/storage/tokudb/mysql-test/tokudb/r/card_auto_analyze_lots.result @@ -798,3 +798,8 @@ SHOW INDEX FROM ar_1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment ar_1 0 PRIMARY 1 a A 1 NULL NULL BTREE ar_1 1 bkey 1 b A 1 NULL NULL YES BTREE +SET SESSION tokudb_auto_analyze = @orig_auto_analyze; +SET SESSION tokudb_analyze_in_background = @orig_in_background; +SET SESSION tokudb_analyze_mode = @orig_mode; +SET SESSION tokudb_analyze_throttle = @orig_throttle; +SET SESSION tokudb_analyze_time = @orig_time; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/disabled.def b/storage/tokudb/mysql-test/tokudb_bugs/disabled.def index 00f886475f34e..d0d1a47e006a1 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/disabled.def +++ b/storage/tokudb/mysql-test/tokudb_bugs/disabled.def @@ -1 +1,2 @@ 5585: times out, too many huge insert...selects +db233: different execution path in mariadb, debug_sync point is not hit diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock.result b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock.result index 5e6a4742de3d7..f93f567961aba 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock.result @@ -1,20 +1,17 @@ SET DEFAULT_STORAGE_ENGINE = 'tokudb'; set global tokudb_checkpoint_on_flush_logs=ON; # Establish connection conn1 (user = root) -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); DB command state info test Sleep NULL -test Query Filling schema table select DB, command, state, info from information_schema.processlist order by info flush logs; -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); DB command state info test Sleep NULL -test Query Filling schema table select DB, command, state, info from information_schema.processlist order by info set tokudb_checkpoint_lock=1; flush logs;; -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); DB command state info test Query init flush logs -test Query Filling schema table select DB, command, state, info from information_schema.processlist order by info set tokudb_checkpoint_lock=0; set global tokudb_checkpoint_on_flush_logs=OFF; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_3.result b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_3.result index 683593bb5528e..3e689191d5953 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_3.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/checkpoint_lock_3.result @@ -1,18 +1,15 @@ SET DEFAULT_STORAGE_ENGINE = 'tokudb'; # Establish connection conn1 (user = root) -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); DB command state info test Sleep NULL -test Query Filling schema table select DB, command, state, info from information_schema.processlist order by info flush logs; -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); DB command state info test Sleep NULL -test Query Filling schema table select DB, command, state, info from information_schema.processlist order by info set tokudb_checkpoint_lock=1; flush logs;; -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); DB command state info test Sleep NULL -test Query Filling schema table select DB, command, state, info from information_schema.processlist order by info set tokudb_checkpoint_lock=0; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash.result index 044797e804722..70bc86e1abc7a 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash.result @@ -3,8 +3,8 @@ drop table if exists t; create table t (id int, x int, primary key (id), key (x)) partition by hash(id) partitions 2; show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 0 NULL NULL BTREE -t 1 x 1 x A 0 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 2 NULL NULL BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,1),(5,1); insert into t values (2,1),(4,1),(6,1); show indexes from t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1.result index ddd0f5404b722..b6d9fd7da8537 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1.result @@ -3,18 +3,18 @@ drop table if exists t; create table t (id int, x int, primary key (id), key (x)) partition by hash(id) partitions 2; show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 0 NULL NULL BTREE -t 1 x 1 x A 0 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 2 NULL NULL BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,1),(5,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 3 NULL NULL BTREE -t 1 x 1 x A 3 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 4 NULL NULL BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 3 NULL NULL BTREE -t 1 x 1 x A 3 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 4 NULL NULL BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE drop table t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result index 54e85a4254c0d..5ba5da217891f 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_1_pick.result @@ -3,8 +3,8 @@ drop table if exists t; create table t (id int, x int, primary key (id), key (x)) partition by hash(id) partitions 2; show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 0 NULL NULL BTREE -t 1 x 1 x A 0 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 2 NULL NULL BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,2),(5,3); insert into t values (2,1),(4,1),(6,1),(8,1); show indexes from t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2.result index 7ad2aa7968e60..6d345d98c95ff 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2.result @@ -3,18 +3,18 @@ drop table if exists t; create table t (id int, x int, primary key (id), key (x)) partition by hash(id) partitions 2; show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 0 NULL NULL BTREE -t 1 x 1 x A 0 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 2 NULL NULL BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (2,1),(4,1),(6,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 3 NULL NULL BTREE -t 1 x 1 x A 3 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 4 NULL NULL BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE analyze table t; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 3 NULL NULL BTREE -t 1 x 1 x A 3 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 4 NULL NULL BTREE +t 1 x 1 x A 4 NULL NULL YES BTREE drop table t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2_pick.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2_pick.result index a0e7a19bcf1d3..06639c311cf9a 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2_pick.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db756_card_part_hash_2_pick.result @@ -3,8 +3,8 @@ drop table if exists t; create table t (id int, x int, primary key (id), key (x)) partition by hash(id) partitions 2; show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 0 NULL NULL BTREE -t 1 x 1 x A 0 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 2 NULL NULL BTREE +t 1 x 1 x A 2 NULL NULL YES BTREE insert into t values (1,1),(3,2),(5,3),(7,4); insert into t values (2,1),(4,1),(6,1); show indexes from t; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result index de82556aba210..623378026883a 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db757_part_alter_analyze.result @@ -6,25 +6,25 @@ partition by range(id) insert into t values (1,1,1),(2,1,2),(3,1,3),(4,1,4); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A 4 NULL NULL YES BTREE -t 1 y 1 y A 4 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 5 NULL NULL BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE +t 1 y 1 y A 5 NULL NULL YES BTREE alter table t analyze partition p0; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A 4 NULL NULL YES BTREE -t 1 y 1 y A 4 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 5 NULL NULL BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE +t 1 y 1 y A 5 NULL NULL YES BTREE alter table t analyze partition p1; Table Op Msg_type Msg_text test.t analyze status OK show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment -t 0 PRIMARY 1 id A 4 NULL NULL BTREE -t 1 x 1 x A 4 NULL NULL YES BTREE -t 1 y 1 y A 4 NULL NULL YES BTREE +t 0 PRIMARY 1 id A 5 NULL NULL BTREE +t 1 x 1 x A 5 NULL NULL YES BTREE +t 1 y 1 y A 5 NULL NULL YES BTREE insert into t values (100,1,1),(200,2,1),(300,3,1),(400,4,1),(500,5,1); show indexes from t; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result index b576ce3150d17..0d05fa1d31ff0 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db945.result @@ -10,3 +10,4 @@ lock tables t1 write, t1 as a read, t1 as b read; insert into t1(a) values(1); alter table t1 drop key a; unlock tables; +drop table t1; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result index 6cc499389bb77..12fec571d875b 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/simple_icp.result @@ -110,7 +110,7 @@ a b c d e 5 1 10 NULL NULL show status like '%Handler_read_prev%'; Variable_name Value -Handler_read_prev 799 +Handler_read_prev 800 flush status; show status like '%Handler_read_prev%'; Variable_name Value @@ -142,7 +142,7 @@ a b c d e 20 1 10 NULL NULL show status like '%Handler_read_prev%'; Variable_name Value -Handler_read_prev 399 +Handler_read_prev 400 flush status; show status like '%Handler_read_next%'; Variable_name Value diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock.test b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock.test index d57a59b22e5b3..5deaa366fb4c5 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock.test @@ -8,9 +8,9 @@ connect (conn1,localhost,root,,); connection default; --sleep 2 -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); flush logs; -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); connection conn1; set tokudb_checkpoint_lock=1; @@ -20,7 +20,7 @@ connection default; connection conn1; --sleep 2 -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); set tokudb_checkpoint_lock=0; connection default; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_3.test b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_3.test index 64c0f491f9ac6..44ef8aaca5bd8 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_3.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/checkpoint_lock_3.test @@ -7,9 +7,9 @@ connect (conn1,localhost,root,,); connection default; --sleep 2 -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); flush logs; -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); connection conn1; set tokudb_checkpoint_lock=1; @@ -19,7 +19,7 @@ connection default; connection conn1; --sleep 2 -select DB, command, state, info from information_schema.processlist order by info; +select DB, command, state, info from information_schema.processlist where id != connection_id(); set tokudb_checkpoint_lock=0; connection default; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db917.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db917.test index 730c91ec83885..ae94d7b30de60 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/db917.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db917.test @@ -1,5 +1,6 @@ # test DB-917 # test that table/share open lock timeout does not crash the server on subsequent access +source include/have_partition.inc; source include/have_tokudb.inc; disable_warnings; drop table if exists t1; diff --git a/storage/tokudb/mysql-test/tokudb_mariadb/r/mdev5426.result b/storage/tokudb/mysql-test/tokudb_mariadb/r/mdev5426.result index 625bb2557559c..086c4f4cc1823 100644 --- a/storage/tokudb/mysql-test/tokudb_mariadb/r/mdev5426.result +++ b/storage/tokudb/mysql-test/tokudb_mariadb/r/mdev5426.result @@ -1,6 +1,6 @@ CREATE TABLE t1 (i INT) ENGINE=TokuDB; EXPLAIN INSERT INTO t1 SELECT * FROM t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 0 Using temporary +1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using temporary INSERT INTO t1 SELECT * FROM t1; DROP TABLE t1; From 02043d7c53857f598a3183c7607587bfdc46ed74 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 9 May 2016 18:38:16 +0200 Subject: [PATCH 047/112] MDEV-9128 Compiling on IBM System Z fails restore the fix f31a89191f that was lost in a merge --- storage/innobase/include/os0sync.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index 95e724ec48ee0..1cf4e9ce501c6 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -466,7 +466,7 @@ amount to decrement. */ # define os_atomic_decrement_uint64(ptr, amount) \ os_atomic_decrement(ptr, amount) -# if defined(IB_STRONG_MEMORY_MODEL) +# if defined(HAVE_ATOMIC_BUILTINS) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero From 67b4a6f576db102d652b401c3d0150556826f641 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Sun, 12 Jun 2016 20:14:51 +0300 Subject: [PATCH 048/112] MDEV-8859 rpl.rpl_mdev382 sporadically fails to finish due to disappeared expect file The combination of --remove_file and --write_file on .expect file creates a race condition which can be hit by MTR which reads the file in a loop. Instead, .expect file should be changed with --append_file. It was fixed in 10.x, but in 5.5 the sporadic failure still affected buildbot. Fixed 3 test files which use the problematic combination --- mysql-test/suite/binlog/t/binlog_mdev342.test | 3 +-- mysql-test/suite/rpl/t/rpl_mdev382.test | 3 +-- mysql-test/suite/storage_engine/alter_tablespace.test | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/binlog/t/binlog_mdev342.test b/mysql-test/suite/binlog/t/binlog_mdev342.test index 02310b87a760d..024fa884f9118 100644 --- a/mysql-test/suite/binlog/t/binlog_mdev342.test +++ b/mysql-test/suite/binlog/t/binlog_mdev342.test @@ -44,8 +44,7 @@ connection con1; --error 2006,2013 reap; ---remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect restart-binlog_mdev342.test EOF diff --git a/mysql-test/suite/rpl/t/rpl_mdev382.test b/mysql-test/suite/rpl/t/rpl_mdev382.test index 21925e0e13046..784617bd198e4 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev382.test +++ b/mysql-test/suite/rpl/t/rpl_mdev382.test @@ -209,8 +209,7 @@ EOF --shutdown_server 30 ---remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect restart-rpl_mdev382.test EOF diff --git a/mysql-test/suite/storage_engine/alter_tablespace.test b/mysql-test/suite/storage_engine/alter_tablespace.test index dec16e5a3aca6..6318b410e6ef1 100644 --- a/mysql-test/suite/storage_engine/alter_tablespace.test +++ b/mysql-test/suite/storage_engine/alter_tablespace.test @@ -53,8 +53,7 @@ EOF --replace_result $datadir --copy_file $datadir/test/t1.ibd $datadir/test/t1.ibd.save - --remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect - --write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + --append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect restart EOF From 416006a3d8164684a1bfffa2e20a1f9894baf372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Sun, 12 Jun 2016 22:45:15 +0300 Subject: [PATCH 049/112] MDEV-8012: Wrong exit code when asking for help Make mysql_waitpid return exit code 0 when -V flag is supplied. --- extra/mysql_waitpid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extra/mysql_waitpid.c b/extra/mysql_waitpid.c index 7777da25aa16e..aa004e573085a 100644 --- a/extra/mysql_waitpid.c +++ b/extra/mysql_waitpid.c @@ -50,7 +50,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), switch(optid) { case 'V': printf("%s version %s by Jani Tolonen\n", progname, VER); - exit(-1); + exit(0); case 'I': case '?': usage(); From 3c77a00d55efe901db9cb52ec000cc93d909a3c9 Mon Sep 17 00:00:00 2001 From: Dan Ungureanu Date: Tue, 8 Mar 2016 13:27:18 +0200 Subject: [PATCH 050/112] MDEV-8012: Wrong exit code when asking for help MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `--help` is a perfectly valid parameter and both `mysqladmin` and `mysql_waitpid` should exit with success (zero errror code). Signed-off-by: VicenÈ›iu Ciorbaru --- client/mysqladmin.cc | 11 ++--------- extra/mysql_waitpid.c | 5 ++++- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 9fd8a9b36fc0a..e7c6410978d27 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -232,8 +232,6 @@ my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { - int error = 0; - switch(optid) { case 'c': opt_count_iterations= 1; @@ -281,8 +279,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case '?': case 'I': /* Info */ - error++; - break; + usage(); + exit(0); case OPT_CHARSETS_DIR: #if MYSQL_VERSION_ID > 32300 charsets_dir = argument; @@ -293,11 +291,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), opt->name); break; } - if (error) - { - usage(); - exit(1); - } return 0; } diff --git a/extra/mysql_waitpid.c b/extra/mysql_waitpid.c index aa004e573085a..5cdf1dedc274d 100644 --- a/extra/mysql_waitpid.c +++ b/extra/mysql_waitpid.c @@ -54,6 +54,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'I': case '?': usage(); + exit(0); } return 0; } @@ -69,7 +70,10 @@ int main(int argc, char *argv[]) exit(-1); if (!argv[0] || !argv[1] || (pid= atoi(argv[0])) <= 0 || (t= atoi(argv[1])) <= 0) + { usage(); + exit(-1); + } for (; t > 0; t--) { if (kill((pid_t) pid, sig)) @@ -100,5 +104,4 @@ void usage(void) printf("integer arguments.\n\n"); printf("Options:\n"); my_print_help(my_long_options); - exit(-1); } From 2db724c8d2f3771c1a20b8cf9aaaf913b94aee68 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 13 Jun 2016 15:54:12 +0400 Subject: [PATCH 051/112] MDEV-10218 - rpl.rpl_binlog_errors fails in buildbot with valgrind warnings - bytes are possibly lost Timer thread of threadpool is created "joinable", but they're not "joined" on completion. This causes memory leaks around thread local storage. Fixed by joining timer thread. --- sql/threadpool_unix.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc index df1a05b3ebffe..6075c758e4050 100644 --- a/sql/threadpool_unix.cc +++ b/sql/threadpool_unix.cc @@ -166,6 +166,7 @@ struct pool_timer_t volatile uint64 next_timeout_check; int tick_interval; bool shutdown; + pthread_t timer_thread_id; }; static pool_timer_t pool_timer; @@ -603,12 +604,12 @@ void check_stall(thread_group_t *thread_group) static void start_timer(pool_timer_t* timer) { - pthread_t thread_id; DBUG_ENTER("start_timer"); mysql_mutex_init(key_timer_mutex,&timer->mutex, NULL); mysql_cond_init(key_timer_cond, &timer->cond, NULL); timer->shutdown = false; - mysql_thread_create(key_timer_thread,&thread_id, NULL, timer_thread, timer); + mysql_thread_create(key_timer_thread, &timer->timer_thread_id, NULL, + timer_thread, timer); DBUG_VOID_RETURN; } @@ -620,6 +621,7 @@ static void stop_timer(pool_timer_t *timer) timer->shutdown = true; mysql_cond_signal(&timer->cond); mysql_mutex_unlock(&timer->mutex); + pthread_join(timer->timer_thread_id, NULL); DBUG_VOID_RETURN; } From 0a96c9c4aab671ddcd1ac6af2c0bacf84405b0ff Mon Sep 17 00:00:00 2001 From: Olivier Bertrand Date: Mon, 13 Jun 2016 14:28:02 +0200 Subject: [PATCH 052/112] - Possibly fix MDEV-10179 Reset remote tables when re-opening modified: storage/connect/tabtbl.cpp - Add trace and make m_Stmt conditional modified: storage/connect/myconn.cpp modified: storage/connect/myconn.h - Protect trace from null string (for Linux) modified: storage/connect/tabcol.cpp - Record error changes modified: storage/connect/mysql-test/connect/r/jdbc_new.result - Typo modified: storage/connect/jdbconn.cpp modified: storage/connect/jsonudf.cpp --- storage/connect/jdbconn.cpp | 2 +- storage/connect/jsonudf.cpp | 4 +- storage/connect/myconn.cpp | 24 +- storage/connect/myconn.h | 6 +- .../connect/mysql-test/connect/disabled.def | 16 ++ .../connect/mysql-test/connect/r/jdbc.result | 269 ++++++++++++++++++ .../mysql-test/connect/r/jdbc_new.result | 216 ++++++++++++++ .../mysql-test/connect/r/jdbc_oracle.result | 70 +++++ .../connect/r/jdbc_postgresql.result | 65 +++++ .../mysql-test/connect/std_data/girls.txt | 5 + .../connect/mysql-test/connect/t/jdbc.test | 143 ++++++++++ .../mysql-test/connect/t/jdbc_new.test | 179 ++++++++++++ .../mysql-test/connect/t/jdbc_oracle.test | 56 ++++ .../mysql-test/connect/t/jdbc_postgresql.test | 53 ++++ .../connect/mysql-test/connect/t/jdbconn.inc | 31 ++ .../mysql-test/connect/t/jdbconn_cleanup.inc | 6 + storage/connect/tabcol.cpp | 2 +- storage/connect/tabtbl.cpp | 8 + 18 files changed, 1144 insertions(+), 11 deletions(-) create mode 100644 storage/connect/mysql-test/connect/disabled.def create mode 100644 storage/connect/mysql-test/connect/r/jdbc.result create mode 100644 storage/connect/mysql-test/connect/r/jdbc_new.result create mode 100644 storage/connect/mysql-test/connect/r/jdbc_oracle.result create mode 100644 storage/connect/mysql-test/connect/r/jdbc_postgresql.result create mode 100644 storage/connect/mysql-test/connect/std_data/girls.txt create mode 100644 storage/connect/mysql-test/connect/t/jdbc.test create mode 100644 storage/connect/mysql-test/connect/t/jdbc_new.test create mode 100644 storage/connect/mysql-test/connect/t/jdbc_oracle.test create mode 100644 storage/connect/mysql-test/connect/t/jdbc_postgresql.test create mode 100644 storage/connect/mysql-test/connect/t/jdbconn.inc create mode 100644 storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc diff --git a/storage/connect/jdbconn.cpp b/storage/connect/jdbconn.cpp index 7a508cd989b06..a8c0b193dcd32 100644 --- a/storage/connect/jdbconn.cpp +++ b/storage/connect/jdbconn.cpp @@ -2081,7 +2081,7 @@ bool JDBConn::SetParam(JDBCCOL *colp) if (!m_Rows) { strcpy(g->Message, "Void result"); return NULL; - } // endif m_Res + } // endif m_Rows /*********************************************************************/ /* Allocate the result storage for future retrieval. */ diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 0bc964d73510e..e94d38179264b 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -1,6 +1,6 @@ /****************** jsonudf C++ Program Source Code File (.CPP) ******************/ -/* PROGRAM NAME: jsonudf Version 1.3 */ -/* (C) Copyright to the author Olivier BERTRAND 2015 */ +/* PROGRAM NAME: jsonudf Version 1.4 */ +/* (C) Copyright to the author Olivier BERTRAND 2015-2016 */ /* This program are the JSON User Defined Functions . */ /*********************************************************************************/ diff --git a/storage/connect/myconn.cpp b/storage/connect/myconn.cpp index b844d68e1cd66..644ca019e4ac0 100644 --- a/storage/connect/myconn.cpp +++ b/storage/connect/myconn.cpp @@ -5,7 +5,7 @@ /* */ /* COPYRIGHT: */ /* ---------- */ -/* (C) Copyright to the author Olivier BERTRAND 2007-2015 */ +/* (C) Copyright to the author Olivier BERTRAND 2007-2016 */ /* */ /* WHAT THIS PROGRAM DOES: */ /* ----------------------- */ @@ -401,8 +401,10 @@ PQRYRES SrcColumns(PGLOBAL g, const char *host, const char *db, MYSQLC::MYSQLC(void) { m_DB = NULL; - m_Stmt = NULL; - m_Res = NULL; +#if defined (MYSQL_PREPARED_STATEMENTS) + m_Stmt = NULL; +#endif // MYSQL_PREPARED_STATEMENTS + m_Res = NULL; m_Rows = -1; m_Row = NULL; m_Fields = -1; @@ -444,7 +446,10 @@ int MYSQLC::Open(PGLOBAL g, const char *host, const char *db, return RC_FX; } // endif m_DB - // Removed to do like FEDERATED do + if (trace) + htrc("MYSQLC Open: m_DB=%.4X size=%d\n", m_DB, (int)sizeof(*m_DB)); + + // Removed to do like FEDERATED do //mysql_options(m_DB, MYSQL_READ_DEFAULT_GROUP, "client-mariadb"); mysql_options(m_DB, MYSQL_OPT_USE_REMOTE_CONNECTION, NULL); mysql_options(m_DB, MYSQL_OPT_CONNECT_TIMEOUT, &cto); @@ -701,6 +706,11 @@ int MYSQLC::ExecSQL(PGLOBAL g, const char *query, int *w) } else { m_Fields = mysql_num_fields(m_Res); m_Rows = (!m_Use) ? (int)mysql_num_rows(m_Res) : 0; + + if (trace) + htrc("ExecSQL: m_Res=%.4X size=%d m_Fields=%d m_Rows=%d\n", + m_Res, sizeof(*m_Res), m_Fields, m_Rows); + } // endif m_Res } else { @@ -1017,7 +1027,11 @@ int MYSQLC::ExecSQLcmd(PGLOBAL g, const char *query, int *w) void MYSQLC::Close(void) { FreeResult(); - mysql_close(m_DB); + + if (trace) + htrc("MYSQLC Close: m_DB=%.4X\n", m_DB); + + mysql_close(m_DB); m_DB = NULL; } // end of Close diff --git a/storage/connect/myconn.h b/storage/connect/myconn.h index 79f095f5c939c..9ebd37527a6d9 100644 --- a/storage/connect/myconn.h +++ b/storage/connect/myconn.h @@ -90,8 +90,10 @@ class DllItem MYSQLC { // Members MYSQL *m_DB; // The return from MySQL connection - MYSQL_STMT *m_Stmt; // Prepared statement handle - MYSQL_RES *m_Res; // Points to MySQL Result +#if defined (MYSQL_PREPARED_STATEMENTS) + MYSQL_STMT *m_Stmt; // Prepared statement handle +#endif // MYSQL_PREPARED_STATEMENTS + MYSQL_RES *m_Res; // Points to MySQL Result MYSQL_ROW m_Row; // Point to current row int m_Rows; // The number of rows of the result int N; diff --git a/storage/connect/mysql-test/connect/disabled.def b/storage/connect/mysql-test/connect/disabled.def new file mode 100644 index 0000000000000..9b4570915c7ec --- /dev/null +++ b/storage/connect/mysql-test/connect/disabled.def @@ -0,0 +1,16 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# : BUG# +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +#json_udf_bin : broken upstream in --ps (fixed) +jdbc : Variable settings depend on machine configuration +jdbc_new : Variable settings depend on machine configuration +jdbc_oracle : Variable settings depend on machine configuration +jdbc_postgresql : Variable settings depend on machine configuration diff --git a/storage/connect/mysql-test/connect/r/jdbc.result b/storage/connect/mysql-test/connect/r/jdbc.result new file mode 100644 index 0000000000000..5e844bc990078 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc.result @@ -0,0 +1,269 @@ +CREATE DATABASE connect; +USE connect; +CREATE TABLE t2 ( +id bigint not null, +msg varchar(500), +tm time, +dt date, +dtm datetime, +ts timestamp); +INSERT INTO t2 VALUES(455000000000, 'A very big number', '18:10:25', '2016-03-16', '1999-12-11 23:01:52', '2015-07-24 09:32:45'); +SELECT * FROM t2; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +# +# Testing JDBC connection to MySQL driver +# +USE test; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root'; +SELECT * FROM t1; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +INSERT INTO t1 VALUES(786325481247, 'Hello!', '19:45:03', '1933-08-10', '1985-11-12 09:02:44', '2014-06-17 10:32:01'); +Warnings: +Note 1105 t2: 1 affected rows +SELECT * FROM t1; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +786325481247 Hello! 19:45:03 1933-08-09 1985-11-12 09:02:44 2014-06-17 10:32:01 +DELETE FROM t1 WHERE msg = 'Hello!'; +Warnings: +Note 1105 t2: 1 affected rows +SELECT * FROM t1; +id msg tm dt dtm ts +455000000000 A very big number 18:10:25 2016-03-16 1999-12-11 23:01:52 2015-07-24 09:32:45 +DROP TABLE t1; +# +# Testing JDBC view +# +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root'; +SELECT * FROM t1; +id msg tm dt +455000000000 A very big number 18:10:25 2016-03-16 +SELECT msg, dt FROM t1; +msg dt +A very big number 2016-03-16 +DROP TABLE t1, connect.t2; +# +# Testing JDBC write operations +# +USE connect; +CREATE TABLE boys ( +name CHAR(12) NOT NULL, +city CHAR(11), +birth DATE DATE_FORMAT='DD/MM/YYYY', +hired DATE DATE_FORMAT='DD/MM/YYYY' flag=36) +ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; +SELECT * FROM boys; +name city birth hired +John Boston 1986-01-25 2010-06-02 +Henry Boston 1987-06-07 2008-04-01 +George San Jose 1981-08-10 2010-06-02 +Sam Chicago 1979-11-22 2007-10-10 +James Dallas 1992-05-13 2009-12-14 +Bill Boston 1986-09-11 2008-02-10 +USE test; +CREATE TABLE t3 ( +name CHAR(12) NOT NULL, +city CHAR(12), +birth DATE, +hired DATE); +INSERT INTO t3 VALUES('Donald','Atlanta','1999-04-01','2016-03-31'),('Mick','New York','1980-01-20','2002-09-11'); +SELECT * FROM t3; +name city birth hired +Donald Atlanta 1999-04-01 2016-03-31 +Mick New York 1980-01-20 2002-09-11 +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:PORT/connect?user=root' OPTION_LIST='scrollable=1'; +SELECT * FROM t1; +name city birth hired +John Boston 1986-01-25 2010-06-02 +Henry Boston 1987-06-07 2008-04-01 +George San Jose 1981-08-10 2010-06-02 +Sam Chicago 1979-11-22 2007-10-10 +James Dallas 1992-05-13 2009-12-14 +Bill Boston 1986-09-11 2008-02-10 +UPDATE t1 SET city = 'Phoenix' WHERE name = 'Henry'; +Warnings: +Note 1105 boys: 1 affected rows +INSERT INTO t1 SELECT * FROM t3; +Warnings: +Note 1105 boys: 2 affected rows +INSERT INTO t1 VALUES('Tom','Seatle','2002-03-15',NULL); +Warnings: +Note 1105 boys: 1 affected rows +SELECT * FROM t1; +name city birth hired +John Boston 1986-01-25 2010-06-02 +Henry Phoenix 1987-06-07 2008-04-01 +George San Jose 1981-08-10 2010-06-02 +Sam Chicago 1979-11-22 2007-10-10 +James Dallas 1992-05-13 2009-12-14 +Bill Boston 1986-09-11 2008-02-10 +Donald Atlanta 1999-04-01 2016-03-31 +Mick New York 1980-01-20 2002-09-11 +Tom Seatle 2002-03-15 1970-01-01 +DROP TABLE t3; +# +# Testing JDBC join operations +# +CREATE TABLE t3 ( +name CHAR(9) NOT NULL, +city CHAR(12) NOT NULL, +age INT(2)) +engine=CONNECT table_type=FIX file_name='girls.txt'; +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN connect.boys b where g.city = b.city; +name name city +Mary John Boston +Susan Sam Chicago +Betty Sam Chicago +Mary Bill Boston +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN t1 b where g.city = b.city; +name name city +Mary John Boston +Susan Sam Chicago +Betty Sam Chicago +Mary Bill Boston +DROP TABLE t1, t3, connect.boys; +# +# Testing MariaDB JDBC driver +# +USE connect; +CREATE TABLE emp ( +serialno CHAR(5) NOT NULL, +name VARCHAR(12) NOT NULL FLAG=6, +sex TINYINT(1) NOT NULL, +title VARCHAR(15) NOT NULL FLAG=20, +manager CHAR(5) NOT NULL, +department CHAR(4) NOT NULL FLAG=41, +secretary CHAR(5) NOT NULL FLAG=46, +salary DOUBLE(8,2) NOT NULL FLAG=52) +ENGINE=connect TABLE_TYPE=fix FILE_NAME='employee.dat' ENDING=1; +SELECT * FROM emp; +serialno name sex title manager department secretary salary +74200 BANCROFT 2 SALESMAN 70012 0318 24888 9600.00 +02345 SMITH 1 ENGINEER 31416 2452 11111 9000.00 +78943 MERCHANT 1 SALESMAN 70012 0318 24888 8700.00 +07654 FUNNIGUY 1 ADMINISTRATOR 40567 0319 33333 8500.00 +45678 BUGHAPPY 1 PROGRAMMER 40567 0319 12345 8500.00 +34567 BIGHEAD 1 SCIENTIST 31416 2452 11111 8000.00 +77777 SHRINKY 2 ADMINISTRATOR 70012 0318 27845 7500.00 +74234 WALTER 1 ENGINEER 70012 0318 24888 7400.00 +56789 FODDERMAN 1 SALESMAN 40567 0319 12345 7000.00 +73452 TONGHO 1 ENGINEER 70012 0318 24888 6800.00 +22222 SHORTSIGHT 2 SECRETARY 87777 0021 5500.00 +55555 MESSIFUL 2 SECRETARY 40567 0319 12345 5000.50 +27845 HONEY 2 SECRETARY 70012 0318 24888 4900.00 +98765 GOOSEPEN 1 ADMINISTRATOR 07654 0319 33333 4700.00 +11111 CHERRY 2 SECRETARY 31416 2452 4500.00 +33333 MONAPENNY 2 SECRETARY 07654 0319 3800.00 +12345 KITTY 2 TYPIST 40567 0319 3000.45 +24888 PLUMHEAD 2 TYPIST 27845 0318 2800.00 +87777 STRONG 1 DIRECTOR 0021 22222 23000.00 +76543 BULLOZER 1 SALESMAN 40567 0319 12345 14800.00 +70012 WERTHER 1 DIRECTOR 87777 0318 27845 14500.00 +40567 QUINN 1 DIRECTOR 87777 0319 55555 14000.00 +31416 ORELLY 1 ENGINEER 87777 2452 11111 13400.00 +36666 BIGHORN 1 SCIENTIST 31416 2452 11111 11000.00 +00137 BROWNY 1 ENGINEER 40567 0319 12345 10500.00 +73111 WHEELFOR 1 SALESMAN 70012 0318 24888 10030.00 +00023 MARTIN 1 ENGINEER 40567 0319 12345 10000.00 +USE test; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `serialno` char(5) NOT NULL, + `name` varchar(12) NOT NULL, + `sex` tinyint(3) NOT NULL, + `title` varchar(15) NOT NULL, + `manager` char(5) NOT NULL, + `department` char(4) NOT NULL, + `secretary` char(5) NOT NULL, + `salary` double(12,2) NOT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mariadb://localhost:PORT/connect?user=root' `TABLE_TYPE`='JDBC' `TABNAME`='emp' +SELECT * FROM t1; +serialno name sex title manager department secretary salary +74200 BANCROFT 2 SALESMAN 70012 0318 24888 9600.00 +02345 SMITH 1 ENGINEER 31416 2452 11111 9000.00 +78943 MERCHANT 1 SALESMAN 70012 0318 24888 8700.00 +07654 FUNNIGUY 1 ADMINISTRATOR 40567 0319 33333 8500.00 +45678 BUGHAPPY 1 PROGRAMMER 40567 0319 12345 8500.00 +34567 BIGHEAD 1 SCIENTIST 31416 2452 11111 8000.00 +77777 SHRINKY 2 ADMINISTRATOR 70012 0318 27845 7500.00 +74234 WALTER 1 ENGINEER 70012 0318 24888 7400.00 +56789 FODDERMAN 1 SALESMAN 40567 0319 12345 7000.00 +73452 TONGHO 1 ENGINEER 70012 0318 24888 6800.00 +22222 SHORTSIGHT 2 SECRETARY 87777 0021 5500.00 +55555 MESSIFUL 2 SECRETARY 40567 0319 12345 5000.50 +27845 HONEY 2 SECRETARY 70012 0318 24888 4900.00 +98765 GOOSEPEN 1 ADMINISTRATOR 07654 0319 33333 4700.00 +11111 CHERRY 2 SECRETARY 31416 2452 4500.00 +33333 MONAPENNY 2 SECRETARY 07654 0319 3800.00 +12345 KITTY 2 TYPIST 40567 0319 3000.45 +24888 PLUMHEAD 2 TYPIST 27845 0318 2800.00 +87777 STRONG 1 DIRECTOR 0021 22222 23000.00 +76543 BULLOZER 1 SALESMAN 40567 0319 12345 14800.00 +70012 WERTHER 1 DIRECTOR 87777 0318 27845 14500.00 +40567 QUINN 1 DIRECTOR 87777 0319 55555 14000.00 +31416 ORELLY 1 ENGINEER 87777 2452 11111 13400.00 +36666 BIGHORN 1 SCIENTIST 31416 2452 11111 11000.00 +00137 BROWNY 1 ENGINEER 40567 0319 12345 10500.00 +73111 WHEELFOR 1 SALESMAN 70012 0318 24888 10030.00 +00023 MARTIN 1 ENGINEER 40567 0319 12345 10000.00 +SELECT name, title, salary FROM t1 WHERE sex = 1; +name title salary +SMITH ENGINEER 9000.00 +MERCHANT SALESMAN 8700.00 +FUNNIGUY ADMINISTRATOR 8500.00 +BUGHAPPY PROGRAMMER 8500.00 +BIGHEAD SCIENTIST 8000.00 +WALTER ENGINEER 7400.00 +FODDERMAN SALESMAN 7000.00 +TONGHO ENGINEER 6800.00 +GOOSEPEN ADMINISTRATOR 4700.00 +STRONG DIRECTOR 23000.00 +BULLOZER SALESMAN 14800.00 +WERTHER DIRECTOR 14500.00 +QUINN DIRECTOR 14000.00 +ORELLY ENGINEER 13400.00 +BIGHORN SCIENTIST 11000.00 +BROWNY ENGINEER 10500.00 +WHEELFOR SALESMAN 10030.00 +MARTIN ENGINEER 10000.00 +DROP TABLE t1, connect.emp; +CREATE TABLE t2 (command varchar(128) not null,number int(5) not null flag=1,message varchar(255) flag=2) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mariadb://localhost:PORT/connect' OPTION_LIST='User=root,Execsrc=1'; +SELECT * FROM t2 WHERE command='drop table tx1'; +command number message +drop table tx1 0 Execute: java.sql.SQLSyntaxErrorException: Unknown table 'connect.tx1' +Query is : drop table tx1 +SELECT * FROM t2 WHERE command = 'create table tx1 (a int not null, b char(32), c double(8,2))'; +command number message +create table tx1 (a int not null, b char(32), c double(8,2)) 0 Affected rows +SELECT * FROM t2 WHERE command in ('insert into tx1 values(1,''The number one'',456.12)',"insert into tx1(a,b) values(2,'The number two'),(3,'The number three')"); +command number message +insert into tx1 values(1,'The number one',456.12) 1 Affected rows +insert into tx1(a,b) values(2,'The number two'),(3,'The number three') 2 Affected rows +SELECT * FROM t2 WHERE command='update tx1 set c = 3.1416 where a = 2'; +command number message +update tx1 set c = 3.1416 where a = 2 1 Affected rows +SELECT * FROM t2 WHERE command='select * from tx1'; +command number message +select * from tx1 3 Result set column number +SELECT * FROM t2 WHERE command='delete from tx1 where a = 2'; +command number message +delete from tx1 where a = 2 1 Affected rows +SELECT * FROM connect.tx1; +a b c +1 The number one 456.12 +3 The number three NULL +DROP TABLE t2; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:mariadb://localhost:PORT/connect' option_list='User=root,Maxres=50'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Table_Type Remark +connect NULL tx1 BASE TABLE +DROP TABLE t1; +DROP TABLE connect.tx1; +DROP DATABASE connect; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_new.result b/storage/connect/mysql-test/connect/r/jdbc_new.result new file mode 100644 index 0000000000000..e5356edd5d812 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc_new.result @@ -0,0 +1,216 @@ +CREATE TABLE t1 (a int, b char(10)); +INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03'); +SELECT * FROM t1; +a b +NULL NULL +0 test00 +1 test01 +2 test02 +3 test03 +# +# Testing errors +# +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=unknown'; +SELECT * FROM t1; +ERROR HY000: Got error 174 'Connecting: java.sql.SQLException: Access denied for user 'unknown'@'localhost' (using password: NO) rc=-2' from CONNECT +DROP TABLE t1; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/unknown?user=root'; +ERROR HY000: Connecting: java.sql.SQLSyntaxErrorException: Unknown database 'unknown' rc=-2 +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' + CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +ERROR HY000: Cannot get columns from unknown +SHOW CREATE TABLE t1; +ERROR 42S02: Table 'test.t1' doesn't exist +CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `x` int(11) DEFAULT NULL, + `y` char(10) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +SELECT * FROM t1; +ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Unknown column 'x' in 'field list' +Query is : SELECT x, y FROM t1' from CONNECT +DROP TABLE t1; +CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +ALTER TABLE t1 RENAME t1backup; +SELECT * FROM t1; +ERROR HY000: Got error 174 'ExecuteQuery: java.sql.SQLSyntaxErrorException: Table 'test.t1' doesn't exist +Query is : SELECT a, b FROM t1' from CONNECT +ALTER TABLE t1backup RENAME t1; +DROP TABLE t1; +# +# Testing SELECT, etc. +# +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(10) DEFAULT NULL, + `b` char(10) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b +0 NULL +0 test00 +1 test01 +2 test02 +3 test03 +DROP TABLE t1; +CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1' + CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` char(10) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC `TABNAME`='t1' +SELECT * FROM t1; +a b +0 NULL +0 test00 +1 test01 +2 test02 +3 test03 +DROP TABLE t1; +CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + `b` char(10) NOT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +SELECT * FROM t1; +a b +0 +0 test00 +1 test01 +2 test02 +3 test03 +DROP TABLE t1; +CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(10) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`=JDBC +SELECT * FROM t1; +a b +0 NULL +0 0 +1 0 +2 0 +3 0 +DROP TABLE t1; +DROP TABLE t1; +# +# Testing numeric data types +# +CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` tinyint(4) DEFAULT NULL, + `b` smallint(6) DEFAULT NULL, + `c` mediumint(9) DEFAULT NULL, + `d` int(11) DEFAULT NULL, + `e` bigint(20) DEFAULT NULL, + `f` float DEFAULT NULL, + `g` double DEFAULT NULL, + `h` decimal(20,5) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265); +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` tinyint(3) DEFAULT NULL, + `b` smallint(5) DEFAULT NULL, + `c` int(7) DEFAULT NULL, + `d` int(10) DEFAULT NULL, + `e` bigint(19) DEFAULT NULL, + `f` double(14,0) DEFAULT NULL, + `g` double(24,0) DEFAULT NULL, + `h` decimal(27,5) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b c d e f g h +100 3333 41235 1234567890 235000000000 3 3 3141.59265 +DROP TABLE t1; +DROP TABLE t1; +# +# Testing character data types +# +CREATE TABLE t1 (a char(12), b varchar(12)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(12) DEFAULT NULL, + `b` varchar(12) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES('Welcome','Hello, World'); +SELECT * FROM t1; +a b +Welcome Hello, World +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(12) DEFAULT NULL, + `b` varchar(12) DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b +Welcome Hello, World +DROP TABLE t1; +DROP TABLE t1; +# +# Testing temporal data types +# +CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL, + `b` datetime DEFAULT NULL, + `c` time DEFAULT NULL, + `d` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `e` year(4) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23'); +Warnings: +Note 1265 Data truncated for column 'a' at row 1 +Note 1265 Data truncated for column 'c' at row 1 +Warning 1265 Data truncated for column 'e' at row 1 +SELECT * FROM t1; +a b c d e +2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 2003 +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC +CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL, + `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + `c` time DEFAULT NULL, + `d` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `e` date DEFAULT NULL +) ENGINE=CONNECT DEFAULT CHARSET=latin1 CONNECTION='jdbc:mysql://127.0.0.1:SLAVE_PORT/test?user=root' `TABLE_TYPE`='JDBC' +SELECT * FROM t1; +a b c d e +2003-05-27 2003-05-27 10:45:23 10:45:23 2003-05-27 10:45:23 1970-01-01 +DROP TABLE t1; +DROP TABLE t1; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result new file mode 100644 index 0000000000000..2e36891a037e6 --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result @@ -0,0 +1,70 @@ +CREATE TABLE t2 ( +command varchar(128) not null, +number int(5) not null flag=1, +message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager,Execsrc=1'; +SELECT * FROM t2 WHERE command = 'drop table employee'; +command number message +drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist + +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; +command number message +create table employee (id int not null, name varchar(32), title char(16), salary number(8,2)) 0 Affected rows +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; +command number message +insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1 WHERE table_name='employee'; +Table_Cat Table_Schema Table_Name Table_Type Remark +NULL SYSTEM EMPLOYEE TABLE NULL +DROP TABLE t1; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks +NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL +NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 0 10 1 NULL +NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 0 10 1 NULL +NULL SYSTEM EMPLOYEE SALARY 3 NUMBER 8 0 2 10 1 NULL +DROP TABLE t1; +CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS ( +HOST 'jdbc:oracle:thin:@localhost:1521:xe', +DATABASE 'SYSTEM', +USER 'system', +PASSWORD 'manager', +PORT 0, +SOCKET '', +OWNER 'SYSTEM'); +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='oracle' tabname='EMPLOYEE'; +SELECT * FROM t1; +ID NAME TITLE SALARY +4567 Johnson Engineer 12560.50 +INSERT INTO t1 VALUES(6214, 'Clinton', 'Retired', NULL); +Warnings: +Note 1105 EMPLOYEE: 1 affected rows +UPDATE t1 set name='Trump' WHERE id = 4567; +Warnings: +Note 1105 EMPLOYEE: 1 affected rows +SELECT * FROM t1; +ID NAME TITLE SALARY +4567 Trump Engineer 12560.50 +6214 Clinton Retired 0.00 +DELETE FROM t1 WHERE id = 6214; +Warnings: +Note 1105 EMPLOYEE: 1 affected rows +SELECT * FROM t1; +ID NAME TITLE SALARY +4567 Trump Engineer 12560.50 +DROP TABLE t1; +SELECT * FROM t2 WHERE command = 'drop table employee'; +command number message +drop table employee 0 Affected rows +DROP TABLE t2; +DROP SERVER 'oracle'; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/r/jdbc_postgresql.result b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result new file mode 100644 index 0000000000000..6d77d79d5d3ff --- /dev/null +++ b/storage/connect/mysql-test/connect/r/jdbc_postgresql.result @@ -0,0 +1,65 @@ +CREATE TABLE t2 ( +command varchar(128) not null, +number int(5) not null flag=1, +message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1'; +SELECT * FROM t2 WHERE command='drop table employee'; +command number message +drop table employee 0 Execute: org.postgresql.util.PSQLException: ERREUR: la table « employee » n'existe pas +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))'; +command number message +create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2)) 0 Affected rows +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; +command number message +insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Table_Type Remark + public employee TABLE NULL + public t1 TABLE NULL + public t2 TABLE NULL +DROP TABLE t1; +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns +CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee +OPTION_LIST='User=mtr,Password=mtr,Maxres=10'; +SELECT * FROM t1; +Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks +NULL public employee id 4 int4 10 0 0 10 0 NULL +NULL public employee name 12 varchar 32 0 0 10 1 NULL +NULL public employee title 1 bpchar 16 0 0 10 1 NULL +NULL public employee salary 2 numeric 8 0 2 10 1 NULL +DROP TABLE t1; +CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS ( +HOST 'localhost', +DATABASE 'mtr', +USER 'mtr', +PASSWORD 'mtr', +PORT 0, +SOCKET '', +OWNER 'root'); +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee'; +SELECT * FROM t1; +id name title salary +4567 Johnson Engineer 12560.50 +INSERT INTO t1 VALUES(3126,'Smith', 'Clerk', 5230.00); +Warnings: +Note 1105 public.employee: 1 affected rows +UPDATE t1 SET salary = salary + 100.00; +Warnings: +Note 1105 public.employee: 2 affected rows +SELECT * FROM t1; +id name title salary +4567 Johnson Engineer 12660.50 +3126 Smith Clerk 5330.00 +DROP TABLE t1; +DROP SERVER 'postgresql'; +SELECT * FROM t2 WHERE command='drop table employee'; +command number message +drop table employee 0 Affected rows +DROP TABLE t2; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; diff --git a/storage/connect/mysql-test/connect/std_data/girls.txt b/storage/connect/mysql-test/connect/std_data/girls.txt new file mode 100644 index 0000000000000..12ce8babbaffb --- /dev/null +++ b/storage/connect/mysql-test/connect/std_data/girls.txt @@ -0,0 +1,5 @@ +Mary Boston 25 +Nancy Palo Alto 23 +Susan Chicago 18 +Betty Chicago 32 +Anne Denver 23 diff --git a/storage/connect/mysql-test/connect/t/jdbc.test b/storage/connect/mysql-test/connect/t/jdbc.test new file mode 100644 index 0000000000000..9389747ad9c75 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc.test @@ -0,0 +1,143 @@ +-- source jdbconn.inc + +let $MYSQLD_DATADIR= `select @@datadir`; +--copy_file $MTR_SUITE_DIR/std_data/girls.txt $MYSQLD_DATADIR/test/girls.txt + +let $PORT= `select @@port`; + +# +# This test is run against a local MariaDB server +# +CREATE DATABASE connect; +USE connect; +CREATE TABLE t2 ( + id bigint not null, + msg varchar(500), + tm time, + dt date, + dtm datetime, + ts timestamp); +INSERT INTO t2 VALUES(455000000000, 'A very big number', '18:10:25', '2016-03-16', '1999-12-11 23:01:52', '2015-07-24 09:32:45'); +SELECT * FROM t2; + +--echo # +--echo # Testing JDBC connection to MySQL driver +--echo # +USE test; +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=t2 CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' +SELECT * FROM t1; +INSERT INTO t1 VALUES(786325481247, 'Hello!', '19:45:03', '1933-08-10', '1985-11-12 09:02:44', '2014-06-17 10:32:01'); +SELECT * FROM t1; +DELETE FROM t1 WHERE msg = 'Hello!'; +SELECT * FROM t1; +DROP TABLE t1; + +--echo # +--echo # Testing JDBC view +--echo # +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC SRCDEF='select id, msg, tm, dt from t2' CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' +SELECT * FROM t1; +SELECT msg, dt FROM t1; +DROP TABLE t1, connect.t2; + +--echo # +--echo # Testing JDBC write operations +--echo # +USE connect; +--copy_file $MTR_SUITE_DIR/std_data/boys.txt $MYSQLD_DATADIR/connect/boys.txt +CREATE TABLE boys ( + name CHAR(12) NOT NULL, + city CHAR(11), + birth DATE DATE_FORMAT='DD/MM/YYYY', + hired DATE DATE_FORMAT='DD/MM/YYYY' flag=36) +ENGINE=CONNECT TABLE_TYPE=FIX FILE_NAME='boys.txt' ENDING=1; +SELECT * FROM boys; + +USE test; +CREATE TABLE t3 ( + name CHAR(12) NOT NULL, + city CHAR(12), + birth DATE, + hired DATE); +INSERT INTO t3 VALUES('Donald','Atlanta','1999-04-01','2016-03-31'),('Mick','New York','1980-01-20','2002-09-11'); +SELECT * FROM t3; + +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=boys CONNECTION='jdbc:mysql://localhost:$PORT/connect?user=root' OPTION_LIST='scrollable=1' +SELECT * FROM t1; +UPDATE t1 SET city = 'Phoenix' WHERE name = 'Henry'; +INSERT INTO t1 SELECT * FROM t3; +INSERT INTO t1 VALUES('Tom','Seatle','2002-03-15',NULL); +SELECT * FROM t1; +DROP TABLE t3; + +--echo # +--echo # Testing JDBC join operations +--echo # +CREATE TABLE t3 ( + name CHAR(9) NOT NULL, + city CHAR(12) NOT NULL, + age INT(2)) +engine=CONNECT table_type=FIX file_name='girls.txt'; +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN connect.boys b where g.city = b.city; +SELECT g.name, b.name, g.city FROM t3 g STRAIGHT_JOIN t1 b where g.city = b.city; +DROP TABLE t1, t3, connect.boys; + +--echo # +--echo # Testing MariaDB JDBC driver +--echo # +USE connect; +--copy_file $MTR_SUITE_DIR/std_data/employee.dat $MYSQLD_DATADIR/connect/employee.dat +CREATE TABLE emp ( + serialno CHAR(5) NOT NULL, + name VARCHAR(12) NOT NULL FLAG=6, + sex TINYINT(1) NOT NULL, + title VARCHAR(15) NOT NULL FLAG=20, + manager CHAR(5) NOT NULL, + department CHAR(4) NOT NULL FLAG=41, + secretary CHAR(5) NOT NULL FLAG=46, + salary DOUBLE(8,2) NOT NULL FLAG=52) +ENGINE=connect TABLE_TYPE=fix FILE_NAME='employee.dat' ENDING=1; +SELECT * FROM emp; + +USE test; +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME=emp CONNECTION='jdbc:mariadb://localhost:$PORT/connect?user=root' +--replace_result $PORT PORT +--eval SHOW CREATE TABLE t1 +SELECT * FROM t1; +SELECT name, title, salary FROM t1 WHERE sex = 1; + +DROP TABLE t1, connect.emp; + +# +# Testing remote command execution +# +--replace_result $PORT PORT +--eval CREATE TABLE t2 (command varchar(128) not null,number int(5) not null flag=1,message varchar(255) flag=2) ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:mariadb://localhost:$PORT/connect' OPTION_LIST='User=root,Execsrc=1' +SELECT * FROM t2 WHERE command='drop table tx1'; +SELECT * FROM t2 WHERE command = 'create table tx1 (a int not null, b char(32), c double(8,2))'; +SELECT * FROM t2 WHERE command in ('insert into tx1 values(1,''The number one'',456.12)',"insert into tx1(a,b) values(2,'The number two'),(3,'The number three')"); +SELECT * FROM t2 WHERE command='update tx1 set c = 3.1416 where a = 2'; +SELECT * FROM t2 WHERE command='select * from tx1'; +SELECT * FROM t2 WHERE command='delete from tx1 where a = 2'; +SELECT * FROM connect.tx1; +DROP TABLE t2; + +--replace_result $PORT PORT +--eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables CONNECTION='jdbc:mariadb://localhost:$PORT/connect' option_list='User=root,Maxres=50' +SELECT * FROM t1; +DROP TABLE t1; +DROP TABLE connect.tx1; + +# +# Clean up +# +--remove_file $MYSQLD_DATADIR/connect/boys.txt +--remove_file $MYSQLD_DATADIR/connect/employee.dat +DROP DATABASE connect; +--remove_file $MYSQLD_DATADIR/test/girls.txt + +-- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbc_new.test b/storage/connect/mysql-test/connect/t/jdbc_new.test new file mode 100644 index 0000000000000..33ec1b343cc88 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc_new.test @@ -0,0 +1,179 @@ +# +# This test is run against a remote MySQL server +# +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,); +connection master; + +-- source jdbconn.inc + +connection slave; +CREATE TABLE t1 (a int, b char(10)); +INSERT INTO t1 VALUES (NULL,NULL),(0,'test00'),(1,'test01'),(2,'test02'),(3,'test03'); +SELECT * FROM t1; + +--echo # +--echo # Testing errors +--echo # +connection master; + +# Bad user name +# Suppress "mysql_real_connect failed:" (printed in _DEBUG build) +--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " "" +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=unknown'; +--error ER_GET_ERRMSG +SELECT * FROM t1; +DROP TABLE t1; + +# Bad database name +--replace_result $SLAVE_MYPORT SLAVE_PORT "mysql_real_connect failed: " "" +--error ER_UNKNOWN_ERROR +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/unknown?user=root'; + +# Bad table name +--replace_result $SLAVE_MYPORT SLAVE_PORT +--error ER_UNKNOWN_ERROR +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='unknown' + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--error ER_NO_SUCH_TABLE +SHOW CREATE TABLE t1; + +# Bad column name +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (x int, y char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +--error ER_GET_ERRMSG +SELECT * FROM t1; +DROP TABLE t1; + +# The remote table disappeared +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; + +connection slave; +ALTER TABLE t1 RENAME t1backup; + +connection master; +--error ER_GET_ERRMSG +SELECT * FROM t1; + +connection slave; +ALTER TABLE t1backup RENAME t1; + +connection master; +DROP TABLE t1; + +--echo # +--echo # Testing SELECT, etc. +--echo # + +# Automatic table structure +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +# Explicit table structure +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a int, b char(10)) ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='t1' + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +# Explicit table structure: remote NULL, local NOT NULL +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a INT NOT NULL, b CHAR(10) NOT NULL) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +# Explicit table structure with wrong column types +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 (a char(10), b int) ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +--echo # +--echo # Testing numeric data types +--echo # + +# TODO: mediumint is converted to int, float is converted to double, decimal is converted to double +CREATE TABLE t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float, g double, h decimal(20,5)); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES(100,3333,41235,1234567890,235000000000,3.14159265,3.14159265,3141.59265); + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +--echo # +--echo # Testing character data types +--echo # + +CREATE TABLE t1 (a char(12), b varchar(12)); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES('Welcome','Hello, World'); +SELECT * FROM t1; + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +--echo # +--echo # Testing temporal data types +--echo # + +CREATE TABLE t1 (a date, b datetime, c time, d timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, e year); +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES('2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23','2003-05-27 10:45:23'); +SELECT * FROM t1; + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC + CONNECTION='jdbc:mysql://127.0.0.1:$SLAVE_MYPORT/test?user=root'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW CREATE TABLE t1; +SELECT * FROM t1; +DROP TABLE t1; + +connection slave; +DROP TABLE t1; + +connection master; +-- source jdbconn_cleanup.inc + diff --git a/storage/connect/mysql-test/connect/t/jdbc_oracle.test b/storage/connect/mysql-test/connect/t/jdbc_oracle.test new file mode 100644 index 0000000000000..10cb7a7b77dba --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc_oracle.test @@ -0,0 +1,56 @@ +-- source jdbconn.inc + +# +# This test is run against Oracle driver +# +CREATE TABLE t2 ( + command varchar(128) not null, + number int(5) not null flag=1, + message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager,Execsrc=1'; +SELECT * FROM t2 WHERE command = 'drop table employee'; +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))'; +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1 WHERE table_name='employee'; +DROP TABLE t1; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC TABNAME='EMPLOYEE' CATFUNC=columns +CONNECTION='jdbc:oracle:thin:@localhost:1521:xe' +OPTION_LIST='User=system,Password=manager'; +SELECT * FROM t1; +DROP TABLE t1; + +# +# Test connecting via a Federated server +# +CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS ( +HOST 'jdbc:oracle:thin:@localhost:1521:xe', +DATABASE 'SYSTEM', +USER 'system', +PASSWORD 'manager', +PORT 0, +SOCKET '', +OWNER 'SYSTEM'); + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='oracle' tabname='EMPLOYEE'; +SELECT * FROM t1; +INSERT INTO t1 VALUES(6214, 'Clinton', 'Retired', NULL); +UPDATE t1 set name='Trump' WHERE id = 4567; +SELECT * FROM t1; +DELETE FROM t1 WHERE id = 6214; +SELECT * FROM t1; +DROP TABLE t1; +SELECT * FROM t2 WHERE command = 'drop table employee'; +DROP TABLE t2; +DROP SERVER 'oracle'; + +# +# Clean up +# + +-- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbc_postgresql.test b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test new file mode 100644 index 0000000000000..1041ef468d7b8 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbc_postgresql.test @@ -0,0 +1,53 @@ +-- source jdbconn.inc + +# +# This test is run against Postgresql driver +# +CREATE TABLE t2 ( + command varchar(128) not null, + number int(5) not null flag=1, + message varchar(255) flag=2) +ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Execsrc=1'; +SELECT * FROM t2 WHERE command='drop table employee'; +SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary decimal(8,2))'; +SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)"; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables +CONNECTION='jdbc:postgresql://localhost/mtr' +OPTION_LIST='User=mtr,Password=mtr,Schema=public,Tabtype=TABLE,Maxres=10'; +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=columns +CONNECTION='jdbc:postgresql://localhost/mtr' tabname=employee +OPTION_LIST='User=mtr,Password=mtr,Maxres=10'; +SELECT * FROM t1; +DROP TABLE t1; + +# +# Test connecting via a Federated server +# +CREATE SERVER 'postgresql' FOREIGN DATA WRAPPER 'postgresql' OPTIONS ( +HOST 'localhost', +DATABASE 'mtr', +USER 'mtr', +PASSWORD 'mtr', +PORT 0, +SOCKET '', +OWNER 'root'); + +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CONNECTION='postgresql/public.employee'; +SELECT * FROM t1; +INSERT INTO t1 VALUES(3126,'Smith', 'Clerk', 5230.00); +UPDATE t1 SET salary = salary + 100.00; +SELECT * FROM t1; +DROP TABLE t1; +DROP SERVER 'postgresql'; +SELECT * FROM t2 WHERE command='drop table employee'; +DROP TABLE t2; + +# +# Clean up +# +-- source jdbconn_cleanup.inc diff --git a/storage/connect/mysql-test/connect/t/jdbconn.inc b/storage/connect/mysql-test/connect/t/jdbconn.inc new file mode 100644 index 0000000000000..0bac0b35fc420 --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbconn.inc @@ -0,0 +1,31 @@ +--source include/not_embedded.inc + +--disable_query_log +--error 0,ER_UNKNOWN_ERROR +CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=drivers; +if (!`SELECT count(*) FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1' + AND ENGINE='CONNECT' + AND (CREATE_OPTIONS LIKE "%`table_type`='JDBC'%" OR CREATE_OPTIONS LIKE '%`table_type`=JDBC%')`) +{ + Skip Need Java support; +} +DROP TABLE t1; + +# This is specific and explains why this test is disabled. +# You should edit this file to reflect what is the required files location on your machine. +# This is the path to the JVM library (dll or so) +SET GLOBAL connect_jvm_path='C:\\Program Files\\Java\\jdk1.8.0_77\\jre\\bin\\client'; + +# The complete class path send when creating the Java Virtual Machine is, in that order: +# 1 - The current directory. +# 2 - The paths of the connect_class_path global variable. +# 3 - The paths of the CLASSPATH environment variable. +# These are the paths to the needed classes or jar files. The Apache ones are only for the JdbcApacheInterface wrapper. +SET GLOBAL connect_class_path='E:\\MariaDB-10.1\\Connect\\storage\\connect;E:\\MariaDB-10.1\\Connect\\sql\\data\\postgresql-9.4.1208.jar;E:\\Oracle\\ojdbc6.jar;E:\\Apache\\commons-dbcp2-2.1.1\\commons-dbcp2-2.1.1.jar;E:\\Apache\\commons-pool2-2.4.2\\commons-pool2-2.4.2.jar;E:\\Apache\\commons-logging-1.2\\commons-logging-1.2.jar'; + +# On my machine, paths to the JDK classes and to the MySQL and MariaDB drivers are defined in the CLASSPATH environment variable +#CREATE FUNCTION envar RETURNS STRING SONAME 'ha_connect.dll'; +#SELECT envar('CLASSPATH'); + +--enable_query_log diff --git a/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc b/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc new file mode 100644 index 0000000000000..48e321495aded --- /dev/null +++ b/storage/connect/mysql-test/connect/t/jdbconn_cleanup.inc @@ -0,0 +1,6 @@ +--disable_warnings +#DROP FUNCTION envar; +SET GLOBAL connect_jvm_path=NULL; +SET GLOBAL connect_class_path=NULL; +SET GLOBAL time_zone = SYSTEM; +--enable_warnings diff --git a/storage/connect/tabcol.cpp b/storage/connect/tabcol.cpp index 662c0b514cf73..fde1baa631724 100644 --- a/storage/connect/tabcol.cpp +++ b/storage/connect/tabcol.cpp @@ -50,7 +50,7 @@ XTAB::XTAB(PTABLE tp) : Name(tp->Name) Qualifier = tp->Qualifier; if (trace) - htrc(" making copy TABLE %s %s\n", Name, Srcdef); + htrc(" making copy TABLE %s %s\n", Name, SVP(Srcdef)); } // end of XTAB constructor diff --git a/storage/connect/tabtbl.cpp b/storage/connect/tabtbl.cpp index 36849146746d0..e3baf7c3da5b0 100644 --- a/storage/connect/tabtbl.cpp +++ b/storage/connect/tabtbl.cpp @@ -569,6 +569,9 @@ pthread_handler_t ThreadOpen(void *p) if (!my_thread_init()) { set_current_thd(cmp->Thd); + if (trace) + htrc("ThreadOpen: Thd=%d\n", cmp->Thd); + // Try to open the connection if (!cmp->Tap->GetTo_Tdb()->OpenDB(cmp->G)) { cmp->Ready = true; @@ -604,9 +607,14 @@ void TDBTBM::ResetDB(void) if (colp->GetAmType() == TYPE_AM_TABID) colp->COLBLK::Reset(); + // Local tables for (PTABLE tabp = Tablist; tabp; tabp = tabp->GetNext()) ((PTDBASE)tabp->GetTo_Tdb())->ResetDB(); + // Remote tables + for (PTBMT tp = Tmp; tp; tp = tp->Next) + ((PTDBASE)tp->Tap->GetTo_Tdb())->ResetDB(); + Tdbp = (Tablist) ? (PTDBASE)Tablist->GetTo_Tdb() : NULL; Crp = 0; } // end of ResetDB From d6a1bae57f369d6d1781b94696b87e81e39be4ca Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 13 Jun 2016 17:10:31 +0400 Subject: [PATCH 053/112] MDEV-10218 - rpl.rpl_binlog_errors fails in buildbot with valgrind warnings - bytes are possibly lost Restored suppressions removed by MDEV-9994: they're needed for detached threads. --- mysql-test/valgrind.supp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 16b59b8a06fa3..b86cbd23408fc 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -1047,3 +1047,22 @@ fun:_nss_dns_gethostbyaddr_r fun:gethostbyaddr_r } + + +# +# Detached threads may not complete deiniitialization by the time shutdown +# thread calls exit. This is unfortunate property of detached threads, which +# we currently can only ignore. Unfortunately there is no way to distinguish +# between false positives generated by detached threads and real memory leaks +# generated by not joined joinable threads. So we hide both cases. +# +# To avoid enumeration of the whole variety of possible traces we ignore all +# "possibly lost" blocks allocated by pthread_create (and it's callees). +# +{ + Detached threads memory loss + Memcheck:Leak + match-leak-kinds:possible + ... + fun:pthread_create* +} From f54dcf1e8742e19d13ab7fb8b92ae6a179e67fe3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jun 2016 12:38:47 +0200 Subject: [PATCH 054/112] 5.5.49-37.9 --- storage/xtradb/dict/dict0crea.c | 4 +-- storage/xtradb/handler/ha_innodb.cc | 2 +- storage/xtradb/include/os0sync.h | 47 ++++++++++++++-------------- storage/xtradb/include/univ.i | 2 +- storage/xtradb/log/log0recv.c | 4 +-- storage/xtradb/os/os0file.c | 48 ++++++++++++++++++++++++++++- 6 files changed, 76 insertions(+), 31 deletions(-) diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index 44ebca8337385..b950c2d9b3f5c 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1255,7 +1255,7 @@ dict_create_index_step( >= DICT_TF_FORMAT_ZIP); node->index = dict_index_get_if_in_cache_low(index_id); - ut_a((node->index == 0) == (err != DB_SUCCESS)); + ut_a((node->index == NULL) == (err != DB_SUCCESS)); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index effff7cf0c4c9..896b27a204785 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -12605,7 +12605,7 @@ innodb_buffer_pool_evict_update( mutex_enter(&block->mutex); buf_LRU_free_block(&block->page, - FALSE, FALSE); + FALSE, TRUE); mutex_exit(&block->mutex); block = prev_block; } diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 83647fe336788..d7dee5e056767 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -41,7 +41,6 @@ Created 9/6/1995 Heikki Tuuri || defined _M_X64 || defined __WIN__ #define IB_STRONG_MEMORY_MODEL -#undef HAVE_IB_GCC_ATOMIC_TEST_AND_SET // Quick-and-dirty fix for bug 1519094 #endif /* __i386__ || __x86_64__ || _M_IX86 || M_X64 || __WIN__ */ @@ -332,28 +331,7 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */ # define os_atomic_test_and_set_byte(ptr, new_val) \ __sync_lock_test_and_set(ptr, (byte) new_val) -# if defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) - -/** Do an atomic test-and-set. -@param[in,out] ptr Memory location to set to non-zero -@return the previous value */ -static inline -lock_word_t -os_atomic_test_and_set(volatile lock_word_t* ptr) -{ - return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); -} - -/** Do an atomic clear. -@param[in,out] ptr Memory location to set to zero */ -static inline -void -os_atomic_clear(volatile lock_word_t* ptr) -{ - __atomic_clear(ptr, __ATOMIC_RELEASE); -} - -# elif defined(IB_STRONG_MEMORY_MODEL) +# if defined(IB_STRONG_MEMORY_MODEL) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero @@ -382,6 +360,27 @@ os_atomic_clear(volatile lock_word_t* ptr) return(__sync_lock_test_and_set(ptr, 0)); } +# elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) + +/** Do an atomic test-and-set. +@param[in,out] ptr Memory location to set to non-zero +@return the previous value */ +static inline +lock_word_t +os_atomic_test_and_set(volatile lock_word_t* ptr) +{ + return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); +} + +/** Do an atomic clear. +@param[in,out] ptr Memory location to set to zero */ +static inline +void +os_atomic_clear(volatile lock_word_t* ptr) +{ + __atomic_clear(ptr, __ATOMIC_RELEASE); +} + # else # error "Unsupported platform" diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 4814a07d3a4d7..d5ec85ce99539 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 37.8 +#define PERCONA_INNODB_VERSION 37.9 #endif #define INNODB_VERSION_STR MYSQL_SERVER_VERSION diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index f9eddec4b4acd..3429361c74c8b 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1837,7 +1837,7 @@ recv_apply_hashed_log_recs( goto loop; } - ut_ad((allow_ibuf == 0) == (mutex_own(&log_sys->mutex) != 0)); + ut_ad((!allow_ibuf) == mutex_own(&log_sys->mutex)); if (!allow_ibuf) { recv_no_ibuf_operations = TRUE; diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c index 6e1b59aba12e1..21f8c3eed117a 100644 --- a/storage/xtradb/os/os0file.c +++ b/storage/xtradb/os/os0file.c @@ -386,6 +386,43 @@ os_get_os_version(void) } #endif /* __WIN__ */ +/***********************************************************************//** +For an EINVAL I/O error, prints a diagnostic message if innodb_flush_method +== ALL_O_DIRECT. +@return TRUE if the diagnostic message was printed +@return FALSE if the diagnostic message does not apply */ +static +ibool +os_diagnose_all_o_direct_einval( +/*============================*/ + ulint err) /*!< in: C error code */ +{ + if ((err == EINVAL) + && (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT)) { + fprintf(stderr, + "InnoDB: The error might be caused by redo log I/O " + "not satisfying innodb_flush_method=ALL_O_DIRECT " + "requirements by the underlying file system.\n"); + if (srv_log_block_size != 512) + fprintf(stderr, + "InnoDB: This might be caused by an " + "incompatible non-default " + "innodb_log_block_size value %lu.\n", + srv_log_block_size); + fprintf(stderr, + "InnoDB: Please file a bug at " + "https://bugs.percona.com and include this error " + "message, my.cnf settings, and information about the " + "file system where the redo log resides.\n"); + fprintf(stderr, + "InnoDB: A possible workaround is to change " + "innodb_flush_method value to something else " + "than ALL_O_DIRECT.\n"); + return(TRUE); + } + return(FALSE); +} + /***********************************************************************//** Retrieves the last error number if an error occurs in a file io function. The number should be retrieved before any other OS calls (because they may @@ -511,7 +548,7 @@ os_file_get_last_error( "InnoDB: The error means mysqld does not have" " the access rights to\n" "InnoDB: the directory.\n"); - } else { + } else if (!os_diagnose_all_o_direct_einval(err)) { if (strerror((int)err) != NULL) { fprintf(stderr, "InnoDB: Error number %lu" @@ -2513,6 +2550,9 @@ os_file_pwrite( /* Handle partial writes and signal interruptions correctly */ for (ret = 0; ret < (ssize_t) n; ) { n_written = pwrite(file, buf, (ssize_t)n - ret, offs); + DBUG_EXECUTE_IF("xb_simulate_all_o_direct_write_failure", + n_written = -1; + errno = EINVAL;); if (n_written >= 0) { ret += n_written; offs += n_written; @@ -2702,6 +2742,10 @@ os_file_read_func( try_again: ret = os_file_pread(file, buf, n, offset, offset_high, trx); + DBUG_EXECUTE_IF("xb_simulate_all_o_direct_read_failure", + ret = -1; + errno = EINVAL;); + if ((ulint)ret == n) { return(TRUE); @@ -3066,6 +3110,8 @@ os_file_write_func( "InnoDB: " REFMAN "operating-system-error-codes.html\n"); + os_diagnose_all_o_direct_einval(errno); + os_has_said_disk_full = TRUE; } From 1b50d599606244677215fbe7b05be1a891fecf18 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 14 Jun 2016 14:44:09 +0400 Subject: [PATCH 055/112] MDEV-9945 - main.kill_processlist-6619 fails sporadically SHOW PROCESSLIST output can be affected by not completed concurrent KILL QUERY. Filter out more column values to make output stable. --- mysql-test/r/kill_processlist-6619.result | 4 ++-- mysql-test/t/kill_processlist-6619.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/kill_processlist-6619.result b/mysql-test/r/kill_processlist-6619.result index a3d971e211568..f14727f1696c3 100644 --- a/mysql-test/r/kill_processlist-6619.result +++ b/mysql-test/r/kill_processlist-6619.result @@ -6,5 +6,5 @@ SHOW PROCESSLIST; ERROR 70100: Query execution was interrupted SHOW PROCESSLIST; Id User Host db Command Time State Info Progress -# root # test Sleep # # NULL 0.000 -# root # test Query # # SHOW PROCESSLIST 0.000 +# root # test # # # # 0.000 +# root # test # # # # 0.000 diff --git a/mysql-test/t/kill_processlist-6619.test b/mysql-test/t/kill_processlist-6619.test index d73859ce8cdb9..28f98bcbb2490 100644 --- a/mysql-test/t/kill_processlist-6619.test +++ b/mysql-test/t/kill_processlist-6619.test @@ -11,5 +11,5 @@ eval KILL QUERY $con_id; --connection con1 --error ER_QUERY_INTERRUPTED SHOW PROCESSLIST; ---replace_column 1 # 3 # 6 # 7 # +--replace_column 1 # 3 # 5 # 6 # 7 # 8 # SHOW PROCESSLIST; From 90eb30266bd88f9b101054ceb67d30ed4eee76e6 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jun 2016 13:57:49 +0200 Subject: [PATCH 056/112] fix main.ssl_ca from mysql-5.5.50 1. to work for OpenSSL 2. to work when $HOME can match in the middle of $MYSQL_TEST_DIR --- mysql-test/t/ssl_ca.test | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/mysql-test/t/ssl_ca.test b/mysql-test/t/ssl_ca.test index 92695de4b0d92..e0a5fa9ad0709 100644 --- a/mysql-test/t/ssl_ca.test +++ b/mysql-test/t/ssl_ca.test @@ -10,6 +10,7 @@ --exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/wrong-cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" 2>&1 --echo # try to connect with correct '--ssl-ca' path : should connect +--replace_result DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA --exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" --echo # @@ -17,19 +18,19 @@ --echo # PATH SUBSTITUTION --echo # ---let $mysql_test_dir_path= `SELECT REPLACE('$MYSQL_TEST_DIR', '$HOME', '~')` +--let $mysql_test_dir_path= `SELECT REPLACE('=$MYSQL_TEST_DIR', '=$HOME', '=~')` --echo # try to connect with '--ssl-ca' option using tilde home directoy --echo # path substitution : should connect ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL --ssl-ca=$mysql_test_dir_path/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" +--replace_result DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA +--exec $MYSQL --ssl-ca$mysql_test_dir_path/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" --echo # try to connect with '--ssl-key' option using tilde home directoy --echo # path substitution : should connect ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$mysql_test_dir_path/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" +--replace_result DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA +--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key$mysql_test_dir_path/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" --echo # try to connect with '--ssl-cert' option using tilde home directoy --echo # path substitution : should connect ---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR ---exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$mysql_test_dir_path/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" +--replace_result DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA +--exec $MYSQL --ssl-ca=$MYSQL_TEST_DIR/std_data/cacert.pem --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert$mysql_test_dir_path/std_data/client-cert.pem test -e "SHOW STATUS LIKE 'Ssl_cipher'" From c3c272cca45205b8ffc5c44b2cce136576649967 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 10 Jun 2016 13:47:00 +0200 Subject: [PATCH 057/112] MDEV-10166 probes_mysql_nodtrace.h is not provided anymore by mariadb-10.0.25 backport of commit bba3d42 Author: Sergei Golubchik Date: Sat Apr 30 10:27:42 2016 +0200 MDEV-9926 probes_mysql.h includes nonexisting files install private generated files --- include/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 33eaa28ae1e3f..219a2917917fe 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -69,3 +69,9 @@ INSTALL(DIRECTORY . DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Developm PATTERN CMakeFiles EXCLUDE PATTERN mysql EXCLUDE REGEX "\\./(${EXCL_RE}$)" EXCLUDE) + +INSTALL(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/. DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development + FILES_MATCHING PATTERN "*.h" + PATTERN CMakeFiles EXCLUDE + PATTERN mysql EXCLUDE + REGEX "\\./(${EXCL_RE}$)" EXCLUDE) From c73b987e73343d49c0b98666552d7aeb1a9799da Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jun 2016 13:18:05 +0200 Subject: [PATCH 058/112] MDEV-8328 Evaluation of two "!" operators depends on space in beetween fix the lexer to backtrack when parsing "<=", "<>", "!=", ">=", "<<", ">>", "<=>". --- mysql-test/r/parser.result | 20 +++++ .../suite/plugins/r/server_audit.result | 2 +- .../plugins/r/thread_pool_server_audit.result | 2 +- mysql-test/t/parser.test | 12 +++ sql/lex.h | 3 - sql/sql_lex.cc | 29 +++---- sql/sql_yacc.yy | 77 +++++++++---------- 7 files changed, 87 insertions(+), 58 deletions(-) diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 915ace0c1b4ca..25143f97d9ae6 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -643,3 +643,23 @@ CREATE TRIGGER trigger1 BEFORE INSERT ON t1 FOR EACH ROW SET default_storage_engine = NEW.INNODB; ERROR 42S22: Unknown column 'INNODB' in 'NEW' DROP TABLE t1; +select 0==0; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '=0' at line 1 +select 1=!0, 1 = ! 0; +1=!0 1 = ! 0 +1 1 +select !!0, ! ! 0; +!!0 ! ! 0 +0 0 +select 2>!0, 2 > ! 0; +2>!0 2 > ! 0 +1 1 +select 0<=!0, 0 <= !0; +0<=!0 0 <= !0 +1 1 +select 1<; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '=' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 CREATE USER u3 IDENTIFIED BY ''; drop user u1, u2, u3; select 2; diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result index 6733850600111..2dcfa107103a3 100644 --- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result +++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result @@ -165,7 +165,7 @@ CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; SET PASSWORD FOR u1 = PASSWORD('pwd 098'); SET PASSWORD FOR u1=; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '=' at line 1 +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 CREATE USER u3 IDENTIFIED BY ''; drop user u1, u2, u3; select 2; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 6899e2876a615..c6aa892784836 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -758,3 +758,15 @@ CREATE TABLE t1 (s VARCHAR(100)); CREATE TRIGGER trigger1 BEFORE INSERT ON t1 FOR EACH ROW SET default_storage_engine = NEW.INNODB; DROP TABLE t1; + +# +# MDEV-8328 Evaluation of two "!" operators depends on space in beetween +# +--error ER_PARSE_ERROR +select 0==0; +select 1=!0, 1 = ! 0; +select !!0, ! ! 0; +select 2>!0, 2 > ! 0; +select 0<=!0, 0 <= !0; +select 1<", SYM(NE)}, { "!=", SYM(NE)}, - { "=", SYM(EQ)}, - { ">", SYM(GT_SYM)}, { ">=", SYM(GE)}, { "<<", SYM(SHIFT_LEFT)}, { ">>", SYM(SHIFT_RIGHT)}, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7b8b37f61fd33..ee0e09acbf999 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1452,32 +1452,35 @@ static int lex_one_token(YYSTYPE *yylval, THD *thd) return (BIN_NUM); case MY_LEX_CMP_OP: // Incomplete comparison operator + lip->next_state= MY_LEX_START; // Allow signed numbers if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP || state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP) - lip->yySkip(); - if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0))) { - lip->next_state= MY_LEX_START; // Allow signed numbers - return(tokval); + lip->yySkip(); + if ((tokval= find_keyword(lip, 2, 0))) + return(tokval); + lip->yyUnget(); } - state = MY_LEX_CHAR; // Something fishy found - break; + return(c); case MY_LEX_LONG_CMP_OP: // Incomplete comparison operator + lip->next_state= MY_LEX_START; if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP || state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP) { lip->yySkip(); if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP) + { lip->yySkip(); + if ((tokval= find_keyword(lip, 3, 0))) + return(tokval); + lip->yyUnget(); + } + if ((tokval= find_keyword(lip, 2, 0))) + return(tokval); + lip->yyUnget(); } - if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0))) - { - lip->next_state= MY_LEX_START; // Found long op - return(tokval); - } - state = MY_LEX_CHAR; // Something fishy found - break; + return(c); case MY_LEX_BOOL: if (c != lip->yyPeek()) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2cb02059ba4a1..50484e08b3f00 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -970,7 +970,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ENGINES_SYM %token ENGINE_SYM %token ENUM -%token EQ /* OPERATOR */ %token EQUAL_SYM /* OPERATOR */ %token ERROR_SYM %token ERRORS @@ -1016,7 +1015,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token GRANTS %token GROUP_SYM /* SQL-2003-R */ %token GROUP_CONCAT_SYM -%token GT_SYM /* OPERATOR */ %token HANDLER_SYM %token HARD_SYM %token HASH_SYM @@ -1095,7 +1093,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token LONG_SYM %token LOOP_SYM %token LOW_PRIORITY -%token LT /* OPERATOR */ %token MASTER_CONNECT_RETRY_SYM %token MASTER_HOST_SYM %token MASTER_LOG_FILE_SYM @@ -1439,7 +1436,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %left XOR %left AND_SYM AND_AND_SYM %left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE -%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM +%left '=' EQUAL_SYM GE '>' LE '<' NE IS LIKE REGEXP IN_SYM %left '|' %left '&' %left SHIFT_LEFT SHIFT_RIGHT @@ -1922,58 +1919,58 @@ master_defs: ; master_def: - MASTER_HOST_SYM EQ TEXT_STRING_sys + MASTER_HOST_SYM '=' TEXT_STRING_sys { Lex->mi.host = $3.str; } - | MASTER_USER_SYM EQ TEXT_STRING_sys + | MASTER_USER_SYM '=' TEXT_STRING_sys { Lex->mi.user = $3.str; } - | MASTER_PASSWORD_SYM EQ TEXT_STRING_sys + | MASTER_PASSWORD_SYM '=' TEXT_STRING_sys { Lex->mi.password = $3.str; } - | MASTER_PORT_SYM EQ ulong_num + | MASTER_PORT_SYM '=' ulong_num { Lex->mi.port = $3; } - | MASTER_CONNECT_RETRY_SYM EQ ulong_num + | MASTER_CONNECT_RETRY_SYM '=' ulong_num { Lex->mi.connect_retry = $3; } - | MASTER_SSL_SYM EQ ulong_num + | MASTER_SSL_SYM '=' ulong_num { Lex->mi.ssl= $3 ? LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE; } - | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CA_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_ca= $3.str; } - | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CAPATH_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_capath= $3.str; } - | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CERT_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_cert= $3.str; } - | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys + | MASTER_SSL_CIPHER_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_cipher= $3.str; } - | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys + | MASTER_SSL_KEY_SYM '=' TEXT_STRING_sys { Lex->mi.ssl_key= $3.str; } - | MASTER_SSL_VERIFY_SERVER_CERT_SYM EQ ulong_num + | MASTER_SSL_VERIFY_SERVER_CERT_SYM '=' ulong_num { Lex->mi.ssl_verify_server_cert= $3 ? LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE; } - | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal + | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal { Lex->mi.heartbeat_period= (float) $3->val_real(); if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD || @@ -2004,7 +2001,7 @@ master_def: } Lex->mi.heartbeat_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; } - | IGNORE_SERVER_IDS_SYM EQ '(' ignore_server_id_list ')' + | IGNORE_SERVER_IDS_SYM '=' '(' ignore_server_id_list ')' { Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE; } @@ -2025,11 +2022,11 @@ ignore_server_id: } master_file_def: - MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys + MASTER_LOG_FILE_SYM '=' TEXT_STRING_sys { Lex->mi.log_file_name = $3.str; } - | MASTER_LOG_POS_SYM EQ ulonglong_num + | MASTER_LOG_POS_SYM '=' ulonglong_num { Lex->mi.pos = $3; /* @@ -2045,11 +2042,11 @@ master_file_def: */ Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos); } - | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys + | RELAY_LOG_FILE_SYM '=' TEXT_STRING_sys { Lex->mi.relay_log_name = $3.str; } - | RELAY_LOG_POS_SYM EQ ulong_num + | RELAY_LOG_POS_SYM '=' ulong_num { Lex->mi.relay_log_pos = $3; /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */ @@ -3032,7 +3029,7 @@ opt_set_signal_information: ; signal_information_item_list: - signal_condition_information_item_name EQ signal_allowed_expr + signal_condition_information_item_name '=' signal_allowed_expr { Set_signal_information *info; info= &thd->m_parser_state->m_yacc.m_set_signal_info; @@ -3041,7 +3038,7 @@ signal_information_item_list: info->m_item[index]= $3; } | signal_information_item_list ',' - signal_condition_information_item_name EQ signal_allowed_expr + signal_condition_information_item_name '=' signal_allowed_expr { Set_signal_information *info; info= &thd->m_parser_state->m_yacc.m_set_signal_info; @@ -4439,7 +4436,7 @@ opt_linear: opt_key_algo: /* empty */ { Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_NONE;} - | ALGORITHM_SYM EQ real_ulong_num + | ALGORITHM_SYM '=' real_ulong_num { switch ($3) { case 1: @@ -7076,7 +7073,7 @@ opt_place: opt_to: /* empty */ {} | TO_SYM {} - | EQ {} + | '=' {} | AS {} ; @@ -7943,13 +7940,13 @@ bool_pri: if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri comp_op predicate %prec EQ + | bool_pri comp_op predicate %prec '=' { $$= (*$2)(0)->create($1,$3); if ($$ == NULL) MYSQL_YYABORT; } - | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ + | bool_pri comp_op all_or_any '(' subselect ')' %prec '=' { $$= all_any_subquery_creator($1, $2, $3, $5); if ($$ == NULL) @@ -8172,11 +8169,11 @@ not2: ; comp_op: - EQ { $$ = &comp_eq_creator; } + '=' { $$ = &comp_eq_creator; } | GE { $$ = &comp_ge_creator; } - | GT_SYM { $$ = &comp_gt_creator; } + | '>' { $$ = &comp_gt_creator; } | LE { $$ = &comp_le_creator; } - | LT { $$ = &comp_lt_creator; } + | '<' { $$ = &comp_lt_creator; } | NE { $$ = &comp_ne_creator; } ; @@ -10197,7 +10194,7 @@ date_time_type: table_alias: /* empty */ | AS - | EQ + | '=' ; opt_table_alias: @@ -11100,7 +11097,7 @@ ident_eq_value: ; equal: - EQ {} + '=' {} | SET_VAR {} ; @@ -13968,11 +13965,11 @@ handler_rkey_function: ; handler_rkey_mode: - EQ { $$=HA_READ_KEY_EXACT; } + '=' { $$=HA_READ_KEY_EXACT; } | GE { $$=HA_READ_KEY_OR_NEXT; } | LE { $$=HA_READ_KEY_OR_PREV; } - | GT_SYM { $$=HA_READ_AFTER_KEY; } - | LT { $$=HA_READ_BEFORE_KEY; } + | '>' { $$=HA_READ_AFTER_KEY; } + | '<' { $$=HA_READ_BEFORE_KEY; } ; /* GRANT / REVOKE */ @@ -14744,7 +14741,7 @@ no_definer: ; definer: - DEFINER_SYM EQ user + DEFINER_SYM '=' user { thd->lex->definer= get_current_user(thd, $3); } @@ -14771,11 +14768,11 @@ view_replace: ; view_algorithm: - ALGORITHM_SYM EQ UNDEFINED_SYM + ALGORITHM_SYM '=' UNDEFINED_SYM { Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; } - | ALGORITHM_SYM EQ MERGE_SYM + | ALGORITHM_SYM '=' MERGE_SYM { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; } - | ALGORITHM_SYM EQ TEMPTABLE_SYM + | ALGORITHM_SYM '=' TEMPTABLE_SYM { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; } ; From a4cfd32125a76a3818f1ad1e2b0ed455329ec26f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jun 2016 14:52:43 +0200 Subject: [PATCH 059/112] main.openssl_1 failure don't test a cipher that was removed from recent openssl versions --- mysql-test/r/openssl_1.result | 2 -- mysql-test/t/openssl_1.test | 1 - 2 files changed, 3 deletions(-) diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 44ea5795a95ec..a49a12c230d00 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -198,8 +198,6 @@ Ssl_cipher DHE-RSA-AES256-SHA Variable_name Value Ssl_cipher EDH-RSA-DES-CBC3-SHA Variable_name Value -Ssl_cipher EDH-RSA-DES-CBC-SHA -Variable_name Value Ssl_cipher RC4-SHA select 'is still running; no cipher request crashed the server' as result from dual; result diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index 1b28c40c0bf4f..62b5c9c10e022 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -222,7 +222,6 @@ DROP TABLE t1; # Common ciphers to openssl and yassl --exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=DHE-RSA-AES256-SHA --exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=EDH-RSA-DES-CBC3-SHA ---exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=EDH-RSA-DES-CBC-SHA --exec $MYSQL --host=localhost -e "SHOW STATUS LIKE 'Ssl_cipher';" --ssl-cipher=RC4-SHA --disable_query_log --disable_result_log From 05bb3b9f85d68cc0e99a7b43c8b40cc07d272d76 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 14 Jun 2016 16:28:07 +0200 Subject: [PATCH 060/112] fix main.ssl_ca test for windows where $HOME is the empty string --- mysql-test/t/ssl_ca.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/ssl_ca.test b/mysql-test/t/ssl_ca.test index e0a5fa9ad0709..3652040dd0b7b 100644 --- a/mysql-test/t/ssl_ca.test +++ b/mysql-test/t/ssl_ca.test @@ -18,7 +18,7 @@ --echo # PATH SUBSTITUTION --echo # ---let $mysql_test_dir_path= `SELECT REPLACE('=$MYSQL_TEST_DIR', '=$HOME', '=~')` +--let $mysql_test_dir_path= `SELECT IF(LENGTH('$HOME'), REPLACE('=$MYSQL_TEST_DIR', '=$HOME', '=~'), '=$MYSQL_TEST_DIR')` --echo # try to connect with '--ssl-ca' option using tilde home directoy --echo # path substitution : should connect From cf721d23cc90e7848b0611180b9777d080a1faf6 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 10 Dec 2015 17:00:14 +1100 Subject: [PATCH 061/112] MDEV-9257: Increase limit on parallel workers in mysql-test-run Signed-off-by: Daniel Black --- mysql-test/mysql-test-run.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 26b31d34d3c9e..63b18c6bebd10 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1801,9 +1801,12 @@ ($) if ( lc($opt_build_thread) eq 'auto' ) { my $found_free = 0; $build_thread = 300; # Start attempts from here + my $build_thread_upper = $build_thread + ($opt_parallel > 1500 + ? 3000 + : 2 * $opt_parallel); while (! $found_free) { - $build_thread= mtr_get_unique_id($build_thread, 349); + $build_thread= mtr_get_unique_id($build_thread, $build_thread_upper); if ( !defined $build_thread ) { mtr_error("Could not get a unique build thread id"); } From 0089af8e1c767ed34ff8d92428beacf50fa97e79 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 13 Jun 2016 18:11:31 +0300 Subject: [PATCH 062/112] MDEV-9433: [PATCH] cppcheck reported a number of minor coding errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a bug in testhash.c that caused an out of bounds memory access when command line parameters specified 0 records to be inserted in the hashtable. Signed-off-by: VicenÈ›iu Ciorbaru --- mysys/testhash.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysys/testhash.c b/mysys/testhash.c index ffdaaece7706c..aa78a2d8c4040 100644 --- a/mysys/testhash.c +++ b/mysys/testhash.c @@ -169,7 +169,9 @@ static int do_test() for (j=0 ; j < 1000 ; j++) if (key1[j] > 1) break; - if (key1[j] > 1) + // j will be 1000 only if we have no keys in the hash. This only happens + // when the parameter recant is set to 0 via command line argument. + if (j < 1000 && key1[j] > 1) { HASH_SEARCH_STATE state; printf("- Testing identical read\n"); From bfef17bec193d8c965604ad29d4b4b9f800bccac Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 13 Jun 2016 18:30:02 +0300 Subject: [PATCH 063/112] MDEV-9433: [PATCH} cppcheck reported a number of minor coding errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix cppwarning of va_args being opened but not closed. Signed-off-by: VicenÈ›iu Ciorbaru --- mysys/mf_iocache.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 02e5c5373ae33..31a09e214d268 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1874,6 +1874,7 @@ void die(const char* fmt, ...) fprintf(stderr,"Error:"); vfprintf(stderr, fmt,va_args); fprintf(stderr,", errno=%d\n", errno); + va_end(va_args); exit(1); } From 6a34ba313005ab861bc9c38b6f9d0624ff17a026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Tue, 16 Feb 2016 16:15:22 +0200 Subject: [PATCH 064/112] [Code cleanup] Refactor duplicate code within myisam and maria sort.cc --- storage/maria/ma_sort.c | 62 +++++++++++++++++---------------------- storage/myisam/sort.c | 64 +++++++++++++++++------------------------ 2 files changed, 53 insertions(+), 73 deletions(-) diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index 95454d88308fd..ce17446eea784 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -86,6 +86,27 @@ static int write_merge_key_varlen(MARIA_SORT_PARAM *info, static inline int my_var_write(MARIA_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs); +/* + Sets the appropriate read and write methods for the MARIA_SORT_PARAM + based on the variable length key flag. +*/ +static void set_sort_param_read_write(MARIA_SORT_PARAM *sort_param) +{ + if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) + { + sort_param->write_keys= write_keys_varlen; + sort_param->read_to_buffer= read_to_buffer_varlen; + sort_param->write_key= write_merge_key_varlen; + } + else + { + sort_param->write_keys= write_keys; + sort_param->read_to_buffer= read_to_buffer; + sort_param->write_key= write_merge_key; + } +} + + /* Creates a index of sorted keys @@ -115,18 +136,7 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, (ulong) sortbuff_size, info->key_length, (ulong) info->sort_info->max_records)); - if (info->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - info->write_keys= write_keys_varlen; - info->read_to_buffer=read_to_buffer_varlen; - info->write_key=write_merge_key_varlen; - } - else - { - info->write_keys= write_keys; - info->read_to_buffer=read_to_buffer; - info->write_key=write_merge_key; - } + set_sort_param_read_write(info); my_b_clear(&tempfile); my_b_clear(&tempfile_for_exceptions); @@ -347,18 +357,7 @@ pthread_handler_t _ma_thr_find_all_keys(void *arg) if (sort_param->sort_info->got_error) goto err; - if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - sort_param->write_keys= write_keys_varlen; - sort_param->read_to_buffer= read_to_buffer_varlen; - sort_param->write_key= write_merge_key_varlen; - } - else - { - sort_param->write_keys= write_keys; - sort_param->read_to_buffer= read_to_buffer; - sort_param->write_key= write_merge_key; - } + set_sort_param_read_write(sort_param); my_b_clear(&sort_param->tempfile); my_b_clear(&sort_param->tempfile_for_exceptions); @@ -564,18 +563,9 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param) { if (got_error) continue; - if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - sinfo->write_keys=write_keys_varlen; - sinfo->read_to_buffer=read_to_buffer_varlen; - sinfo->write_key=write_merge_key_varlen; - } - else - { - sinfo->write_keys=write_keys; - sinfo->read_to_buffer=read_to_buffer; - sinfo->write_key=write_merge_key; - } + + set_sort_param_read_write(sinfo); + if (sinfo->buffpek.elements) { uint maxbuffer=sinfo->buffpek.elements-1; diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 2c4639b314342..69c0bfc3edce7 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -84,6 +84,28 @@ static int write_merge_key_varlen(MI_SORT_PARAM *info, static inline int my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs); + +/* + Sets the appropriate read and write methods for the MI_SORT_PARAM + based on the variable length key flag. +*/ +static void set_sort_param_read_write(MI_SORT_PARAM *sort_param) +{ + if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) + { + sort_param->write_keys= write_keys_varlen; + sort_param->read_to_buffer= read_to_buffer_varlen; + sort_param->write_key= write_merge_key_varlen; + } + else + { + sort_param->write_keys= write_keys; + sort_param->read_to_buffer= read_to_buffer; + sort_param->write_key= write_merge_key; + } +} + + /* Creates a index of sorted keys @@ -111,18 +133,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, DBUG_ENTER("_create_index_by_sort"); DBUG_PRINT("enter",("sort_length: %d", info->key_length)); - if (info->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - info->write_keys=write_keys_varlen; - info->read_to_buffer=read_to_buffer_varlen; - info->write_key= write_merge_key_varlen; - } - else - { - info->write_keys=write_keys; - info->read_to_buffer=read_to_buffer; - info->write_key=write_merge_key; - } + set_sort_param_read_write(info); my_b_clear(&tempfile); my_b_clear(&tempfile_for_exceptions); @@ -307,7 +318,6 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys, DBUG_RETURN((*maxbuffer)*(keys-1)+idx); } /* find_all_keys */ - /* Search after all keys and place them in a temp. file */ pthread_handler_t thr_find_all_keys(void *arg) @@ -332,18 +342,7 @@ pthread_handler_t thr_find_all_keys(void *arg) if (sort_param->sort_info->got_error) goto err; - if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - sort_param->write_keys= write_keys_varlen; - sort_param->read_to_buffer= read_to_buffer_varlen; - sort_param->write_key= write_merge_key_varlen; - } - else - { - sort_param->write_keys= write_keys; - sort_param->read_to_buffer= read_to_buffer; - sort_param->write_key= write_merge_key; - } + set_sort_param_read_write(sort_param); my_b_clear(&sort_param->tempfile); my_b_clear(&sort_param->tempfile_for_exceptions); @@ -550,18 +549,9 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) { if (got_error) continue; - if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - sinfo->write_keys=write_keys_varlen; - sinfo->read_to_buffer=read_to_buffer_varlen; - sinfo->write_key=write_merge_key_varlen; - } - else - { - sinfo->write_keys=write_keys; - sinfo->read_to_buffer=read_to_buffer; - sinfo->write_key=write_merge_key; - } + + set_sort_param_read_write(sinfo); + if (sinfo->buffpek.elements) { uint maxbuffer=sinfo->buffpek.elements-1; From 2b47832a2d261dbaf735b26e796aa126bccafb20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 10 Dec 2015 03:56:31 +0200 Subject: [PATCH 065/112] Fixed compilation failure using clang Both aria and myisam storage engines feature a logic path in thr_find_all_keys that leads to undefined behaviour by bypassing the initialization code of variables after my_thread_init(). By refactoring the nested logic into a separate function, this problem is resolved. --- include/myisam.h | 3 +- storage/maria/ma_sort.c | 289 ++++++++++++++++++----------------- storage/maria/maria_def.h | 3 +- storage/myisam/sort.c | 311 ++++++++++++++++++++------------------ 4 files changed, 321 insertions(+), 285 deletions(-) diff --git a/include/myisam.h b/include/myisam.h index d50b1dc360eb6..186b049b32e36 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -330,7 +330,8 @@ typedef struct st_sort_info my_off_t filelength, dupp, buff_length; ha_rows max_records; uint current_key, total_keys; - uint got_error, threads_running; + volatile uint got_error; + uint threads_running; myf myf_rw; enum data_file_type new_data_file_type; } MI_SORT_INFO; diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index ce17446eea784..ea2b61b358a6f 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -333,170 +333,187 @@ static ha_rows find_all_keys(MARIA_SORT_PARAM *info, uint keys, } /* find_all_keys */ -/* Search after all keys and place them in a temp. file */ - -pthread_handler_t _ma_thr_find_all_keys(void *arg) +static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param) { - MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg; - int error; - size_t memavl,old_memavl; - uint sort_length; - ulong idx, maxbuffer, keys; - uchar **sort_keys=0; - - LINT_INIT(keys); + DBUG_ENTER("_ma_thr_find_all_keys"); + DBUG_PRINT("enter", ("master: %d", sort_param->master)); - error=1; + my_bool error= FALSE; + ulonglong memavl, old_memavl; + uint UNINIT_VAR(keys), idx; + uint sort_length; + uint maxbuffer; + uchar **sort_keys= NULL; - if (my_thread_init()) - goto err; + if (sort_param->sort_info->got_error) + DBUG_RETURN(TRUE); - { /* Add extra block since DBUG_ENTER declare variables */ - DBUG_ENTER("_ma_thr_find_all_keys"); - DBUG_PRINT("enter", ("master: %d", sort_param->master)); - if (sort_param->sort_info->got_error) - goto err; + set_sort_param_read_write(sort_param); - set_sort_param_read_write(sort_param); - my_b_clear(&sort_param->tempfile); - my_b_clear(&sort_param->tempfile_for_exceptions); - bzero((char*) &sort_param->buffpek,sizeof(sort_param->buffpek)); - bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); + my_b_clear(&sort_param->tempfile); + my_b_clear(&sort_param->tempfile_for_exceptions); + bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); + bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); - memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); - idx= (uint)sort_param->sort_info->max_records; - sort_length= sort_param->key_length; - maxbuffer= 1; + memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); + idx= sort_param->sort_info->max_records; + sort_length= sort_param->key_length; + maxbuffer= 1; - while (memavl >= MIN_SORT_MEMORY) + while (memavl >= MIN_SORT_MEMORY) + { + if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl) + keys= idx+1; + else { - if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl) - keys= idx+1; - else - { - ulong skr; - do - { - skr= maxbuffer; - if (memavl < sizeof(BUFFPEK)*maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ - (sort_length+sizeof(char*))) <= 1 || - keys < maxbuffer) - { - _ma_check_print_error(sort_param->sort_info->param, - "aria_sort_buffer_size is too small"); - goto err; - } - } - while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); - } - if ((sort_keys= (uchar **) - my_malloc(keys*(sort_length+sizeof(char*))+ - ((sort_param->keyinfo->flag & HA_FULLTEXT) ? - HA_FT_MAXBYTELEN : 0), MYF(0)))) + ulong skr; + do { - if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) + skr= maxbuffer; + if (memavl < sizeof(BUFFPEK)*maxbuffer || + (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ + (sort_length+sizeof(char*))) <= 1 || + keys < maxbuffer) { - my_free(sort_keys); - sort_keys= (uchar **) NULL; /* for err: label */ + _ma_check_print_error(sort_param->sort_info->param, + "aria_sort_buffer_size is too small"); + goto err; } - else - break; } - old_memavl= memavl; - if ((memavl= memavl/4*3) < MIN_SORT_MEMORY && - old_memavl > MIN_SORT_MEMORY) - memavl= MIN_SORT_MEMORY; + while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); } - if (memavl < MIN_SORT_MEMORY) + if ((sort_keys= (uchar **) + my_malloc(keys*(sort_length+sizeof(char*))+ + ((sort_param->keyinfo->flag & HA_FULLTEXT) ? + HA_FT_MAXBYTELEN : 0), MYF(0)))) { - _ma_check_print_error(sort_param->sort_info->param, - "Aria sort buffer too small"); - goto err; /* purecov: tested */ + if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), + maxbuffer, maxbuffer / 2)) + { + my_free(sort_keys); + sort_keys= NULL; /* Safety against double free on error. */ + } + else + break; } + old_memavl= memavl; + if ((memavl= memavl/4*3) < MIN_SORT_MEMORY && + old_memavl > MIN_SORT_MEMORY) + memavl= MIN_SORT_MEMORY; + } - if (sort_param->sort_info->param->testflag & T_VERBOSE) - printf("Key %d - Allocating buffer for %lu keys\n", - sort_param->key+1, (ulong) keys); - sort_param->sort_keys= sort_keys; + if (memavl < MIN_SORT_MEMORY) + { + /* purecov: begin inspected */ + _ma_check_print_error(sort_param->sort_info->param, + "aria_sort_buffer_size is too small. Current " + "aria_sort_buffer_size: %llu rows: %llu " + "sort_length: %u", + (ulonglong) sort_param->sortbuff_size, + (ulonglong) idx, sort_length); + my_errno= ENOMEM; + goto err; + /* purecov: end inspected */ + } - idx= error= 0; - sort_keys[0]= (uchar*) (sort_keys+keys); + if (sort_param->sort_info->param->testflag & T_VERBOSE) + printf("Key %d - Allocating buffer for %llu keys\n", + sort_param->key + 1, (ulonglong) keys); + sort_param->sort_keys= sort_keys; - DBUG_PRINT("info", ("reading keys")); - while (!(error= sort_param->sort_info->got_error) && - !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) - { - if (sort_param->real_key_length > sort_param->key_length) - { - if (write_key(sort_param,sort_keys[idx], - &sort_param->tempfile_for_exceptions)) - goto err; - continue; - } + idx= error= 0; + sort_keys[0]= (uchar*) (sort_keys+keys); - if (++idx == keys) - { - if (sort_param->write_keys(sort_param, sort_keys, idx - 1, - (BUFFPEK *)alloc_dynamic(&sort_param-> - buffpek), - &sort_param->tempfile)) - goto err; - sort_keys[0]= (uchar*) (sort_keys+keys); - memcpy(sort_keys[0], sort_keys[idx - 1], - (size_t) sort_param->key_length); - idx= 1; - } - sort_keys[idx]=sort_keys[idx - 1] + sort_param->key_length; + DBUG_PRINT("info", ("reading keys")); + while (!(error= sort_param->sort_info->got_error) && + !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) + { + if (sort_param->real_key_length > sort_param->key_length) + { + if (write_key(sort_param, sort_keys[idx], + &sort_param->tempfile_for_exceptions)) + goto err; + continue; } - if (error > 0) - goto err; - if (sort_param->buffpek.elements) + + if (++idx == keys) { - if (sort_param->write_keys(sort_param,sort_keys, idx, - (BUFFPEK *) alloc_dynamic(&sort_param-> - buffpek), + if (sort_param->write_keys(sort_param, sort_keys, idx - 1, + (BUFFPEK *)alloc_dynamic(&sort_param->buffpek), &sort_param->tempfile)) goto err; - sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; + sort_keys[0]= (uchar*) (sort_keys+keys); + memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); + idx= 1; } - else - sort_param->keys= idx; + sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; + } + if (error > 0) + goto err; + if (sort_param->buffpek.elements) + { + if (sort_param->write_keys(sort_param,sort_keys, idx, + (BUFFPEK *) alloc_dynamic(&sort_param->buffpek), + &sort_param->tempfile)) + goto err; + sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; + } + else + sort_param->keys= idx; - sort_param->sort_keys_length= keys; - goto ok; + sort_param->sort_keys_length= keys; + DBUG_RETURN(FALSE); err: - DBUG_PRINT("error", ("got some error")); - sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ - my_free(sort_keys); - sort_param->sort_keys=0; - delete_dynamic(& sort_param->buffpek); - close_cached_file(&sort_param->tempfile); - close_cached_file(&sort_param->tempfile_for_exceptions); - -ok: - free_root(&sort_param->wordroot, MYF(0)); - /* - Detach from the share if the writer is involved. Avoid others to - be blocked. This includes a flush of the write buffer. This will - also indicate EOF to the readers. - */ - if (sort_param->sort_info->info->rec_cache.share) - remove_io_thread(&sort_param->sort_info->info->rec_cache); - - /* Readers detach from the share if any. Avoid others to be blocked. */ - if (sort_param->read_cache.share) - remove_io_thread(&sort_param->read_cache); - - mysql_mutex_lock(&sort_param->sort_info->mutex); - if (!--sort_param->sort_info->threads_running) - mysql_cond_signal(&sort_param->sort_info->cond); - mysql_mutex_unlock(&sort_param->sort_info->mutex); - DBUG_PRINT("exit", ("======== ending thread ========")); - } + DBUG_PRINT("error", ("got some error")); + my_free(sort_keys); + sort_param->sort_keys= 0; + delete_dynamic(& sort_param->buffpek); + close_cached_file(&sort_param->tempfile); + close_cached_file(&sort_param->tempfile_for_exceptions); + + DBUG_RETURN(TRUE); +} + +/* Search after all keys and place them in a temp. file */ + +pthread_handler_t _ma_thr_find_all_keys(void *arg) +{ + MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg; + my_bool error= FALSE; + /* If my_thread_init fails */ + if (my_thread_init() || _ma_thr_find_all_keys_exec(sort_param)) + error= TRUE; + + /* + Thread must clean up after itself. + */ + free_root(&sort_param->wordroot, MYF(0)); + /* + Detach from the share if the writer is involved. Avoid others to + be blocked. This includes a flush of the write buffer. This will + also indicate EOF to the readers. + That means that a writer always gets here first and readers - + only when they see EOF. But if a reader finishes prematurely + because of an error it may reach this earlier - don't allow it + to detach the writer thread. + */ + if (sort_param->master && sort_param->sort_info->info->rec_cache.share) + remove_io_thread(&sort_param->sort_info->info->rec_cache); + + /* Readers detach from the share if any. Avoid others to be blocked. */ + if (sort_param->read_cache.share) + remove_io_thread(&sort_param->read_cache); + + mysql_mutex_lock(&sort_param->sort_info->mutex); + if (error) + sort_param->sort_info->got_error= 1; + + if (!--sort_param->sort_info->threads_running) + mysql_cond_signal(&sort_param->sort_info->cond); + mysql_mutex_unlock(&sort_param->sort_info->mutex); + my_thread_end(); return NULL; } diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 983e0fba7f4c1..473cddee190a4 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -67,7 +67,8 @@ typedef struct st_maria_sort_info pgcache_page_no_t page; ha_rows max_records; uint current_key, total_keys; - uint got_error, threads_running; + volatile uint got_error; + uint threads_running; myf myf_rw; enum data_file_type new_data_file_type, org_data_file_type; } MARIA_SORT_INFO; diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 69c0bfc3edce7..21f1fa9fd6499 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -318,177 +318,194 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys, DBUG_RETURN((*maxbuffer)*(keys-1)+idx); } /* find_all_keys */ -/* Search after all keys and place them in a temp. file */ - -pthread_handler_t thr_find_all_keys(void *arg) +static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param) { - MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; - int error; - ulonglong memavl, old_memavl; - uint keys, sort_length; - uint idx, maxbuffer; - uchar **sort_keys=0; - - LINT_INIT(keys); + DBUG_ENTER("thr_find_all_keys"); + DBUG_PRINT("enter", ("master: %d", sort_param->master)); - error=1; - - if (my_thread_init()) - goto err; - - { /* Add extra block since DBUG_ENTER declare variables */ - DBUG_ENTER("thr_find_all_keys"); - DBUG_PRINT("enter", ("master: %d", sort_param->master)); - if (sort_param->sort_info->got_error) - goto err; - - set_sort_param_read_write(sort_param); - - my_b_clear(&sort_param->tempfile); - my_b_clear(&sort_param->tempfile_for_exceptions); - bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); - bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); - sort_keys= (uchar **) NULL; - - memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER); - idx= (uint)sort_param->sort_info->max_records; - sort_length= sort_param->key_length; - maxbuffer= 1; - - if ((memavl - sizeof(BUFFPEK)) / (sort_length + - sizeof(char *)) > UINT_MAX32) - memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *)); + ulonglong memavl, old_memavl; + uint UNINIT_VAR(keys), idx; + uint sort_length; + uint maxbuffer; + uchar **sort_keys= NULL; + + my_bool error= FALSE; + if (sort_param->sort_info->got_error) + error= TRUE; + if (error) + DBUG_RETURN(error); + + set_sort_param_read_write(sort_param); + + my_b_clear(&sort_param->tempfile); + my_b_clear(&sort_param->tempfile_for_exceptions); + bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); + bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); + + memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER); + idx= (uint) sort_param->sort_info->max_records; + sort_length= sort_param->key_length; + maxbuffer= 1; + + if ((memavl - sizeof(BUFFPEK)) / (sort_length + + sizeof(char *)) > UINT_MAX32) + memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *)); - while (memavl >= MIN_SORT_BUFFER) + while (memavl >= MIN_SORT_BUFFER) + { + if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= + (my_off_t) memavl) + keys= idx+1; + else { - if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= - (my_off_t) memavl) - keys= idx+1; - else - { - uint skr; - do - { - skr= maxbuffer; - if (memavl < sizeof(BUFFPEK)*maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ - (sort_length+sizeof(char*))) <= 1 || - keys < (uint) maxbuffer) - { - mi_check_print_error(sort_param->sort_info->param, - "myisam_sort_buffer_size is too small"); - goto err; - } - } - while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); - } - if ((sort_keys= (uchar**) - my_malloc(keys*(sort_length+sizeof(char*))+ - ((sort_param->keyinfo->flag & HA_FULLTEXT) ? - HA_FT_MAXBYTELEN : 0), MYF(0)))) + uint skr; + do { - if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) + skr= maxbuffer; + if (memavl < sizeof(BUFFPEK)*maxbuffer || + (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ + (sort_length+sizeof(char*))) <= 1 || + keys < (uint) maxbuffer) { - my_free(sort_keys); - sort_keys= (uchar **) NULL; /* for err: label */ + mi_check_print_error(sort_param->sort_info->param, + "myisam_sort_buffer_size is too small. Current " + "myisam_sort_buffer_size: %llu rows: %llu sort_length: %u", + sort_param->sortbuff_size, (ulonglong) idx, sort_length); + DBUG_RETURN(TRUE); } - else - break; } - old_memavl= memavl; - if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER && - old_memavl > MIN_SORT_BUFFER) - memavl= MIN_SORT_BUFFER; + while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); } - if (memavl < MIN_SORT_BUFFER) + if ((sort_keys= my_malloc(keys * (sort_length + sizeof(char *)) + + ((sort_param->keyinfo->flag & HA_FULLTEXT) ? + HA_FT_MAXBYTELEN : 0), MYF(0)))) { - mi_check_print_error(sort_param->sort_info->param, - "MyISAM sort buffer too small"); - goto err; /* purecov: tested */ + if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), + maxbuffer, min(maxbuffer / 2, 1000))) + { + my_free(sort_keys); + sort_keys= NULL; /* Safety against double free on error. */ + } + else + break; } + old_memavl= memavl; + if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER && + old_memavl > MIN_SORT_BUFFER) + memavl= MIN_SORT_BUFFER; + } + if (memavl < MIN_SORT_BUFFER) + { + /* purecov: begin inspected */ + mi_check_print_error(sort_param->sort_info->param, + "myisam_sort_buffer_size is too small. Current " + "myisam_sort_buffer_size: %llu rows: %llu sort_length: %u", + sort_param->sortbuff_size, (ulonglong) idx, sort_length); + my_errno= ENOMEM; + goto err; + /* purecov: end inspected */ + } - if (sort_param->sort_info->param->testflag & T_VERBOSE) - printf("Key %d - Allocating buffer for %d keys\n", - sort_param->key + 1, keys); - sort_param->sort_keys= sort_keys; + if (sort_param->sort_info->param->testflag & T_VERBOSE) + printf("Key %d - Allocating buffer for %llu keys\n", + sort_param->key + 1, (ulonglong) keys); + sort_param->sort_keys= sort_keys; - idx= error= 0; - sort_keys[0]= (uchar*) (sort_keys+keys); + idx= error= 0; + sort_keys[0]= (uchar*) (sort_keys+keys); - DBUG_PRINT("info", ("reading keys")); - while (!(error= sort_param->sort_info->got_error) && - !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) + DBUG_PRINT("info", ("reading keys")); + while (!(error= sort_param->sort_info->got_error) && + !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) + { + if (sort_param->real_key_length > sort_param->key_length) { - if (sort_param->real_key_length > sort_param->key_length) - { - if (write_key(sort_param, sort_keys[idx], - &sort_param->tempfile_for_exceptions)) - goto err; - continue; - } - - if (++idx == keys) - { - if (sort_param->write_keys(sort_param, sort_keys, idx - 1, - (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), - &sort_param->tempfile)) - goto err; - sort_keys[0]= (uchar*) (sort_keys+keys); - memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); - idx= 1; - } - sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; + if (write_key(sort_param, sort_keys[idx], + &sort_param->tempfile_for_exceptions)) + goto err; + continue; } - if (error > 0) - goto err; - if (sort_param->buffpek.elements) + + if (++idx == keys) { - if (sort_param->write_keys(sort_param, sort_keys, idx, + if (sort_param->write_keys(sort_param, sort_keys, idx - 1, (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), &sort_param->tempfile)) goto err; - sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; + sort_keys[0]= (uchar*) (sort_keys+keys); + memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); + idx= 1; } - else - sort_param->keys= idx; + sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; + } - sort_param->sort_keys_length= keys; - goto ok; + if (error > 0) + goto err; -err: - DBUG_PRINT("error", ("got some error")); - sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ - my_free(sort_keys); - sort_param->sort_keys= 0; - delete_dynamic(& sort_param->buffpek); - close_cached_file(&sort_param->tempfile); - close_cached_file(&sort_param->tempfile_for_exceptions); - -ok: - free_root(&sort_param->wordroot, MYF(0)); - /* - Detach from the share if the writer is involved. Avoid others to - be blocked. This includes a flush of the write buffer. This will - also indicate EOF to the readers. - That means that a writer always gets here first and readers - - only when they see EOF. But if a reader finishes prematurely - because of an error it may reach this earlier - don't allow it - to detach the writer thread. - */ - if (sort_param->master && sort_param->sort_info->info->rec_cache.share) - remove_io_thread(&sort_param->sort_info->info->rec_cache); - - /* Readers detach from the share if any. Avoid others to be blocked. */ - if (sort_param->read_cache.share) - remove_io_thread(&sort_param->read_cache); - - mysql_mutex_lock(&sort_param->sort_info->mutex); - if (!--sort_param->sort_info->threads_running) - mysql_cond_signal(&sort_param->sort_info->cond); - mysql_mutex_unlock(&sort_param->sort_info->mutex); - DBUG_PRINT("exit", ("======== ending thread ========")); + if (sort_param->buffpek.elements) + { + if (sort_param->write_keys(sort_param, sort_keys, idx, + (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), + &sort_param->tempfile)) + goto err; + sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; } + else + sort_param->keys= idx; + + sort_param->sort_keys_length= keys; + + DBUG_RETURN(FALSE); + +err: + DBUG_PRINT("error", ("got some error")); + sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ + my_free(sort_keys); + sort_param->sort_keys= 0; + delete_dynamic(& sort_param->buffpek); + close_cached_file(&sort_param->tempfile); + close_cached_file(&sort_param->tempfile_for_exceptions); + + DBUG_RETURN(TRUE); +} + +/* Search after all keys and place them in a temp. file */ + +pthread_handler_t thr_find_all_keys(void *arg) +{ + MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; + my_bool error= FALSE; + /* If my_thread_init fails */ + if (my_thread_init() || thr_find_all_keys_exec(sort_param)) + error= TRUE; + + /* + Thread must clean up after itself. + */ + free_root(&sort_param->wordroot, MYF(0)); + /* + Detach from the share if the writer is involved. Avoid others to + be blocked. This includes a flush of the write buffer. This will + also indicate EOF to the readers. + That means that a writer always gets here first and readers - + only when they see EOF. But if a reader finishes prematurely + because of an error it may reach this earlier - don't allow it + to detach the writer thread. + */ + if (sort_param->master && sort_param->sort_info->info->rec_cache.share) + remove_io_thread(&sort_param->sort_info->info->rec_cache); + + /* Readers detach from the share if any. Avoid others to be blocked. */ + if (sort_param->read_cache.share) + remove_io_thread(&sort_param->read_cache); + + mysql_mutex_lock(&sort_param->sort_info->mutex); + if (error) + sort_param->sort_info->got_error= 1; + + if (!--sort_param->sort_info->threads_running) + mysql_cond_signal(&sort_param->sort_info->cond); + mysql_mutex_unlock(&sort_param->sort_info->mutex); my_thread_end(); return NULL; } From 1bf25092cbf700049b16f556980c84a9674a811f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Mon, 13 Jun 2016 23:32:50 +0300 Subject: [PATCH 066/112] MDEV-10162: Update repair testcase --- storage/maria/ma_sort.c | 8 ++------ storage/myisam/sort.c | 13 ++++--------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index ea2b61b358a6f..4f092b17037bc 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -377,7 +377,7 @@ static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param) keys < maxbuffer) { _ma_check_print_error(sort_param->sort_info->param, - "aria_sort_buffer_size is too small"); + "aria_sort_buffer_size is too small."); goto err; } } @@ -407,11 +407,7 @@ static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param) { /* purecov: begin inspected */ _ma_check_print_error(sort_param->sort_info->param, - "aria_sort_buffer_size is too small. Current " - "aria_sort_buffer_size: %llu rows: %llu " - "sort_length: %u", - (ulonglong) sort_param->sortbuff_size, - (ulonglong) idx, sort_length); + "aria_sort_buffer_size is too small."); my_errno= ENOMEM; goto err; /* purecov: end inspected */ diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index 21f1fa9fd6499..e10e4e26112d2 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -190,7 +190,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, } if (memavl < MIN_SORT_BUFFER) { - mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */ + mi_check_print_error(info->sort_info->param, + "MyISAM sort buffer too small"); /* purecov: tested */ my_errno= ENOMEM; /* purecov: tested */ goto err; /* purecov: tested */ } @@ -331,8 +332,6 @@ static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param) my_bool error= FALSE; if (sort_param->sort_info->got_error) - error= TRUE; - if (error) DBUG_RETURN(error); set_sort_param_read_write(sort_param); @@ -368,9 +367,7 @@ static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param) keys < (uint) maxbuffer) { mi_check_print_error(sort_param->sort_info->param, - "myisam_sort_buffer_size is too small. Current " - "myisam_sort_buffer_size: %llu rows: %llu sort_length: %u", - sort_param->sortbuff_size, (ulonglong) idx, sort_length); + "myisam_sort_buffer_size is too small"); DBUG_RETURN(TRUE); } } @@ -398,9 +395,7 @@ static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param) { /* purecov: begin inspected */ mi_check_print_error(sort_param->sort_info->param, - "myisam_sort_buffer_size is too small. Current " - "myisam_sort_buffer_size: %llu rows: %llu sort_length: %u", - sort_param->sortbuff_size, (ulonglong) idx, sort_length); + "myisam_sort_buffer_size is too small"); my_errno= ENOMEM; goto err; /* purecov: end inspected */ From 34a104ba0ccbe254100a235c04e4648136c9aa7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Tue, 14 Jun 2016 12:28:05 +0300 Subject: [PATCH 067/112] MDEV-10229: TokuDB fails to build with CLang Structure initialization must feature all members present within the struct. --- storage/tokudb/ft-index/ft/logger/recover.cc | 6 +++--- .../ft/serialize/ft_node-serialize.cc | 2 +- storage/tokudb/ft-index/ft/txn/txn.cc | 8 ++++---- .../ft-index/portability/toku_pthread.h | 19 ------------------- .../src/tests/threaded_stress_test_helpers.h | 2 +- 5 files changed, 9 insertions(+), 28 deletions(-) diff --git a/storage/tokudb/ft-index/ft/logger/recover.cc b/storage/tokudb/ft-index/ft/logger/recover.cc index 680485201da56..7a5fa361e2d9d 100644 --- a/storage/tokudb/ft-index/ft/logger/recover.cc +++ b/storage/tokudb/ft-index/ft/logger/recover.cc @@ -785,7 +785,7 @@ static int toku_recover_xcommit (struct logtype_xcommit *l, RECOVER_ENV renv) { assert(txn!=NULL); // commit the transaction - toku_txn_progress_extra extra = { time(NULL), l->lsn, "commit", l->xid }; + toku_txn_progress_extra extra = { time(NULL), l->lsn, "commit", l->xid, 0 }; int r = toku_txn_commit_with_lsn(txn, true, l->lsn, toku_recover_txn_progress, &extra); assert(r == 0); @@ -828,7 +828,7 @@ static int toku_recover_xabort (struct logtype_xabort *l, RECOVER_ENV renv) { assert(txn!=NULL); // abort the transaction - toku_txn_progress_extra extra = { time(NULL), l->lsn, "abort", l->xid }; + toku_txn_progress_extra extra = { time(NULL), l->lsn, "abort", l->xid, 0 }; r = toku_txn_abort_with_lsn(txn, l->lsn, toku_recover_txn_progress, &extra); assert(r == 0); @@ -1363,7 +1363,7 @@ static void recover_abort_live_txn(TOKUTXN txn) { // sanity check that the recursive call successfully NULLs out txn->child invariant(txn->child == NULL); // abort the transaction - toku_txn_progress_extra extra = { time(NULL), ZERO_LSN, "abort live", txn->txnid }; + toku_txn_progress_extra extra = { time(NULL), ZERO_LSN, "abort live", txn->txnid, 0 }; int r = toku_txn_abort_txn(txn, toku_recover_txn_progress, &extra); assert(r == 0); diff --git a/storage/tokudb/ft-index/ft/serialize/ft_node-serialize.cc b/storage/tokudb/ft-index/ft/serialize/ft_node-serialize.cc index 6fd452aba5421..84f3f98cfb5a4 100644 --- a/storage/tokudb/ft-index/ft/serialize/ft_node-serialize.cc +++ b/storage/tokudb/ft-index/ft/serialize/ft_node-serialize.cc @@ -643,7 +643,7 @@ serialize_and_compress_in_parallel(FTNODE node, struct serialize_compress_work work[npartitions]; workset_lock(&ws); for (int i = 0; i < npartitions; i++) { - work[i] = (struct serialize_compress_work) { .base = {{NULL}}, + work[i] = (struct serialize_compress_work) { .base = {{NULL, NULL}}, .node = node, .i = i, .compression_method = compression_method, diff --git a/storage/tokudb/ft-index/ft/txn/txn.cc b/storage/tokudb/ft-index/ft/txn/txn.cc index 922c955a6b5e8..9aa933751269a 100644 --- a/storage/tokudb/ft-index/ft/txn/txn.cc +++ b/storage/tokudb/ft-index/ft/txn/txn.cc @@ -333,14 +333,14 @@ static txn_child_manager tcm; .do_fsync = false, .force_fsync_on_commit = false, .do_fsync_lsn = ZERO_LSN, - .xa_xid = {0}, + .xa_xid = {0, 0, 0, {}}, .progress_poll_fun = NULL, .progress_poll_fun_extra = NULL, - .txn_lock = ZERO_MUTEX_INITIALIZER, + .txn_lock = TOKU_MUTEX_INITIALIZER, .open_fts = open_fts, .roll_info = roll_info, - .state_lock = ZERO_MUTEX_INITIALIZER, - .state_cond = ZERO_COND_INITIALIZER, + .state_lock = TOKU_MUTEX_INITIALIZER, + .state_cond = TOKU_COND_INITIALIZER, .state = TOKUTXN_LIVE, .num_pin = 0, .client_id = 0, diff --git a/storage/tokudb/ft-index/portability/toku_pthread.h b/storage/tokudb/ft-index/portability/toku_pthread.h index a9dc660b6a751..4a564e4029be1 100644 --- a/storage/tokudb/ft-index/portability/toku_pthread.h +++ b/storage/tokudb/ft-index/portability/toku_pthread.h @@ -125,16 +125,6 @@ typedef struct toku_mutex_aligned { toku_mutex_t aligned_mutex __attribute__((__aligned__(64))); } toku_mutex_aligned_t; -// Different OSes implement mutexes as different amounts of nested structs. -// C++ will fill out all missing values with zeroes if you provide at least one zero, but it needs the right amount of nesting. -#if defined(__FreeBSD__) -# define ZERO_MUTEX_INITIALIZER {0} -#elif defined(__APPLE__) -# define ZERO_MUTEX_INITIALIZER {{0}} -#else // __linux__, at least -# define ZERO_MUTEX_INITIALIZER {{{0}}} -#endif - #if TOKU_PTHREAD_DEBUG # define TOKU_MUTEX_INITIALIZER { .pmutex = PTHREAD_MUTEX_INITIALIZER, .owner = 0, .locked = false, .valid = true } #else @@ -276,15 +266,6 @@ typedef struct toku_cond { pthread_cond_t pcond; } toku_cond_t; -// Different OSes implement mutexes as different amounts of nested structs. -// C++ will fill out all missing values with zeroes if you provide at least one zero, but it needs the right amount of nesting. -#if defined(__FreeBSD__) -# define ZERO_COND_INITIALIZER {0} -#elif defined(__APPLE__) -# define ZERO_COND_INITIALIZER {{0}} -#else // __linux__, at least -# define ZERO_COND_INITIALIZER {{{0}}} -#endif #define TOKU_COND_INITIALIZER {PTHREAD_COND_INITIALIZER} static inline void diff --git a/storage/tokudb/ft-index/src/tests/threaded_stress_test_helpers.h b/storage/tokudb/ft-index/src/tests/threaded_stress_test_helpers.h index f9da16938471e..fc4acecff104a 100644 --- a/storage/tokudb/ft-index/src/tests/threaded_stress_test_helpers.h +++ b/storage/tokudb/ft-index/src/tests/threaded_stress_test_helpers.h @@ -1825,7 +1825,7 @@ static int run_workers( { int r; const struct perf_formatter *perf_formatter = &perf_formatters[cli_args->perf_output_format]; - toku_mutex_t mutex = ZERO_MUTEX_INITIALIZER; + toku_mutex_t mutex = TOKU_MUTEX_INITIALIZER; toku_mutex_init(&mutex, nullptr); struct rwlock rwlock; rwlock_init(&rwlock); From b644661e5d2fb514d373fe533cd7e0131bae54a0 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 14 Jun 2016 22:29:24 +0200 Subject: [PATCH 068/112] MDEV-9256 : Crashes on Windows x64 with aria_pagecache_buffer_size > 4GB Fixed wrong calculation of buffer sizes. ulong datatype was used wrongly, as were the casts to ulong. Buffer sizes should be of type size_t, not ulong, or bad things happen on 64 bit Windows. This patch changes pagecache struct to use size_t/ssize_t where long/ulong were previously used. Also, removed several casts. --- storage/maria/ma_pagecache.c | 34 ++++++++++++++++---------------- storage/maria/ma_pagecache.h | 38 ++++++++++++++++++------------------ storage/maria/ma_sort.c | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 6aaccea219f74..1a791d4303463 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -500,8 +500,8 @@ static void test_key_cache(PAGECACHE *pagecache, const char *where, my_bool lock); #endif -#define PAGECACHE_HASH(p, f, pos) (((ulong) (pos) + \ - (ulong) (f).file) & (p->hash_entries-1)) +#define PAGECACHE_HASH(p, f, pos) (((size_t) (pos) + \ + (size_t) (f).file) & (p->hash_entries-1)) #define FILE_HASH(f) ((uint) (f).file & (PAGECACHE_CHANGED_BLOCKS_HASH - 1)) #define DEFAULT_PAGECACHE_DEBUG_LOG "pagecache_debug.log" @@ -639,10 +639,10 @@ static my_bool pagecache_fwrite(PAGECACHE *pagecache, { char buff[80]; uint len= my_sprintf(buff, - (buff, "fwrite: fd: %d id: %u page: %lu", + (buff, "fwrite: fd: %d id: %u page: %llu", filedesc->file, _ma_file_callback_to_id(filedesc->callback_data), - (ulong) pageno)); + pageno)); (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY, (uchar*) buff, len); } @@ -741,11 +741,11 @@ static inline uint next_power(uint value) */ -ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, +size_t init_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold, uint block_size, myf my_readwrite_flags) { - ulong blocks, hash_links, length; + size_t blocks, hash_links, length; int error; DBUG_ENTER("init_pagecache"); DBUG_ASSERT(block_size >= 512); @@ -782,10 +782,10 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, DBUG_PRINT("info", ("block_size: %u", block_size)); DBUG_ASSERT(((uint)(1 << pagecache->shift)) == block_size); - blocks= (ulong) (use_mem / (sizeof(PAGECACHE_BLOCK_LINK) + + blocks= use_mem / (sizeof(PAGECACHE_BLOCK_LINK) + 2 * sizeof(PAGECACHE_HASH_LINK) + sizeof(PAGECACHE_HASH_LINK*) * - 5/4 + block_size)); + 5/4 + block_size); /* We need to support page cache with just one block to be able to do scanning of rows-in-block files @@ -816,7 +816,7 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, blocks--; /* Allocate memory for cache page buffers */ if ((pagecache->block_mem= - my_large_malloc((ulong) blocks * pagecache->block_size, + my_large_malloc(blocks * pagecache->block_size, MYF(MY_WME)))) { /* @@ -824,7 +824,7 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, For each block 2 hash links are allocated */ if ((pagecache->block_root= - (PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0)))) + (PAGECACHE_BLOCK_LINK*) my_malloc(length, MYF(0)))) break; my_large_free(pagecache->block_mem); pagecache->block_mem= 0; @@ -832,7 +832,7 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, blocks= blocks / 4*3; } pagecache->blocks_unused= blocks; - pagecache->disk_blocks= (long) blocks; + pagecache->disk_blocks= blocks; pagecache->hash_links= hash_links; pagecache->hash_root= (PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root + @@ -887,7 +887,7 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, PAGECACHE_CHANGED_BLOCKS_HASH); pagecache->blocks= pagecache->disk_blocks > 0 ? pagecache->disk_blocks : 0; - DBUG_RETURN((ulong) pagecache->disk_blocks); + DBUG_RETURN((size_t)pagecache->disk_blocks); err: error= my_errno; @@ -978,11 +978,11 @@ static int flush_all_key_blocks(PAGECACHE *pagecache) So we disable it for now. */ #if NOT_USED /* keep disabled until code is fixed see above !! */ -ulong resize_pagecache(PAGECACHE *pagecache, +size_t resize_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold) { - ulong blocks; + size_t blocks; struct st_my_thread_var *thread; WQUEUE *wqueue; @@ -1379,7 +1379,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block, ("linked block: %u:%1u status: %x #requests: %u #available: %u", PCBLOCK_NUMBER(pagecache, block), at_end, block->status, block->requests, pagecache->blocks_available)); - KEYCACHE_DBUG_ASSERT((ulong) pagecache->blocks_available <= + KEYCACHE_DBUG_ASSERT(pagecache->blocks_available <= pagecache->blocks_used); #endif DBUG_VOID_RETURN; @@ -2018,7 +2018,7 @@ static PAGECACHE_BLOCK_LINK *find_block(PAGECACHE *pagecache, /* There are some never used blocks, take first of them */ block= &pagecache->block_root[pagecache->blocks_used]; block->buffer= ADD_TO_PTR(pagecache->block_mem, - ((ulong) pagecache->blocks_used* + (pagecache->blocks_used* pagecache->block_size), uchar*); pagecache->blocks_used++; @@ -4870,7 +4870,7 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache, LSN *min_rec_lsn) { my_bool error= 0; - ulong stored_list_size= 0; + size_t stored_list_size= 0; uint file_hash; char *ptr; LSN minimum_rec_lsn= LSN_MAX; diff --git a/storage/maria/ma_pagecache.h b/storage/maria/ma_pagecache.h index 8460eaddc57b6..cb331bae74a13 100644 --- a/storage/maria/ma_pagecache.h +++ b/storage/maria/ma_pagecache.h @@ -117,20 +117,20 @@ typedef struct st_pagecache_hash_link PAGECACHE_HASH_LINK; typedef struct st_pagecache { size_t mem_size; /* specified size of the cache memory */ - ulong min_warm_blocks; /* min number of warm blocks; */ - ulong age_threshold; /* age threshold for hot blocks */ + size_t min_warm_blocks; /* min number of warm blocks; */ + size_t age_threshold; /* age threshold for hot blocks */ ulonglong time; /* total number of block link operations */ - ulong hash_entries; /* max number of entries in the hash table */ - long hash_links; /* max number of hash links */ - long hash_links_used; /* number of hash links taken from free links pool */ - long disk_blocks; /* max number of blocks in the cache */ - ulong blocks_used; /* maximum number of concurrently used blocks */ - ulong blocks_unused; /* number of currently unused blocks */ - ulong blocks_changed; /* number of currently dirty blocks */ - ulong warm_blocks; /* number of blocks in warm sub-chain */ - ulong cnt_for_resize_op; /* counter to block resize operation */ - ulong blocks_available; /* number of blocks available in the LRU chain */ - long blocks; /* max number of blocks in the cache */ + size_t hash_entries; /* max number of entries in the hash table */ + ssize_t hash_links; /* max number of hash links */ + ssize_t hash_links_used; /* number of hash links taken from free links pool */ + ssize_t disk_blocks; /* max number of blocks in the cache */ + size_t blocks_used; /* maximum number of concurrently used blocks */ + size_t blocks_unused; /* number of currently unused blocks */ + size_t blocks_changed; /* number of currently dirty blocks */ + size_t warm_blocks; /* number of blocks in warm sub-chain */ + size_t cnt_for_resize_op; /* counter to block resize operation */ + size_t blocks_available; /* number of blocks available in the LRU chain */ + ssize_t blocks; /* max number of blocks in the cache */ uint32 block_size; /* size of the page buffer of a cache block */ PAGECACHE_HASH_LINK **hash_root;/* arr. of entries into hash table buckets */ PAGECACHE_HASH_LINK *hash_link_root;/* memory for hash table links */ @@ -155,12 +155,12 @@ typedef struct st_pagecache */ ulonglong param_buff_size; /* size the memory allocated for the cache */ - ulong param_block_size; /* size of the blocks in the key cache */ - ulong param_division_limit; /* min. percentage of warm blocks */ - ulong param_age_threshold; /* determines when hot block is downgraded */ + size_t param_block_size; /* size of the blocks in the key cache */ + size_t param_division_limit; /* min. percentage of warm blocks */ + size_t param_age_threshold; /* determines when hot block is downgraded */ /* Statistics variables. These are reset in reset_pagecache_counters(). */ - ulong global_blocks_changed; /* number of currently dirty blocks */ + size_t global_blocks_changed; /* number of currently dirty blocks */ ulonglong global_cache_w_requests;/* number of write requests (write hits) */ ulonglong global_cache_write; /* number of writes from cache to files */ ulonglong global_cache_r_requests;/* number of read requests (read hits) */ @@ -193,10 +193,10 @@ typedef enum pagecache_flush_filter_result /* The default key cache */ extern PAGECACHE dflt_pagecache_var, *dflt_pagecache; -extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem, +extern size_t init_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold, uint block_size, myf my_read_flags); -extern ulong resize_pagecache(PAGECACHE *pagecache, +extern size_t resize_pagecache(PAGECACHE *pagecache, size_t use_mem, uint division_limit, uint age_threshold); extern void change_pagecache_param(PAGECACHE *pagecache, uint division_limit, diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index 4f092b17037bc..3180118a1559d 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -519,7 +519,7 @@ int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param) { MARIA_SORT_INFO *sort_info=sort_param->sort_info; HA_CHECK *param=sort_info->param; - ulong UNINIT_VAR(length), keys; + size_t UNINIT_VAR(length), keys; double *rec_per_key_part= param->new_rec_per_key_part; int got_error=sort_info->got_error; uint i; From 1d21b22155242f604ab8e4a7b4ed92a422f61266 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 15 Jun 2016 13:53:19 +0200 Subject: [PATCH 069/112] MDEV-10001 my_b_seek() may not work correctly after my_b_read() hits EOF applied the patch from David Gow --- mysys/mf_iocache.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index a3cbaff68b0b1..06a76c6847708 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -507,6 +507,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) { /* End of file. Return, what we did copy from the buffer. */ info->error= (int) left_length; + info->seek_not_done=1; DBUG_RETURN(1); } /* @@ -524,6 +525,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) */ info->error= (read_length == (size_t) -1 ? -1 : (int) (read_length+left_length)); + info->seek_not_done=1; DBUG_RETURN(1); } Count-=length; @@ -572,6 +574,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) /* For a read error, return -1, otherwise, what we got in total. */ info->error= length == (size_t) -1 ? -1 : (int) (length+left_length); info->read_pos=info->read_end=info->buffer; + info->seek_not_done=1; DBUG_RETURN(1); } /* From 0e50b924820d365bcc1659eec2cad606f6887597 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 16 Jun 2016 12:35:14 +0400 Subject: [PATCH 070/112] MDEV-9969 mysql_install_db error processing ignore_db_dirs. Check for same directories in the list added. --- mysql-test/r/mysqld_option_err.result | 1 + mysql-test/t/mysqld_option_err.test | 8 ++++++++ sql/sql_show.cc | 24 +++++++++++++++++++++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/mysqld_option_err.result b/mysql-test/r/mysqld_option_err.result index 4afcc5e0cb1b2..1870ea85270fc 100644 --- a/mysql-test/r/mysqld_option_err.result +++ b/mysql-test/r/mysqld_option_err.result @@ -5,4 +5,5 @@ Test non-numeric value passed to number option. Test that bad value for plugin enum option is rejected correctly. Test that --help --verbose works Test that --not-known-option --help --verbose gives error +Test that specifying same directory several times handled properly. Done. diff --git a/mysql-test/t/mysqld_option_err.test b/mysql-test/t/mysqld_option_err.test index 0c38eba7ca923..6f1e089fbe46b 100644 --- a/mysql-test/t/mysqld_option_err.test +++ b/mysql-test/t/mysqld_option_err.test @@ -56,4 +56,12 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --error 2 --exec $MYSQLD_BOOTSTRAP_CMD --not-known-option --help --verbose >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 +# +# MDEV-9969 mysql_install_db error processing ignore_db_dirs. +# + +--echo Test that specifying same directory several times handled properly. + +--exec echo "" | $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 + --echo Done. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b8926b986b068..931011dcbc265 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -720,12 +720,24 @@ ignore_db_dirs_process_additions() for (i= 0; i < ignore_db_dirs_array.elements; i++) { get_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); - if (my_hash_insert(&ignore_db_dirs_hash, (uchar *) dir)) + if (my_hash_insert(&ignore_db_dirs_hash, (uchar *)dir)) + { + /* ignore duplicates from the config file */ + if (my_hash_search(&ignore_db_dirs_hash, (uchar *)dir->str, dir->length)) + { + sql_print_warning("Duplicate ignore-db-dir directory name '%.*s' " + "found in the config file(s). Ignoring the duplicate.", + (int) dir->length, dir->str); + my_free(dir); + goto continue_loop; + } + return true; + } ptr= strnmov(ptr, dir->str, dir->length); - if (i + 1 < ignore_db_dirs_array.elements) - ptr= strmov(ptr, ","); + *(ptr++)= ','; +continue_loop: /* Set the transferred array element to NULL to avoid double free in case of error. @@ -734,6 +746,12 @@ ignore_db_dirs_process_additions() set_dynamic(&ignore_db_dirs_array, (uchar *) &dir, i); } + if (ptr > opt_ignore_db_dirs) + { + ptr--; + DBUG_ASSERT(*ptr == ','); + } + /* make sure the string is terminated */ DBUG_ASSERT(ptr - opt_ignore_db_dirs <= (ptrdiff_t) len); *ptr= 0; From b21e7af20ed4e694376b6a2a246af9dd481d7bb0 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Thu, 16 Jun 2016 13:41:45 +0400 Subject: [PATCH 071/112] MDEV-9969 mysql_install_db error processing ignore_db_dirs. Changes to the mysql_install_db scripts so they don't repeat arguments twice. --- scripts/mysql_install_db.pl.in | 2 +- scripts/mysql_install_db.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in index 4d3641397d04c..ede5fabd3aaa5 100644 --- a/scripts/mysql_install_db.pl.in +++ b/scripts/mysql_install_db.pl.in @@ -238,7 +238,7 @@ sub quote_options { ############################################################################## my $opt = {}; -parse_arguments($opt, 'PICK-ARGS-FROM-ARGV', @ARGV); +parse_arguments($opt, @ARGV); # ---------------------------------------------------------------------- # We can now find my_print_defaults. This script supports: diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index d08d04914eead..bdce0857d1e12 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -216,7 +216,7 @@ cannot_find_file() # Ok, let's go. We first need to parse arguments which are required by # my_print_defaults so that we can execute it first, then later re-parse # the command line to add any extra bits that we need. -parse_arguments PICK-ARGS-FROM-ARGV "$@" +parse_arguments "$@" # # We can now find my_print_defaults. This script supports: From 0a50e43e9df2f1e005591e22388e6d20f82edf72 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 16 Jun 2016 14:57:32 +0400 Subject: [PATCH 072/112] MDEV-9374 having '2015-01-01 01:00:00.000001' > coalesce(NULL) returns true The problem was earlier fixed by the patch for MDEV-9521. Adding tests only. --- mysql-test/r/type_datetime.result | 8 ++++++++ mysql-test/t/type_datetime.test | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 82b64d30d96b0..e033fe486079b 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -834,5 +834,13 @@ a b a b DEALLOCATE PREPARE stmt1; DROP TABLE t1,t2; # +# MDEV-9374 having '2015-01-01 01:00:00.000001' > coalesce(NULL) returns true +# +CREATE TABLE t1 (c1 DATETIME(0)); +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1 HAVING '2015-01-01 01:00:00.000001' > COALESCE(c1); +c1 +DROP TABLE t1; +# # End of 5.5 tests # diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index e44b190def024..3f96673c43f46 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -610,6 +610,14 @@ EXECUTE stmt1; DEALLOCATE PREPARE stmt1; DROP TABLE t1,t2; +--echo # +--echo # MDEV-9374 having '2015-01-01 01:00:00.000001' > coalesce(NULL) returns true +--echo # +CREATE TABLE t1 (c1 DATETIME(0)); +INSERT INTO t1 VALUES (NULL); +SELECT * FROM t1 HAVING '2015-01-01 01:00:00.000001' > COALESCE(c1); +DROP TABLE t1; + --echo # --echo # End of 5.5 tests --echo # From 7ab7abdb51ab88664f12f1a7be3730aaa0a950db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 16 Jun 2016 18:52:46 +0300 Subject: [PATCH 073/112] Fix compilation failure when compiling with std=c90 Change variable declaration to be before any other statements. --- storage/maria/ma_sort.c | 5 ++--- storage/myisam/sort.c | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index 3180118a1559d..a95f9bb7ddb25 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -335,15 +335,14 @@ static ha_rows find_all_keys(MARIA_SORT_PARAM *info, uint keys, static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param) { - DBUG_ENTER("_ma_thr_find_all_keys"); - DBUG_PRINT("enter", ("master: %d", sort_param->master)); - my_bool error= FALSE; ulonglong memavl, old_memavl; uint UNINIT_VAR(keys), idx; uint sort_length; uint maxbuffer; uchar **sort_keys= NULL; + DBUG_ENTER("_ma_thr_find_all_keys"); + DBUG_PRINT("enter", ("master: %d", sort_param->master)); if (sort_param->sort_info->got_error) DBUG_RETURN(TRUE); diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index e10e4e26112d2..b1cdbf450c8a1 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -321,16 +321,15 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys, static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param) { - DBUG_ENTER("thr_find_all_keys"); - DBUG_PRINT("enter", ("master: %d", sort_param->master)); - ulonglong memavl, old_memavl; uint UNINIT_VAR(keys), idx; uint sort_length; uint maxbuffer; uchar **sort_keys= NULL; - my_bool error= FALSE; + DBUG_ENTER("thr_find_all_keys"); + DBUG_PRINT("enter", ("master: %d", sort_param->master)); + if (sort_param->sort_info->got_error) DBUG_RETURN(error); From c7eef029533d71d1c83c231dde065184589930f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 16 Jun 2016 22:00:16 +0300 Subject: [PATCH 074/112] Increase the number of default build thread ids possibilities When running mysql-test-run without a parallel parameter, it might be impossible to find a free port. --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 63b18c6bebd10..a85bed883951f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1803,7 +1803,7 @@ ($) $build_thread = 300; # Start attempts from here my $build_thread_upper = $build_thread + ($opt_parallel > 1500 ? 3000 - : 2 * $opt_parallel); + : 2 * $opt_parallel) + 300; while (! $found_free) { $build_thread= mtr_get_unique_id($build_thread, $build_thread_upper); From 12ae840375fe30da1c23647facaa0678858d6d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Thu, 16 Jun 2016 22:04:24 +0300 Subject: [PATCH 075/112] Fix typo bug that cause myisam repair to fail We need to return TRUE if got_error == 1, not error, which is initialized to FALSE. --- storage/maria/ma_sort.c | 2 +- storage/myisam/sort.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c index a95f9bb7ddb25..a49ce8fba1f75 100644 --- a/storage/maria/ma_sort.c +++ b/storage/maria/ma_sort.c @@ -335,7 +335,7 @@ static ha_rows find_all_keys(MARIA_SORT_PARAM *info, uint keys, static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param) { - my_bool error= FALSE; + int error= 0; ulonglong memavl, old_memavl; uint UNINIT_VAR(keys), idx; uint sort_length; diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index b1cdbf450c8a1..ed9267a6f1fd5 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -326,12 +326,12 @@ static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param) uint sort_length; uint maxbuffer; uchar **sort_keys= NULL; - my_bool error= FALSE; + int error= 0; DBUG_ENTER("thr_find_all_keys"); DBUG_PRINT("enter", ("master: %d", sort_param->master)); if (sort_param->sort_info->got_error) - DBUG_RETURN(error); + DBUG_RETURN(TRUE); set_sort_param_read_write(sort_param); From 7ff86b49912df5de7b5a8b9c9134e72134b7ba5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Fri, 17 Jun 2016 14:59:17 +0300 Subject: [PATCH 076/112] MDEV-10247 TokuDB assertion error when building with DEBUG Fix the assertion failure by setting the struct to 0. This can not be done using a macro due to different definitions of mutexes on various OS-es. Afterwards we call toku_mutex_init and completely initialize the locks. --- storage/tokudb/ft-index/ft/txn/txn.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/storage/tokudb/ft-index/ft/txn/txn.cc b/storage/tokudb/ft-index/ft/txn/txn.cc index 9aa933751269a..34c7e0f2a6705 100644 --- a/storage/tokudb/ft-index/ft/txn/txn.cc +++ b/storage/tokudb/ft-index/ft/txn/txn.cc @@ -336,17 +336,26 @@ static txn_child_manager tcm; .xa_xid = {0, 0, 0, {}}, .progress_poll_fun = NULL, .progress_poll_fun_extra = NULL, - .txn_lock = TOKU_MUTEX_INITIALIZER, + .txn_lock = {}, // Needs to be set to 0 after initialization. + // See: + // https://llvm.org/bugs/show_bug.cgi?id=21689 + // and MDEV-10229 .open_fts = open_fts, .roll_info = roll_info, - .state_lock = TOKU_MUTEX_INITIALIZER, - .state_cond = TOKU_COND_INITIALIZER, + .state_lock = {}, // Needs to be set to 0. + .state_cond = {}, // Needs to be set to 0. .state = TOKUTXN_LIVE, .num_pin = 0, .client_id = 0, .start_time = time(NULL), }; + // We initialize the locks afterwards, but to prevent undefined behaviour + // we zero-out the structures containing them. + ZERO_STRUCT(new_txn.txn_lock); + ZERO_STRUCT(new_txn.state_lock); + ZERO_STRUCT(new_txn.state_cond); + TOKUTXN result = NULL; XMEMDUP(result, &new_txn); invalidate_xa_xid(&result->xa_xid); From 128930c19b4ebc6a50f254bcee6af84db79ebe91 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Fri, 17 Jun 2016 12:39:20 -0400 Subject: [PATCH 077/112] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 58a6b369de910..db9d497c141a9 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=50 +MYSQL_VERSION_PATCH=51 MYSQL_VERSION_EXTRA= From e24a1833701d358b98d294716c2c1d24850bf982 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sat, 18 Jun 2016 10:46:55 +0400 Subject: [PATCH 078/112] MDEV-9969 mysql_install_db error processing ignore_db_dirs. test failed on Windows so fixed by testing slightly differently. --- mysql-test/r/mysqld_option_err.result | 1 - mysql-test/t/bootstrap.test | 10 ++++++++++ mysql-test/t/mysqld_option_err.test | 8 -------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/mysqld_option_err.result b/mysql-test/r/mysqld_option_err.result index 1870ea85270fc..4afcc5e0cb1b2 100644 --- a/mysql-test/r/mysqld_option_err.result +++ b/mysql-test/r/mysqld_option_err.result @@ -5,5 +5,4 @@ Test non-numeric value passed to number option. Test that bad value for plugin enum option is rejected correctly. Test that --help --verbose works Test that --not-known-option --help --verbose gives error -Test that specifying same directory several times handled properly. Done. diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test index e2d21c0d990c9..f92b7c5b14801 100644 --- a/mysql-test/t/bootstrap.test +++ b/mysql-test/t/bootstrap.test @@ -89,3 +89,13 @@ drop table t1; --replace_result .dll .so select * from mysql.plugin; truncate table mysql.plugin; + + +# +# MDEV-9969 mysql_install_db error processing ignore_db_dirs. +# +--write_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql +use test; +EOF +--exec $MYSQLD_BOOTSTRAP_CMD --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' < $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1 +--remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_9969.sql diff --git a/mysql-test/t/mysqld_option_err.test b/mysql-test/t/mysqld_option_err.test index 6f1e089fbe46b..0c38eba7ca923 100644 --- a/mysql-test/t/mysqld_option_err.test +++ b/mysql-test/t/mysqld_option_err.test @@ -56,12 +56,4 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --error 2 --exec $MYSQLD_BOOTSTRAP_CMD --not-known-option --help --verbose >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 -# -# MDEV-9969 mysql_install_db error processing ignore_db_dirs. -# - ---echo Test that specifying same directory several times handled properly. - ---exec echo "" | $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --ignore-db-dirs='some_dir' --ignore-db-dirs='some_dir' >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 - --echo Done. From 70ad689b11bfbd8a30a777f4893a5384628c00e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 20 Jun 2016 09:58:31 +0300 Subject: [PATCH 079/112] MDEV-8633: information_schema.index_statistics doesn't delete item when drop table indexes or drop table; Problem was that table and index statistics is removed from persistent tables but not from memory cache. Added functions to remove table and index statistics from memory cache. --- mysql-test/r/information_schema_stats.result | 70 +++++++++++++++ mysql-test/r/status_user.result | 4 - mysql-test/t/information_schema_stats.test | 44 +++++++++ sql/sql_show.cc | 94 ++++++++++++++++++++ sql/sql_show.h | 3 +- sql/sql_statistics.cc | 9 ++ 6 files changed, 219 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/information_schema_stats.result create mode 100644 mysql-test/t/information_schema_stats.test diff --git a/mysql-test/r/information_schema_stats.result b/mysql-test/r/information_schema_stats.result new file mode 100644 index 0000000000000..cd73636879c82 --- /dev/null +++ b/mysql-test/r/information_schema_stats.result @@ -0,0 +1,70 @@ +set global userstat=1; +create table just_a_test(id int,first_name varchar(10),last_name varchar(10),address varchar(100),phone bigint,email varchar(30), state varchar(30)); +insert into just_a_test values(1,'fa','la','china_a',11111111,'fa_la@163.com','California'), +(2,'fb','lb','china_b',22222222,'fb_lb@163.com','Arizona'), +(3,'fc','lc','china_c',33333333,'fc_lc@163.com','California'), +(4,'fd','ld','china_d',44444444,'fd_ld@163.com','Utah'), +(5,'fe','le','china_e',55555555,'fe_le@163.com','Arizona'); +alter table just_a_test add primary key (id); +alter table just_a_test add key IND_just_a_test_first_name_last_name(first_name,last_name); +alter table just_a_test add key IND_just_a_test_state(state); +select count(*) from just_a_test where first_name='fc' and last_name='lc'; +count(*) +1 +select count(*) from just_a_test where state = 'California'; +count(*) +2 +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +test just_a_test IND_just_a_test_state 2 +test just_a_test IND_just_a_test_first_name_last_name 1 +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test just_a_test 18 5 5 +alter table just_a_test drop key IND_just_a_test_first_name_last_name; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +test just_a_test IND_just_a_test_state 2 +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test just_a_test 23 5 5 +alter table just_a_test drop column state; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test just_a_test 28 5 5 +drop table just_a_test; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +create table just_a_test(id int not null primary key,first_name varchar(10),last_name varchar(10),address varchar(100),phone bigint,email varchar(30), state varchar(30),key(first_name,last_name),key(state)); +insert into just_a_test values(1,'fa','la','china_a',11111111,'fa_la@163.com','California'), +(2,'fb','lb','china_b',22222222,'fb_lb@163.com','Arizona'), +(3,'fc','lc','china_c',33333333,'fc_lc@163.com','California'), +(4,'fd','ld','china_d',44444444,'fd_ld@163.com','Utah'), +(5,'fe','le','china_e',55555555,'fe_le@163.com','Arizona'); +select count(*) from just_a_test where first_name='fc' and last_name='lc'; +count(*) +1 +select count(*) from just_a_test where state = 'California'; +count(*) +2 +select count(*) from just_a_test where id between 2 and 4; +count(*) +3 +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +test just_a_test first_name 1 +test just_a_test state 2 +test just_a_test PRIMARY 5 +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +test just_a_test 8 5 15 +drop table just_a_test; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES +set global userstat=0; diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 829c8abb634cc..c6248a85d3a93 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -128,16 +128,12 @@ handler_read_key set @@global.userstat=0; select * from information_schema.index_statistics; TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ -test t1 PRIMARY 2 select * from information_schema.table_statistics; TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES -test t1 6 13 13 show table_statistics; Table_schema Table_name Rows_read Rows_changed Rows_changed_x_#indexes -test t1 6 13 13 show index_statistics; Table_schema Table_name Index_name Rows_read -test t1 PRIMARY 2 select TOTAL_CONNECTIONS, CONCURRENT_CONNECTIONS, ROWS_READ, ROWS_SENT, ROWS_DELETED, ROWS_INSERTED, ROWS_UPDATED, SELECT_COMMANDS, UPDATE_COMMANDS, OTHER_COMMANDS, COMMIT_TRANSACTIONS, ROLLBACK_TRANSACTIONS, DENIED_CONNECTIONS, LOST_CONNECTIONS, ACCESS_DENIED, EMPTY_QUERIES from information_schema.client_statistics;; TOTAL_CONNECTIONS 1 CONCURRENT_CONNECTIONS 0 diff --git a/mysql-test/t/information_schema_stats.test b/mysql-test/t/information_schema_stats.test new file mode 100644 index 0000000000000..38248063d6875 --- /dev/null +++ b/mysql-test/t/information_schema_stats.test @@ -0,0 +1,44 @@ +# +# MDEV-8633: information_schema.index_statistics doesn't delete item when drop table indexes or drop table; +# +set global userstat=1; +create table just_a_test(id int,first_name varchar(10),last_name varchar(10),address varchar(100),phone bigint,email varchar(30), state varchar(30)); +insert into just_a_test values(1,'fa','la','china_a',11111111,'fa_la@163.com','California'), +(2,'fb','lb','china_b',22222222,'fb_lb@163.com','Arizona'), +(3,'fc','lc','china_c',33333333,'fc_lc@163.com','California'), +(4,'fd','ld','china_d',44444444,'fd_ld@163.com','Utah'), +(5,'fe','le','china_e',55555555,'fe_le@163.com','Arizona'); +alter table just_a_test add primary key (id); +alter table just_a_test add key IND_just_a_test_first_name_last_name(first_name,last_name); +alter table just_a_test add key IND_just_a_test_state(state); +select count(*) from just_a_test where first_name='fc' and last_name='lc'; +select count(*) from just_a_test where state = 'California'; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +alter table just_a_test drop key IND_just_a_test_first_name_last_name; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +alter table just_a_test drop column state; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +drop table just_a_test; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +# +# Test direct drop table +# +create table just_a_test(id int not null primary key,first_name varchar(10),last_name varchar(10),address varchar(100),phone bigint,email varchar(30), state varchar(30),key(first_name,last_name),key(state)); +insert into just_a_test values(1,'fa','la','china_a',11111111,'fa_la@163.com','California'), +(2,'fb','lb','china_b',22222222,'fb_lb@163.com','Arizona'), +(3,'fc','lc','china_c',33333333,'fc_lc@163.com','California'), +(4,'fd','ld','china_d',44444444,'fd_ld@163.com','Utah'), +(5,'fe','le','china_e',55555555,'fe_le@163.com','Arizona'); +select count(*) from just_a_test where first_name='fc' and last_name='lc'; +select count(*) from just_a_test where state = 'California'; +select count(*) from just_a_test where id between 2 and 4; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +drop table just_a_test; +select * from information_schema.index_statistics where table_schema='test' and table_name='just_a_test'; +select * from information_schema.table_statistics where table_schema='test' and table_name='just_a_test'; +set global userstat=0; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 931011dcbc265..97f6b86305837 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3460,6 +3460,100 @@ int fill_schema_table_stats(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(0); } +/* Remove all indexes for a given table from global index statistics */ + +static +int del_global_index_stats_for_table(THD *thd, uchar* cache_key, uint cache_key_length) +{ + int res = 0; + DBUG_ENTER("del_global_index_stats_for_table"); + + mysql_mutex_lock(&LOCK_global_index_stats); + + for (uint i= 0; i < global_index_stats.records;) + { + INDEX_STATS *index_stats = + (INDEX_STATS*) my_hash_element(&global_index_stats, i); + + /* We search correct db\0table_name\0 string */ + if (index_stats && + index_stats->index_name_length >= cache_key_length && + !memcmp(index_stats->index, cache_key, cache_key_length)) + { + res= my_hash_delete(&global_index_stats, (uchar*)index_stats); + /* + In our HASH implementation on deletion one elements + is moved into a place where a deleted element was, + and the last element is moved into the empty space. + Thus we need to re-examine the current element, but + we don't have to restart the search from the beginning. + */ + } + else + i++; + } + + mysql_mutex_unlock(&LOCK_global_index_stats); + DBUG_RETURN(res); +} + +/* Remove a table from global table statistics */ + +int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table) +{ + TABLE_STATS *table_stats; + int res = 0; + uchar *cache_key; + uint cache_key_length; + DBUG_ENTER("del_global_table_stat"); + + cache_key_length= db->length + 1 + table->length + 1; + + if(!(cache_key= (uchar *)my_malloc(cache_key_length, + MYF(MY_WME | MY_ZEROFILL)))) + { + /* Out of memory error already given */ + res = 1; + goto end; + } + + memcpy(cache_key, db->str, db->length); + memcpy(cache_key + db->length + 1, table->str, table->length); + + res= del_global_index_stats_for_table(thd, cache_key, cache_key_length); + + mysql_mutex_lock(&LOCK_global_table_stats); + + if((table_stats= (TABLE_STATS*) my_hash_search(&global_table_stats, + cache_key, + cache_key_length))) + res= my_hash_delete(&global_table_stats, (uchar*)table_stats); + + my_free(cache_key); + mysql_mutex_unlock(&LOCK_global_table_stats); + +end: + DBUG_RETURN(res); +} + +/* Remove a index from global index statistics */ + +int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info) +{ + INDEX_STATS *index_stats; + uint key_length= table->s->table_cache_key.length + key_info->name_length + 1; + int res = 0; + DBUG_ENTER("del_global_index_stat"); + mysql_mutex_lock(&LOCK_global_index_stats); + + if((index_stats= (INDEX_STATS*) my_hash_search(&global_index_stats, + key_info->cache_name, + key_length))) + res= my_hash_delete(&global_index_stats, (uchar*)index_stats); + + mysql_mutex_unlock(&LOCK_global_index_stats); + DBUG_RETURN(res); +} /* Fill information schema table with index statistics */ diff --git a/sql/sql_show.h b/sql/sql_show.h index 84064ae0a05a9..9ca60557cc079 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -113,7 +113,8 @@ void view_store_options(THD *thd, TABLE_LIST *table, String *buff); void init_fill_schema_files_row(TABLE* table); bool schema_table_store_record(THD *thd, TABLE *table); void initialize_information_schema_acl(); - +int del_global_index_stat(THD *thd, TABLE* tab, KEY* key_info); +int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table); ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name); ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx); int make_schema_select(THD *thd, SELECT_LEX *sel, diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index e86c84040b4f0..47a5a40ebeb44 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -29,6 +29,7 @@ #include "sql_statistics.h" #include "opt_range.h" #include "my_atomic.h" +#include "sql_show.h" /* The system variable 'use_stat_tables' can take one of the @@ -3193,6 +3194,10 @@ int delete_statistics_for_table(THD *thd, LEX_STRING *db, LEX_STRING *tab) rc= 1; } + err= del_global_table_stat(thd, db, tab); + if (err & !rc) + rc= 1; + thd->restore_stmt_binlog_format(save_binlog_format); close_system_tables(thd, &open_tables_backup); @@ -3339,6 +3344,10 @@ int delete_statistics_for_index(THD *thd, TABLE *tab, KEY *key_info, } } + err= del_global_index_stat(thd, tab, key_info); + if (err && !rc) + rc= 1; + thd->restore_stmt_binlog_format(save_binlog_format); close_system_tables(thd, &open_tables_backup); From a80dbe068ca650ef1f4daee2263f0bc6e7aeb0e1 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 20 Jun 2016 14:11:01 +0400 Subject: [PATCH 080/112] MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL The problem was that the loop in get_func_mm_tree() accessed improperly initialized instances of String, which resided in the bzero'ed part of the in_vector::base array. Strings in in_vector::base are originally initialized in Item_func_in::fix_length_and_dec(), in in_vector::in_vector() using sql_calloc, rather than using a String constructor, so their str_charset members are originally equal to NULL. Strings in in_vector::base are later initialized to good values in Item_func_in::fix_length_and_dec(), using array->set(), in this code: uint j=0; for (uint i=1 ; i < arg_count ; i++) { array->set(j,args[i]); if (!args[i]->null_value) // Skip NULL values j++; else have_null= 1; } if ((array->used_count= j)) array->sort(); NULLs are not taken into account, so at the end array->used_count can be smaller than array->count. This patch fixes the loop in opt_range.cc, in get_func_mm_tree(), to access only properly initialized elements in in_vector::base, preventing access to its bzero'ed non-initialized tail. --- mysql-test/r/func_in.result | 19 +++++++++++++++++++ mysql-test/t/func_in.test | 21 +++++++++++++++++++++ sql/opt_range.cc | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result index fc56660ac6277..210b0a9ef916d 100644 --- a/mysql-test/r/func_in.result +++ b/mysql-test/r/func_in.result @@ -812,3 +812,22 @@ EXECUTE s; 1 DROP TABLE t1; # End of 5.3 tests +# +# Start of 10.0 tests +# +# +# MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL +# +CREATE TABLE t1 +( +a INT(11), +b VARCHAR(10), +KEY (b) +); +INSERT INTO t1 VALUES (1,'x'),(2,'y'),(3,'z'); +SELECT * FROM t1 WHERE b NOT IN (NULL, '', 'A'); +a b +DROP TABLE t1; +# +# End of 10.0 tests +# diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 1e695142d906b..17736ac40c62f 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -606,3 +606,24 @@ EXECUTE s; DROP TABLE t1; --echo # End of 5.3 tests + +--echo # +--echo # Start of 10.0 tests +--echo # + +--echo # +--echo # MDEV-10020 InnoDB NOT IN Query Crash When One Item Is NULL +--echo # +CREATE TABLE t1 +( + a INT(11), + b VARCHAR(10), + KEY (b) +); +INSERT INTO t1 VALUES (1,'x'),(2,'y'),(3,'z'); +SELECT * FROM t1 WHERE b NOT IN (NULL, '', 'A'); +DROP TABLE t1; + +--echo # +--echo # End of 10.0 tests +--echo # diff --git a/sql/opt_range.cc b/sql/opt_range.cc index f051ed07a7e99..ae5899d8de450 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7730,7 +7730,7 @@ static SEL_TREE *get_func_mm_tree(RANGE_OPT_PARAM *param, Item_func *cond_func, break; } SEL_TREE *tree2; - for (; i < func->array->count; i++) + for (; i < func->array->used_count; i++) { if (func->array->compare_elems(i, i-1)) { From 7f38a070baa503a37af186ff24f39606816f55ec Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 17 Jun 2016 18:54:11 +0400 Subject: [PATCH 081/112] MDEV-10043 - main.events_restart fails sporadically in buildbot (crashes upon shutdown) There was race condition between shutdown thread and event worker threads. Shutdown thread waits for thread_count to become 0 in close_connections(). It may happen so that event worker thread was started but didn't increment thread_count by this time. In this case shutdown thread may miss wait for this working thread and continue deinitialization. Worker thread in turn may continue execution and crash on deinitialized data. Fixed by incrementing thread_count before thread is actually created like it is done for connection threads. Also let event scheduler not to inc/dec running threads counter for symmetry with other "service" threads. --- sql/event_scheduler.cc | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index beb3c864662fd..a5a3f7110b37f 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -131,12 +131,6 @@ post_init_event_thread(THD *thd) thd->cleanup(); return TRUE; } - - mysql_mutex_lock(&LOCK_thread_count); - threads.append(thd); - thread_count++; - inc_thread_running(); - mysql_mutex_unlock(&LOCK_thread_count); return FALSE; } @@ -158,7 +152,6 @@ deinit_event_thread(THD *thd) DBUG_PRINT("exit", ("Event thread finishing")); mysql_mutex_lock(&LOCK_thread_count); thread_count--; - dec_thread_running(); delete thd; mysql_cond_broadcast(&COND_thread_count); mysql_mutex_unlock(&LOCK_thread_count); @@ -195,6 +188,8 @@ pre_init_event_thread(THD* thd) thd->client_capabilities|= CLIENT_MULTI_RESULTS; mysql_mutex_lock(&LOCK_thread_count); thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; + threads.append(thd); + thread_count++; mysql_mutex_unlock(&LOCK_thread_count); /* @@ -241,13 +236,8 @@ event_scheduler_thread(void *arg) my_free(arg); if (!res) scheduler->run(thd); - else - { - thd->proc_info= "Clearing"; - net_end(&thd->net); - delete thd; - } + deinit_event_thread(thd); DBUG_LEAVE; // Against gcc warnings my_thread_end(); return 0; @@ -308,6 +298,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) DBUG_ENTER("Event_worker_thread::run"); DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd)); + inc_thread_running(); if (res) goto end; @@ -334,6 +325,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event) event->name.str)); delete event; + dec_thread_running(); deinit_event_thread(thd); DBUG_VOID_RETURN; @@ -432,13 +424,9 @@ Event_scheduler::start(int *err_no) " Can not create thread for event scheduler (errno=%d)", *err_no); - new_thd->proc_info= "Clearing"; - DBUG_ASSERT(new_thd->net.buff != 0); - net_end(&new_thd->net); - state= INITIALIZED; scheduler_thd= NULL; - delete new_thd; + deinit_event_thread(new_thd); delete scheduler_param_value; ret= true; @@ -505,7 +493,6 @@ Event_scheduler::run(THD *thd) } LOCK_DATA(); - deinit_event_thread(thd); scheduler_thd= NULL; state= INITIALIZED; DBUG_PRINT("info", ("Broadcasting COND_state back to the stoppers")); @@ -564,10 +551,7 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) sql_print_error("Event_scheduler::execute_top: Can not create event worker" " thread (errno=%d). Stopping event scheduler", res); - new_thd->proc_info= "Clearing"; - DBUG_ASSERT(new_thd->net.buff != 0); - net_end(&new_thd->net); - + deinit_event_thread(new_thd); goto error; } @@ -579,9 +563,6 @@ Event_scheduler::execute_top(Event_queue_element_for_exec *event_name) error: DBUG_PRINT("error", ("Event_scheduler::execute_top() res: %d", res)); - if (new_thd) - delete new_thd; - delete event_name; DBUG_RETURN(TRUE); } From 95bf696d2c8ee189a1836b5b0e4ec353aa4bda30 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 19 Jun 2016 14:51:03 +0200 Subject: [PATCH 082/112] MDEV-9749 InnoDB receives 'Bad file descriptor' error, possibly related to feedback plugin and MDEV-10250 InnoDB: Error: File (unknown): 'close' returned OS error 209. Cannot continue operation" after a failed connect() feedback plugin was continuing with the file descriptor, trying to send the data (which failed) and closing it at the end. Even though this fd might've been reused for something else already. --- plugin/feedback/url_http.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc index dff5da56a4f2b..fbea38c07eb16 100644 --- a/plugin/feedback/url_http.cc +++ b/plugin/feedback/url_http.cc @@ -190,6 +190,7 @@ int Url_http::send(const char* data, size_t data_length) break; closesocket(fd); + fd= INVALID_SOCKET; } freeaddrinfo(addrs); From a482e76e65a4fee70479e877929381c86b1ec62f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 20 Jun 2016 16:12:54 +0200 Subject: [PATCH 083/112] fix a mysql-5.5.50 merge: mysqlcheck quote identifiers correctly --- client/mysqlcheck.c | 4 ++-- mysql-test/r/mysqlcheck.result | 5 +++++ mysql-test/t/mysqlcheck.test | 5 +++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 011a0e2d738a2..75f841f3c5e30 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -756,7 +756,7 @@ static int fix_table_storage_name(const char *name) if (strncmp(name, "#mysql50#", 9)) DBUG_RETURN(1); - my_snprintf(qbuf, sizeof(qbuf), "RENAME TABLE `%s` TO `%s`", + my_snprintf(qbuf, sizeof(qbuf), "RENAME TABLE %`s TO %`s", name, name + 9); rc= run_query(qbuf); @@ -773,7 +773,7 @@ static int fix_database_storage_name(const char *name) if (strncmp(name, "#mysql50#", 9)) DBUG_RETURN(1); - my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE `%s` UPGRADE DATA DIRECTORY " + my_snprintf(qbuf, sizeof(qbuf), "ALTER DATABASE %`s UPGRADE DATA DIRECTORY " "NAME", name); rc= run_query(qbuf); if (verbose) diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index c5ba3e7dc792e..d2f4745c5f187 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -339,3 +339,8 @@ Repairing views test.v1 OK drop view v1; drop table t1; +create table `#mysql50#t1``1` (a int) engine=myisam; +show tables; +Tables_in_test +t1`1 +drop table `t1``1`; diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index ac42e1e184d19..7da14e3742ad8 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -350,3 +350,8 @@ create table t1(a int); --exec $MYSQL_CHECK --process-views --check-upgrade --auto-repair test drop view v1; drop table t1; + +create table `#mysql50#t1``1` (a int) engine=myisam; +--exec $MYSQL_CHECK --fix-table-names --databases test +show tables; +drop table `t1``1`; From c3c4d55e7e8dc9ec35ad27c6976fc3d85d6640b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 20 Jun 2016 22:08:55 +0300 Subject: [PATCH 084/112] Merge commit from 10.1: commit 4165961d54c7047f9574982edeb55885884d27a9 Author: Sergei Golubchik Fri Oct 16 02:07:06 2015 Committer: Sergei Golubchik Mon Nov 16 08:55:55 2015 disable innodb on sol10-64 because buildbot config invokes BUILD/compile-solaris-amd64 with the --extra-args=--without-plugin-innodb argument, but BUILD/compile-solaris-amd64 doesn't take arguments and doesn't invoke configure.pl, so this extra-args is lost. --- BUILD/compile-solaris-amd64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD/compile-solaris-amd64 b/BUILD/compile-solaris-amd64 index 8b032309beb7b..b24c1460dc4e6 100755 --- a/BUILD/compile-solaris-amd64 +++ b/BUILD/compile-solaris-amd64 @@ -3,6 +3,6 @@ export LDFLAGS='-m64 -lmtmalloc -R/usr/sfw/lib/64' export CFLAGS='-mtune=i386 -D__sun -m64 -mtune=athlon64' export CXXFLAGS='-mtune=i386 -D__sun -m64 -mtune=athlon64' -cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DWITH_EXTRA_CHARSETS=complex -DWITH_READLINE=ON -DWITH_SSL=bundled -DWITH_MAX=ON -DWITH_EMBEDDED_SERVER=ON -DWITH_ZLIB=bundled +cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DWITH_EXTRA_CHARSETS=complex -DWITH_READLINE=ON -DWITH_SSL=bundled -DWITH_MAX=ON -DWITH_EMBEDDED_SERVER=ON -DWITH_ZLIB=bundled -DPLUGIN_INNOBASE=NO gmake -j6 VERBOSE=1 From fa10a65dc293c9222687b33379cebf240cc4bf29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 21 Jun 2016 12:37:39 +0300 Subject: [PATCH 085/112] MDEV-9356: innodb.innodb_bug53290 fails (crashes) on sol10-64 in buildbot Analysis: In storage/innobase/row/row0merge.cc InnoDB calls thd_progress_init, thd_progress_report and thd_progress_end functions. These seem to cause crash on solaris 10 64-bit. Fix: Disable progress reporting on UNIV_SOLARIS until the actual issue causing the crash is fixed. The actual bug is not on InnoDB code base. --- storage/innobase/row/row0merge.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 14806ceb3b951..f75b1f66a7a6a 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2381,10 +2381,16 @@ row_merge_sort( of file marker). Thus, it must be at least one block. */ ut_ad(file->offset > 0); + /* These thd_progress* calls will crash on sol10-64 when innodb_plugin + is used. MDEV-9356: innodb.innodb_bug53290 fails (crashes) on + sol10-64 in buildbot. + */ +#ifndef UNIV_SOLARIS /* Progress report only for "normal" indexes. */ if (!(dup->index->type & DICT_FTS)) { thd_progress_init(trx->mysql_thd, 1); } +#endif /* UNIV_SOLARIS */ /* Merge the runs until we have one big run */ do { @@ -2394,9 +2400,11 @@ row_merge_sort( /* Report progress of merge sort to MySQL for show processlist progress field only for "normal" indexes. */ +#ifndef UNIV_SOLARIS if (!(dup->index->type & DICT_FTS)) { thd_progress_report(trx->mysql_thd, file->offset - num_runs, file->offset); } +#endif /* UNIV_SOLARIS */ if (error != DB_SUCCESS) { break; @@ -2407,9 +2415,11 @@ row_merge_sort( mem_free(run_offset); +#ifndef UNIV_SOLARIS if (!(dup->index->type & DICT_FTS)) { thd_progress_end(trx->mysql_thd); } +#endif /* UNIV_SOLARIS */ DBUG_RETURN(error); } From b42664e85e2cd512245de4fde94237a502fdbedb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 21 Jun 2016 14:20:09 +0200 Subject: [PATCH 086/112] 5.6.30-76.3 --- storage/xtradb/buf/buf0buf.cc | 20 ++ storage/xtradb/buf/buf0lru.cc | 19 +- storage/xtradb/fil/fil0fil.cc | 67 +++--- storage/xtradb/fts/fts0fts.cc | 266 +++++++++++++++++----- storage/xtradb/fts/fts0opt.cc | 81 +++++-- storage/xtradb/ha/ha0ha.cc | 4 + storage/xtradb/handler/ha_innodb.cc | 14 +- storage/xtradb/ibuf/ibuf0ibuf.cc | 2 +- storage/xtradb/include/fil0fil.h | 5 - storage/xtradb/include/fts0fts.h | 24 +- storage/xtradb/include/fts0types.h | 10 +- storage/xtradb/include/log0log.h | 17 +- storage/xtradb/include/log0log.ic | 12 +- storage/xtradb/include/log0online.h | 15 +- storage/xtradb/include/log0recv.h | 33 --- storage/xtradb/include/log0recv.ic | 16 -- storage/xtradb/include/os0file.h | 6 - storage/xtradb/include/os0sync.h | 128 +++++++---- storage/xtradb/include/srv0srv.h | 20 +- storage/xtradb/include/sync0rw.h | 8 +- storage/xtradb/include/sync0rw.ic | 14 +- storage/xtradb/include/sync0sync.h | 5 +- storage/xtradb/include/sync0sync.ic | 2 +- storage/xtradb/include/univ.i | 2 +- storage/xtradb/lock/lock0lock.cc | 11 + storage/xtradb/log/log0log.cc | 21 +- storage/xtradb/log/log0online.cc | 67 +++--- storage/xtradb/log/log0recv.cc | 329 ---------------------------- storage/xtradb/mem/mem0pool.cc | 1 + storage/xtradb/os/os0file.cc | 63 +++++- storage/xtradb/os/os0sync.cc | 247 ++++----------------- storage/xtradb/os/os0thread.cc | 15 +- storage/xtradb/row/row0merge.cc | 5 +- storage/xtradb/srv/srv0conc.cc | 4 + storage/xtradb/srv/srv0srv.cc | 98 +++++++-- storage/xtradb/srv/srv0start.cc | 50 +---- storage/xtradb/sync/sync0arr.cc | 12 +- storage/xtradb/sync/sync0rw.cc | 16 +- storage/xtradb/sync/sync0sync.cc | 40 ++-- storage/xtradb/trx/trx0i_s.cc | 2 + 40 files changed, 765 insertions(+), 1006 deletions(-) diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 1786ba51429ad..882f0af5aad1b 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -1454,6 +1454,7 @@ buf_pool_free_instance( buf_chunk_t* chunk; buf_chunk_t* chunks; buf_page_t* bpage; + ulint i; bpage = UT_LIST_GET_LAST(buf_pool->LRU); while (bpage != NULL) { @@ -1477,10 +1478,29 @@ buf_pool_free_instance( mem_free(buf_pool->watch); buf_pool->watch = NULL; + for (i = BUF_FLUSH_LRU; i < BUF_FLUSH_N_TYPES; i++) { + os_event_free(buf_pool->no_flush[i]); + } + mutex_free(&buf_pool->LRU_list_mutex); + mutex_free(&buf_pool->free_list_mutex); + mutex_free(&buf_pool->zip_free_mutex); + mutex_free(&buf_pool->zip_hash_mutex); + mutex_free(&buf_pool->zip_mutex); + mutex_free(&buf_pool->flush_state_mutex); + mutex_free(&buf_pool->flush_list_mutex); + chunks = buf_pool->chunks; chunk = chunks + buf_pool->n_chunks; while (--chunk >= chunks) { + buf_block_t* block = chunk->blocks; + for (i = 0; i < chunk->size; i++, block++) { + mutex_free(&block->mutex); + rw_lock_free(&block->lock); +#ifdef UNIV_SYNC_DEBUG + rw_lock_free(&block->debug_latch); +#endif + } os_mem_free_large(chunk->mem, chunk->mem_size); } diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index af816d36e239a..bb0f4d44052f6 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -607,6 +607,7 @@ buf_flush_or_remove_pages( bpage != NULL; bpage = prev) { + ut_ad(!must_restart); ut_a(buf_page_in_file(bpage)); /* Save the previous link because once we free the @@ -624,9 +625,6 @@ buf_flush_or_remove_pages( /* Remove was unsuccessful, we have to try again by scanning the entire list from the end. - This also means that we never released the - flush list mutex. Therefore we can trust the prev - pointer. buf_flush_or_remove_page() released the flush list mutex but not the LRU list mutex. Therefore it is possible that a new page was @@ -643,6 +641,11 @@ buf_flush_or_remove_pages( iteration. */ all_freed = false; + if (UNIV_UNLIKELY(must_restart)) { + + /* Cannot trust the prev pointer */ + break; + } } else if (flush) { /* The processing was successful. And during the @@ -650,12 +653,9 @@ buf_flush_or_remove_pages( when calling buf_page_flush(). We cannot trust prev pointer. */ goto rescan; - } else if (UNIV_UNLIKELY(must_restart)) { - - ut_ad(!all_freed); - break; } + ut_ad(!must_restart); ++processed; /* Yield if we have hogged the CPU and mutexes for too long. */ @@ -666,6 +666,11 @@ buf_flush_or_remove_pages( /* Reset the batch size counter if we had to yield. */ processed = 0; + } else if (UNIV_UNLIKELY(must_restart)) { + + /* Cannot trust the prev pointer */ + all_freed = false; + break; } #ifdef DBUG_OFF diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 981df578acb5f..1dd5620825fe7 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -3248,8 +3248,6 @@ fil_create_link_file( const char* tablename, /*!< in: tablename */ const char* filepath) /*!< in: pathname of tablespace */ { - os_file_t file; - ibool success; dberr_t err = DB_SUCCESS; char* link_filepath; char* prev_filepath = fil_read_link_file(tablename); @@ -3268,13 +3266,24 @@ fil_create_link_file( link_filepath = fil_make_isl_name(tablename); - file = os_file_create_simple_no_error_handling( - innodb_file_data_key, link_filepath, - OS_FILE_CREATE, OS_FILE_READ_WRITE, &success); + /** Check if the file already exists. */ + FILE* file = NULL; + ibool exists; + os_file_type_t ftype; - if (!success) { - /* The following call will print an error message */ - ulint error = os_file_get_last_error(true); + bool success = os_file_status(link_filepath, &exists, &ftype); + + ulint error = 0; + if (success && !exists) { + file = fopen(link_filepath, "w"); + if (file == NULL) { + /* This call will print its own error message */ + error = os_file_get_last_error(true); + } + } else { + error = OS_FILE_ALREADY_EXISTS; + } + if (error != 0) { ut_print_timestamp(stderr); fputs(" InnoDB: Cannot create file ", stderr); @@ -3299,13 +3308,17 @@ fil_create_link_file( return(err); } - if (!os_file_write(link_filepath, file, filepath, 0, - strlen(filepath))) { + ulint rbytes = fwrite(filepath, 1, strlen(filepath), file); + if (rbytes != strlen(filepath)) { + os_file_get_last_error(true); + ib_logf(IB_LOG_LEVEL_ERROR, + "cannot write link file " + "%s",filepath); err = DB_ERROR; } /* Close the file, we only need it at startup */ - os_file_close(file); + fclose(file); mem_free(link_filepath); @@ -5185,8 +5198,8 @@ fil_extend_space_to_desired_size( ib_logf(IB_LOG_LEVEL_ERROR, "preallocating file space for file \'%s\' " "failed. Current size " INT64PF - ", len " INT64PF ", desired size " INT64PF - "\n", node->name, start_offset, end_offset, + ", len " INT64PF ", desired size " INT64PF, + node->name, start_offset, end_offset, start_offset + end_offset); } mutex_enter(&fil_system->mutex); @@ -6254,10 +6267,7 @@ void fil_close(void) /*===========*/ { -#ifndef UNIV_HOTBACKUP - /* The mutex should already have been freed. */ - ut_ad(fil_system->mutex.magic_n == 0); -#endif /* !UNIV_HOTBACKUP */ + mutex_free(&fil_system->mutex); hash_table_free(fil_system->spaces); @@ -6781,27 +6791,6 @@ fil_mtr_rename_log( /************************************************************************* functions to access is_corrupt flag of fil_space_t*/ -ibool -fil_space_is_corrupt( -/*=================*/ - ulint space_id) -{ - fil_space_t* space; - ibool ret = FALSE; - - mutex_enter(&fil_system->mutex); - - space = fil_space_get_by_id(space_id); - - if (UNIV_UNLIKELY(space && space->is_corrupt)) { - ret = TRUE; - } - - mutex_exit(&fil_system->mutex); - - return(ret); -} - void fil_space_set_corrupt( /*==================*/ diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 5d6d5ae7cf9e8..25047b38b9de0 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -260,16 +260,18 @@ static const char* fts_config_table_insert_values_sql = "INSERT INTO \"%s\" VALUES ('" FTS_TABLE_STATE "', '0');\n"; -/****************************************************************//** -Run SYNC on the table, i.e., write out data from the cache to the +/** Run SYNC on the table, i.e., write out data from the cache to the FTS auxiliary INDEX table and clear the cache at the end. -@return DB_SUCCESS if all OK */ +@param[in,out] sync sync state +@param[in] unlock_cache whether unlock cache lock when write node +@param[in] wait whether wait when a sync is in progress +@return DB_SUCCESS if all OK */ static dberr_t fts_sync( -/*=====*/ - fts_sync_t* sync) /*!< in: sync state */ - __attribute__((nonnull)); + fts_sync_t* sync, + bool unlock_cache, + bool wait); /****************************************************************//** Release all resources help by the words rb tree e.g., the node ilist. */ @@ -653,6 +655,7 @@ fts_cache_create( mem_heap_zalloc(heap, sizeof(fts_sync_t))); cache->sync->table = table; + cache->sync->event = os_event_create(); /* Create the index cache vector that will hold the inverted indexes. */ cache->indexes = ib_vector_create( @@ -1207,6 +1210,7 @@ fts_cache_destroy( mutex_free(&cache->optimize_lock); mutex_free(&cache->deleted_lock); mutex_free(&cache->doc_id_lock); + os_event_free(cache->sync->event); if (cache->stopword_info.cached_stopword) { rbt_free(cache->stopword_info.cached_stopword); @@ -1435,7 +1439,7 @@ fts_cache_add_doc( ib_vector_last(word->nodes)); } - if (fts_node == NULL + if (fts_node == NULL || fts_node->synced || fts_node->ilist_size > FTS_ILIST_MAX_SIZE || doc_id < fts_node->last_doc_id) { @@ -2886,35 +2890,28 @@ fts_doc_ids_free( } /*********************************************************************//** -Do commit-phase steps necessary for the insertion of a new row. -@return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) -dberr_t +Do commit-phase steps necessary for the insertion of a new row. */ +void fts_add( /*====*/ fts_trx_table_t*ftt, /*!< in: FTS trx table */ fts_trx_row_t* row) /*!< in: row */ { dict_table_t* table = ftt->table; - dberr_t error = DB_SUCCESS; doc_id_t doc_id = row->doc_id; ut_a(row->state == FTS_INSERT || row->state == FTS_MODIFY); fts_add_doc_by_id(ftt, doc_id, row->fts_indexes); - if (error == DB_SUCCESS) { - mutex_enter(&table->fts->cache->deleted_lock); - ++table->fts->cache->added; - mutex_exit(&table->fts->cache->deleted_lock); + mutex_enter(&table->fts->cache->deleted_lock); + ++table->fts->cache->added; + mutex_exit(&table->fts->cache->deleted_lock); - if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID) - && doc_id >= table->fts->cache->next_doc_id) { - table->fts->cache->next_doc_id = doc_id + 1; - } + if (!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID) + && doc_id >= table->fts->cache->next_doc_id) { + table->fts->cache->next_doc_id = doc_id + 1; } - - return(error); } /*********************************************************************//** @@ -3025,7 +3022,7 @@ fts_modify( error = fts_delete(ftt, row); if (error == DB_SUCCESS) { - error = fts_add(ftt, row); + fts_add(ftt, row); } return(error); @@ -3114,7 +3111,7 @@ fts_commit_table( switch (row->state) { case FTS_INSERT: - error = fts_add(ftt, row); + fts_add(ftt, row); break; case FTS_MODIFY: @@ -3553,16 +3550,34 @@ fts_add_doc_by_id( get_doc->index_cache, doc_id, doc.tokens); + bool need_sync = false; + if ((cache->total_size > fts_max_cache_size / 10 + || fts_need_sync) + && !cache->sync->in_progress) { + need_sync = true; + } + rw_lock_x_unlock(&table->fts->cache->lock); DBUG_EXECUTE_IF( "fts_instrument_sync", - fts_sync(cache->sync); + fts_optimize_request_sync_table(table); + os_event_wait(cache->sync->event); + ); + + DBUG_EXECUTE_IF( + "fts_instrument_sync_debug", + fts_sync(cache->sync, true, true); ); - if (cache->total_size > fts_max_cache_size - || fts_need_sync) { - fts_sync(cache->sync); + DEBUG_SYNC_C("fts_instrument_sync_request"); + DBUG_EXECUTE_IF( + "fts_instrument_sync_request", + fts_optimize_request_sync_table(table); + ); + + if (need_sync) { + fts_optimize_request_sync_table(table); } mtr_start(&mtr); @@ -3933,16 +3948,17 @@ fts_sync_add_deleted_cache( return(error); } -/*********************************************************************//** -Write the words and ilist to disk. +/** Write the words and ilist to disk. +@param[in,out] trx transaction +@param[in] index_cache index cache +@param[in] unlock_cache whether unlock cache when write node @return DB_SUCCESS if all went well else error code */ static __attribute__((nonnull, warn_unused_result)) dberr_t fts_sync_write_words( -/*=================*/ - trx_t* trx, /*!< in: transaction */ - fts_index_cache_t* - index_cache) /*!< in: index cache */ + trx_t* trx, + fts_index_cache_t* index_cache, + bool unlock_cache) { fts_table_t fts_table; ulint n_nodes = 0; @@ -3950,8 +3966,8 @@ fts_sync_write_words( const ib_rbt_node_t* rbt_node; dberr_t error = DB_SUCCESS; ibool print_error = FALSE; -#ifdef FTS_DOC_STATS_DEBUG dict_table_t* table = index_cache->index->table; +#ifdef FTS_DOC_STATS_DEBUG ulint n_new_words = 0; #endif /* FTS_DOC_STATS_DEBUG */ @@ -3964,7 +3980,7 @@ fts_sync_write_words( since we want to free the memory used during caching. */ for (rbt_node = rbt_first(index_cache->words); rbt_node; - rbt_node = rbt_first(index_cache->words)) { + rbt_node = rbt_next(index_cache->words, rbt_node)) { ulint i; ulint selected; @@ -3997,27 +4013,47 @@ fts_sync_write_words( } #endif /* FTS_DOC_STATS_DEBUG */ - n_nodes += ib_vector_size(word->nodes); - - /* We iterate over all the nodes even if there was an error, - this is to free the memory of the fts_node_t elements. */ + /* We iterate over all the nodes even if there was an error */ for (i = 0; i < ib_vector_size(word->nodes); ++i) { fts_node_t* fts_node = static_cast( ib_vector_get(word->nodes, i)); + if (fts_node->synced) { + continue; + } else { + fts_node->synced = true; + } + + /*FIXME: we need to handle the error properly. */ if (error == DB_SUCCESS) { + if (unlock_cache) { + rw_lock_x_unlock( + &table->fts->cache->lock); + } error = fts_write_node( trx, &index_cache->ins_graph[selected], &fts_table, &word->text, fts_node); - } - ut_free(fts_node->ilist); - fts_node->ilist = NULL; + DEBUG_SYNC_C("fts_write_node"); + DBUG_EXECUTE_IF("fts_write_node_crash", + DBUG_SUICIDE();); + + DBUG_EXECUTE_IF("fts_instrument_sync_sleep", + os_thread_sleep(1000000); + ); + + if (unlock_cache) { + rw_lock_x_lock( + &table->fts->cache->lock); + } + } } + n_nodes += ib_vector_size(word->nodes); + if (error != DB_SUCCESS && !print_error) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error (%s) writing " @@ -4026,9 +4062,6 @@ fts_sync_write_words( print_error = TRUE; } - - /* NOTE: We are responsible for free'ing the node */ - ut_free(rbt_remove_node(index_cache->words, rbt_node)); } #ifdef FTS_DOC_STATS_DEBUG @@ -4329,7 +4362,7 @@ fts_sync_index( ut_ad(rbt_validate(index_cache->words)); - error = fts_sync_write_words(trx, index_cache); + error = fts_sync_write_words(sync->trx, index_cache, sync->unlock_cache); #ifdef FTS_DOC_STATS_DEBUG /* FTS_RESOLVE: the word counter info in auxiliary table "DOC_ID" @@ -4345,6 +4378,36 @@ fts_sync_index( return(error); } +/** Check if index cache has been synced completely +@param[in,out] sync sync state +@param[in,out] index_cache index cache +@return true if index is synced, otherwise false. */ +static +bool +fts_sync_index_check( + fts_sync_t* sync, + fts_index_cache_t* index_cache) +{ + const ib_rbt_node_t* rbt_node; + + for (rbt_node = rbt_first(index_cache->words); + rbt_node != NULL; + rbt_node = rbt_next(index_cache->words, rbt_node)) { + + fts_tokenizer_word_t* word; + word = rbt_value(fts_tokenizer_word_t, rbt_node); + + fts_node_t* fts_node; + fts_node = static_cast(ib_vector_last(word->nodes)); + + if (!fts_node->synced) { + return(false); + } + } + + return(true); +} + /*********************************************************************//** Commit the SYNC, change state of processed doc ids etc. @return DB_SUCCESS if all OK */ @@ -4421,21 +4484,53 @@ fts_sync_rollback( trx_t* trx = sync->trx; fts_cache_t* cache = sync->table->fts->cache; + for (ulint i = 0; i < ib_vector_size(cache->indexes); ++i) { + ulint j; + fts_index_cache_t* index_cache; + + index_cache = static_cast( + ib_vector_get(cache->indexes, i)); + + for (j = 0; fts_index_selector[j].value; ++j) { + + if (index_cache->ins_graph[j] != NULL) { + + fts_que_graph_free_check_lock( + NULL, index_cache, + index_cache->ins_graph[j]); + + index_cache->ins_graph[j] = NULL; + } + + if (index_cache->sel_graph[j] != NULL) { + + fts_que_graph_free_check_lock( + NULL, index_cache, + index_cache->sel_graph[j]); + + index_cache->sel_graph[j] = NULL; + } + } + } + rw_lock_x_unlock(&cache->lock); fts_sql_rollback(trx); trx_free_for_background(trx); } -/****************************************************************//** -Run SYNC on the table, i.e., write out data from the cache to the +/** Run SYNC on the table, i.e., write out data from the cache to the FTS auxiliary INDEX table and clear the cache at the end. +@param[in,out] sync sync state +@param[in] unlock_cache whether unlock cache lock when write node +@param[in] wait whether wait when a sync is in progress @return DB_SUCCESS if all OK */ static dberr_t fts_sync( -/*=====*/ - fts_sync_t* sync) /*!< in: sync state */ + fts_sync_t* sync, + bool unlock_cache, + bool wait) { ulint i; dberr_t error = DB_SUCCESS; @@ -4443,8 +4538,35 @@ fts_sync( rw_lock_x_lock(&cache->lock); + /* Check if cache is being synced. + Note: we release cache lock in fts_sync_write_words() to + avoid long wait for the lock by other threads. */ + while (sync->in_progress) { + rw_lock_x_unlock(&cache->lock); + + if (wait) { + os_event_wait(sync->event); + } else { + return(DB_SUCCESS); + } + + rw_lock_x_lock(&cache->lock); + } + + sync->unlock_cache = unlock_cache; + sync->in_progress = true; + + DEBUG_SYNC_C("fts_sync_begin"); fts_sync_begin(sync); +begin_sync: + if (cache->total_size > fts_max_cache_size) { + /* Avoid the case: sync never finish when + insert/update keeps comming. */ + ut_ad(sync->unlock_cache); + sync->unlock_cache = false; + } + for (i = 0; i < ib_vector_size(cache->indexes); ++i) { fts_index_cache_t* index_cache; @@ -4459,21 +4581,43 @@ fts_sync( if (error != DB_SUCCESS && !sync->interrupted) { - break; + goto end_sync; } } DBUG_EXECUTE_IF("fts_instrument_sync_interrupted", sync->interrupted = true; error = DB_INTERRUPTED; + goto end_sync; ); + /* Make sure all the caches are synced. */ + for (i = 0; i < ib_vector_size(cache->indexes); ++i) { + fts_index_cache_t* index_cache; + + index_cache = static_cast( + ib_vector_get(cache->indexes, i)); + + if (index_cache->index->to_be_dropped + || fts_sync_index_check(sync, index_cache)) { + continue; + } + + goto begin_sync; + } + +end_sync: if (error == DB_SUCCESS && !sync->interrupted) { error = fts_sync_commit(sync); } else { fts_sync_rollback(sync); } + rw_lock_x_lock(&cache->lock); + sync->in_progress = false; + os_event_set(sync->event); + rw_lock_x_unlock(&cache->lock); + /* We need to check whether an optimize is required, for that we make copies of the two variables that control the trigger. These variables can change behind our back and we don't want to hold the @@ -4488,21 +4632,25 @@ fts_sync( return(error); } -/****************************************************************//** -Run SYNC on the table, i.e., write out data from the cache to the -FTS auxiliary INDEX table and clear the cache at the end. */ +/** Run SYNC on the table, i.e., write out data from the cache to the +FTS auxiliary INDEX table and clear the cache at the end. +@param[in,out] table fts table +@param[in] unlock_cache whether unlock cache when write node +@param[in] wait whether wait for existing sync to finish +@return DB_SUCCESS on success, error code on failure. */ UNIV_INTERN dberr_t fts_sync_table( -/*===========*/ - dict_table_t* table) /*!< in: table */ + dict_table_t* table, + bool unlock_cache, + bool wait) { dberr_t err = DB_SUCCESS; ut_ad(table->fts); if (!dict_table_is_discarded(table) && table->fts->cache) { - err = fts_sync(table->fts->cache->sync); + err = fts_sync(table->fts->cache->sync, unlock_cache, wait); } return(err); diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 2a0aa4daf1231..711c5f53d01c9 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -87,6 +87,7 @@ enum fts_msg_type_t { FTS_MSG_DEL_TABLE, /*!< Remove a table from the optimize threads work queue */ + FTS_MSG_SYNC_TABLE /*!< Sync fts cache of a table */ }; /** Compressed list of words that have been read from FTS INDEX @@ -2652,6 +2653,39 @@ fts_optimize_remove_table( os_event_free(event); } +/** Send sync fts cache for the table. +@param[in] table table to sync */ +UNIV_INTERN +void +fts_optimize_request_sync_table( + dict_table_t* table) +{ + fts_msg_t* msg; + table_id_t* table_id; + + /* if the optimize system not yet initialized, return */ + if (!fts_optimize_wq) { + return; + } + + /* FTS optimizer thread is already exited */ + if (fts_opt_start_shutdown) { + ib_logf(IB_LOG_LEVEL_INFO, + "Try to sync table %s after FTS optimize" + " thread exiting.", table->name); + return; + } + + msg = fts_optimize_create_msg(FTS_MSG_SYNC_TABLE, NULL); + + table_id = static_cast( + mem_heap_alloc(msg->heap, sizeof(table_id_t))); + *table_id = table->id; + msg->ptr = table_id; + + ib_wqueue_add(fts_optimize_wq, msg, msg->heap); +} + /**********************************************************************//** Find the slot for a particular table. @return slot if found else NULL. */ @@ -2932,6 +2966,25 @@ fts_optimize_need_sync( } #endif +/** Sync fts cache of a table +@param[in] table_id table id */ +void +fts_optimize_sync_table( + table_id_t table_id) +{ + dict_table_t* table = NULL; + + table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL); + + if (table) { + if (dict_table_has_fts_index(table) && table->fts->cache) { + fts_sync_table(table, true, false); + } + + dict_table_close(table, FALSE, FALSE); + } +} + /**********************************************************************//** Optimize all FTS tables. @return Dummy return */ @@ -3053,6 +3106,11 @@ fts_optimize_thread( ((fts_msg_del_t*) msg->ptr)->event); break; + case FTS_MSG_SYNC_TABLE: + fts_optimize_sync_table( + *static_cast(msg->ptr)); + break; + default: ut_error; } @@ -3079,26 +3137,7 @@ fts_optimize_thread( ib_vector_get(tables, i)); if (slot->state != FTS_STATE_EMPTY) { - dict_table_t* table = NULL; - - /*slot->table may be freed, so we try to open - table by slot->table_id.*/ - table = dict_table_open_on_id( - slot->table_id, FALSE, - DICT_TABLE_OP_NORMAL); - - if (table) { - - if (dict_table_has_fts_index(table)) { - fts_sync_table(table); - } - - if (table->fts) { - fts_free(table); - } - - dict_table_close(table, FALSE, FALSE); - } + fts_optimize_sync_table(slot->table_id); } } } diff --git a/storage/xtradb/ha/ha0ha.cc b/storage/xtradb/ha/ha0ha.cc index b79ae922045c2..3674260f17303 100644 --- a/storage/xtradb/ha/ha0ha.cc +++ b/storage/xtradb/ha/ha0ha.cc @@ -155,11 +155,15 @@ ha_clear( switch (table->type) { case HASH_TABLE_SYNC_MUTEX: + for (ulint i = 0; i < table->n_sync_obj; i++) + mutex_free(table->sync_obj.mutexes + i); mem_free(table->sync_obj.mutexes); table->sync_obj.mutexes = NULL; break; case HASH_TABLE_SYNC_RW_LOCK: + for (ulint i = 0; i < table->n_sync_obj; i++) + rw_lock_free(table->sync_obj.rw_locks + i); mem_free(table->sync_obj.rw_locks); table->sync_obj.rw_locks = NULL; break; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3d10f04fe078e..06230a9507630 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. Copyright (c) 2012, Facebook Inc. @@ -3813,6 +3813,16 @@ innobase_init( innobase_open_files = table_cache_size; } } + + if (innobase_open_files > (long) open_files_limit) { + fprintf(stderr, + "innodb_open_files should not be greater" + " than the open_files_limit.\n"); + if (innobase_open_files > (long) table_cache_size) { + innobase_open_files = table_cache_size; + } + } + srv_max_n_open_files = (ulint) innobase_open_files; srv_innodb_status = (ibool) innobase_create_status_file; @@ -12258,7 +12268,7 @@ ha_innobase::optimize( if (innodb_optimize_fulltext_only) { if (prebuilt->table->fts && prebuilt->table->fts->cache && !dict_table_is_discarded(prebuilt->table)) { - fts_sync_table(prebuilt->table); + fts_sync_table(prebuilt->table, false, true); fts_optimize_table(prebuilt->table); } return(HA_ADMIN_OK); diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc index 17d9854c30d2b..4bca5bbdf2a52 100644 --- a/storage/xtradb/ibuf/ibuf0ibuf.cc +++ b/storage/xtradb/ibuf/ibuf0ibuf.cc @@ -2892,7 +2892,7 @@ ibuf_contract_in_background( sum_bytes += n_bytes; sum_pages += n_pag2; - srv_inc_activity_count(); + srv_inc_activity_count(true); } return(sum_bytes); diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 1c78519cac5c5..29d3ed9877914 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -1048,11 +1048,6 @@ fil_system_hash_nodes(void); /************************************************************************* functions to access is_corrupt flag of fil_space_t*/ -ibool -fil_space_is_corrupt( -/*=================*/ - ulint space_id); - void fil_space_set_corrupt( /*==================*/ diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index d54ed281d9a13..9f7b0216d9b88 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -724,6 +724,13 @@ fts_optimize_remove_table( /*======================*/ dict_table_t* table); /*!< in: table to remove */ +/** Send sync fts cache for the table. +@param[in] table table to sync */ +UNIV_INTERN +void +fts_optimize_request_sync_table( + dict_table_t* table); + /**********************************************************************//** Signal the optimize thread to prepare for shutdown. */ UNIV_INTERN @@ -826,15 +833,18 @@ fts_drop_index_split_tables( dict_index_t* index) /*!< in: fts instance */ __attribute__((nonnull, warn_unused_result)); -/****************************************************************//** -Run SYNC on the table, i.e., write out data from the cache to the -FTS auxiliary INDEX table and clear the cache at the end. */ +/** Run SYNC on the table, i.e., write out data from the cache to the +FTS auxiliary INDEX table and clear the cache at the end. +@param[in,out] table fts table +@param[in] unlock_cache whether unlock cache when write node +@param[in] wait whether wait for existing sync to finish +@return DB_SUCCESS on success, error code on failure. */ UNIV_INTERN dberr_t fts_sync_table( -/*===========*/ - dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + dict_table_t* table, + bool unlock_cache, + bool wait); /****************************************************************//** Free the query graph but check whether dict_sys->mutex is already diff --git a/storage/xtradb/include/fts0types.h b/storage/xtradb/include/fts0types.h index 64677428331b5..e495fe72a606b 100644 --- a/storage/xtradb/include/fts0types.h +++ b/storage/xtradb/include/fts0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -122,7 +122,11 @@ struct fts_sync_t { doc_id_t max_doc_id; /*!< The doc id at which the cache was noted as being full, we use this to set the upper_limit field */ - ib_time_t start_time; /*!< SYNC start time */ + ib_time_t start_time; /*!< SYNC start time */ + bool in_progress; /*!< flag whether sync is in progress.*/ + bool unlock_cache; /*!< flag whether unlock cache when + write fts node */ + os_event_t event; /*!< sync finish event */ }; /** The cache for the FTS system. It is a memory-based inverted index @@ -165,7 +169,6 @@ struct fts_cache_t { objects, they are recreated after a SYNC is completed */ - ib_alloc_t* self_heap; /*!< This heap is the heap out of which an instance of the cache itself was created. Objects created using @@ -212,6 +215,7 @@ struct fts_node_t { ulint ilist_size_alloc; /*!< Allocated size of ilist in bytes */ + bool synced; /*!< flag whether the node is synced */ }; /** A tokenizer word. Contains information about one word. */ diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h index fbaf0a1e63380..c8fe996994dc9 100644 --- a/storage/xtradb/include/log0log.h +++ b/storage/xtradb/include/log0log.h @@ -322,17 +322,6 @@ log_archive_do( ulint* n_bytes);/*!< out: archive log buffer size, 0 if nothing to archive */ /****************************************************************//** -Writes the log contents to the archive up to the lsn when this function was -called, and stops the archiving. When archiving is started again, the archived -log file numbers start from a number one higher, so that the archiving will -not write again to the archived log files which exist when this function -returns. -@return DB_SUCCESS or DB_ERROR */ -UNIV_INTERN -ulint -log_archive_stop(void); -/*==================*/ -/****************************************************************//** Starts again archiving which has been stopped. @return DB_SUCCESS or DB_ERROR */ UNIV_INTERN @@ -594,10 +583,8 @@ log_mem_free(void); /*==============*/ /****************************************************************//** -Safely reads the log_sys->tracked_lsn value. Uses atomic operations -if available, otherwise this field is protected with the log system -mutex. The writer counterpart function is log_set_tracked_lsn() in -log0online.c. +Safely reads the log_sys->tracked_lsn value. The writer counterpart function +is log_set_tracked_lsn() in log0online.c. @return log_sys->tracked_lsn value. */ UNIV_INLINE diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic index 6402c7df1e7a8..f24c369be3354 100644 --- a/storage/xtradb/include/log0log.ic +++ b/storage/xtradb/include/log0log.ic @@ -514,10 +514,8 @@ log_free_check(void) #endif /* !UNIV_HOTBACKUP */ /****************************************************************//** -Safely reads the log_sys->tracked_lsn value. Uses atomic operations -if available, otherwise this field is protected with the log system -mutex. The writer counterpart function is log_set_tracked_lsn() in -log0online.c. +Safely reads the log_sys->tracked_lsn value. The writer counterpart function +is log_set_tracked_lsn() in log0online.c. @return log_sys->tracked_lsn value. */ UNIV_INLINE @@ -525,11 +523,7 @@ lsn_t log_get_tracked_lsn(void) /*=====================*/ { -#ifdef HAVE_ATOMIC_BUILTINS_64 - return os_atomic_increment_uint64(&log_sys->tracked_lsn, 0); -#else - ut_ad(mutex_own(&(log_sys->mutex))); + os_rmb; return log_sys->tracked_lsn; -#endif } diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h index 1ef4df7d6da35..67dc0d72b4bcd 100644 --- a/storage/xtradb/include/log0online.h +++ b/storage/xtradb/include/log0online.h @@ -73,20 +73,7 @@ UNIV_INTERN ibool log_online_purge_changed_page_bitmaps( /*==================================*/ - ib_uint64_t lsn); /*!(signal_count()) < count_mask); + count_and_set++; + } + + /** Return how many times this event has been signalled */ + ib_int64_t signal_count(void) const + { + return (count_and_set & count_mask); + } }; /** Denotes an infinite delay for os_event_wait_time() */ @@ -115,8 +160,7 @@ struct os_event { /** Operating system mutex handle */ typedef struct os_mutex_t* os_ib_mutex_t; -/** Mutex protecting counts and the event and OS 'slow' mutex lists */ -extern os_ib_mutex_t os_sync_mutex; +// All the os_*_count variables are accessed atomically /** This is incremented by 1 in os_thread_create and decremented by 1 in os_thread_exit */ @@ -132,12 +176,15 @@ UNIV_INTERN void os_sync_init(void); /*==============*/ -/*********************************************************//** -Frees created events and OS 'slow' mutexes. */ + +/** Create an event semaphore, i.e., a semaphore which may just have two +states: signaled and nonsignaled. The created event is manual reset: it must be +reset explicitly by calling sync_os_reset_event. +@param[in,out] event memory block where to create the event */ UNIV_INTERN void -os_sync_free(void); -/*==============*/ +os_event_create(os_event_t event); + /*********************************************************//** Creates an event semaphore, i.e., a semaphore which may just have two states: signaled and nonsignaled. The created event is manual reset: it must be reset @@ -173,7 +220,10 @@ UNIV_INTERN void os_event_free( /*==========*/ - os_event_t event); /*!< in: event to free */ + os_event_t event, /*!< in: event to free */ + bool free_memory = true); + /*!< in: if true, deallocate the event memory + block too */ /**********************************************************//** Waits for an event object until it is in the signaled state. @@ -450,28 +500,7 @@ amount to decrement. */ # define os_atomic_decrement_uint64(ptr, amount) \ os_atomic_decrement(ptr, amount) -# if defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) - -/** Do an atomic test-and-set. -@param[in,out] ptr Memory location to set to non-zero -@return the previous value */ -inline -lock_word_t -os_atomic_test_and_set(volatile lock_word_t* ptr) -{ - return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); -} - -/** Do an atomic clear. -@param[in,out] ptr Memory location to set to zero */ -inline -void -os_atomic_clear(volatile lock_word_t* ptr) -{ - __atomic_clear(ptr, __ATOMIC_RELEASE); -} - -# elif defined(IB_STRONG_MEMORY_MODEL) +# if defined(IB_STRONG_MEMORY_MODEL) /** Do an atomic test and set. @param[in,out] ptr Memory location to set to non-zero @@ -500,6 +529,27 @@ os_atomic_clear(volatile lock_word_t* ptr) return(__sync_lock_test_and_set(ptr, 0)); } +# elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) + +/** Do an atomic test-and-set. +@param[in,out] ptr Memory location to set to non-zero +@return the previous value */ +inline +lock_word_t +os_atomic_test_and_set(volatile lock_word_t* ptr) +{ + return(__atomic_test_and_set(ptr, __ATOMIC_ACQUIRE)); +} + +/** Do an atomic clear. +@param[in,out] ptr Memory location to set to zero */ +inline +void +os_atomic_clear(volatile lock_word_t* ptr) +{ + __atomic_clear(ptr, __ATOMIC_RELEASE); +} + # else # error "Unsupported platform" diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 400c3b546ccec..480d1a2ac2a0b 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -380,8 +380,6 @@ extern ulong srv_innodb_stats_method; #ifdef UNIV_LOG_ARCHIVE extern ibool srv_log_archive_on; -extern ibool srv_archive_recovery; -extern ib_uint64_t srv_archive_recovery_limit_lsn; #endif /* UNIV_LOG_ARCHIVE */ extern char* srv_file_flush_method_str; @@ -832,19 +830,29 @@ ulint srv_get_activity_count(void); /*========================*/ /*******************************************************************//** -Check if there has been any activity. +Check if there has been any activity. Considers background change buffer +merge as regular server activity unless a non-default +old_ibuf_merge_activity_count value is passed, in which case the merge will be +treated as keeping server idle. @return FALSE if no change in activity counter. */ UNIV_INTERN ibool srv_check_activity( /*===============*/ - ulint old_activity_count); /*!< old activity count */ + ulint old_activity_count, /*!< old activity count */ + /*!< old change buffer merge + activity count, or + ULINT_UNDEFINED */ + ulint old_ibuf_merge_activity_count = ULINT_UNDEFINED); /******************************************************************//** Increment the server activity counter. */ UNIV_INTERN void -srv_inc_activity_count(void); -/*=========================*/ +srv_inc_activity_count( +/*===================*/ + bool ibuf_merge_activity = false); /*!< whether this activity bump + is caused by the background + change buffer merge */ /**********************************************************************//** Enqueues a task to server task queue and releases a worker thread, if there diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h index 84ac40bab78a2..93f184b614762 100644 --- a/storage/xtradb/include/sync0rw.h +++ b/storage/xtradb/include/sync0rw.h @@ -737,8 +737,8 @@ struct rw_lock_t { /*!< Thread id of writer thread. Is only guaranteed to have sane and non-stale value iff recursive flag is set. */ - os_event_t event; /*!< Used by sync0arr.cc for thread queueing */ - os_event_t wait_ex_event; + struct os_event event; /*!< Used by sync0arr.cc for thread queueing */ + struct os_event wait_ex_event; /*!< Event for next-writer to wait on. A thread must decrement lock_word before waiting. */ #ifndef INNODB_RW_LOCKS_USE_ATOMICS @@ -788,12 +788,12 @@ struct prio_rw_lock_t { volatile ulint high_priority_s_waiters; /* Number of high priority S waiters */ - os_event_t high_priority_s_event; /* High priority wait + struct os_event high_priority_s_event; /* High priority wait array event for S waiters */ volatile ulint high_priority_x_waiters; /* Number of high priority X waiters */ - os_event_t high_priority_x_event; + struct os_event high_priority_x_event; /* High priority wait arraay event for X waiters */ volatile ulint high_priority_wait_ex_waiter; diff --git a/storage/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic index 8aadc406132d2..d7898befe8ced 100644 --- a/storage/xtradb/include/sync0rw.ic +++ b/storage/xtradb/include/sync0rw.ic @@ -585,7 +585,7 @@ rw_lock_s_unlock_func( /* wait_ex waiter exists. It may not be asleep, but we signal anyway. We do not wake other waiters, because they can't exist without wait_ex waiter and wait_ex waiter goes first.*/ - os_event_set(lock->wait_ex_event); + os_event_set(&lock->wait_ex_event); sync_array_object_signalled(); } @@ -625,7 +625,7 @@ rw_lock_s_unlock_func( /* A waiting next-writer exists, either high priority or regular, sharing the same wait event. */ - os_event_set(lock->base_lock.wait_ex_event); + os_event_set(&lock->base_lock.wait_ex_event); sync_array_object_signalled(); } else if (lock_word == X_LOCK_DECR) { @@ -636,7 +636,7 @@ rw_lock_s_unlock_func( if (lock->base_lock.waiters) { rw_lock_reset_waiter_flag(&lock->base_lock); - os_event_set(lock->base_lock.event); + os_event_set(&lock->base_lock.event); sync_array_object_signalled(); } } @@ -718,7 +718,7 @@ rw_lock_x_unlock_func( if (lock->waiters) { rw_lock_reset_waiter_flag(lock); - os_event_set(lock->event); + os_event_set(&lock->event); sync_array_object_signalled(); } } @@ -761,16 +761,16 @@ rw_lock_x_unlock_func( if (lock->high_priority_x_waiters) { - os_event_set(lock->high_priority_x_event); + os_event_set(&lock->high_priority_x_event); sync_array_object_signalled(); } else if (lock->high_priority_s_waiters) { - os_event_set(lock->high_priority_s_event); + os_event_set(&lock->high_priority_s_event); sync_array_object_signalled(); } else if (lock->base_lock.waiters) { rw_lock_reset_waiter_flag(&lock->base_lock); - os_event_set(lock->base_lock.event); + os_event_set(&lock->base_lock.event); sync_array_object_signalled(); } } diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h index 33bf1305e383d..93f37e6208bd6 100644 --- a/storage/xtradb/include/sync0sync.h +++ b/storage/xtradb/include/sync0sync.h @@ -922,7 +922,7 @@ implementation of a mutual exclusion semaphore. */ /** InnoDB mutex */ struct ib_mutex_t { - os_event_t event; /*!< Used by sync0arr.cc for the wait queue */ + struct os_event event; /*!< Used by sync0arr.cc for the wait queue */ volatile lock_word_t lock_word; /*!< lock_word is the target of the atomic test-and-set instruction when atomic operations are enabled. */ @@ -969,14 +969,13 @@ struct ib_mutex_t { struct ib_prio_mutex_t { ib_mutex_t base_mutex; /* The regular mutex provides the lock word etc. for the priority mutex */ - os_event_t high_priority_event; /* High priority wait array + struct os_event high_priority_event; /* High priority wait array event */ volatile ulint high_priority_waiters; /* Number of threads that asked for this mutex to be acquired with high priority in the global wait array waiting for this mutex to be released. */ - UT_LIST_NODE_T(ib_prio_mutex_t) list; }; /** Constant determining how long spin wait is continued before suspending diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic index d6561a76cdb65..5227bd8696469 100644 --- a/storage/xtradb/include/sync0sync.ic +++ b/storage/xtradb/include/sync0sync.ic @@ -225,7 +225,7 @@ mutex_exit_func( /* Wake up any high priority waiters first. */ if (mutex->high_priority_waiters != 0) { - os_event_set(mutex->high_priority_event); + os_event_set(&mutex->high_priority_event); sync_array_object_signalled(); } else if (mutex_get_waiters(&mutex->base_mutex) != 0) { diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 6db589355e2b2..592265c15bd54 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -47,7 +47,7 @@ Created 1/20/1994 Heikki Tuuri #define INNODB_VERSION_BUGFIX MYSQL_VERSION_PATCH #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 76.2 +#define PERCONA_INNODB_VERSION 76.3 #endif /* Enable UNIV_LOG_ARCHIVE in XtraDB */ diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index c523b09afc60a..38b9257f5ea50 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -641,6 +641,17 @@ lock_sys_close(void) mutex_free(&lock_sys->mutex); mutex_free(&lock_sys->wait_mutex); + os_event_free(lock_sys->timeout_event); + + for (srv_slot_t* slot = lock_sys->waiting_threads; + slot < lock_sys->waiting_threads + OS_THREAD_MAX_N; slot++) { + + ut_ad(!slot->in_use); + ut_ad(!slot->thr); + if (slot->event != NULL) + os_event_free(slot->event); + } + mem_free(lock_stack); mem_free(lock_sys); diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc index 5a23a083ab31c..4c5a8b3707669 100644 --- a/storage/xtradb/log/log0log.cc +++ b/storage/xtradb/log/log0log.cc @@ -1050,8 +1050,7 @@ log_group_init( ulint space_id, /*!< in: space id of the file space which contains the log files of this group */ - ulint archive_space_id __attribute__((unused))) - /*!< in: space id of the file space + ulint archive_space_id) /*!< in: space id of the file space which contains some archived log files for this group; currently, only for the first log group this is @@ -3128,10 +3127,9 @@ log_archive_close_groups( Writes the log contents to the archive up to the lsn when this function was called, and stops the archiving. When archiving is started again, the archived log file numbers start from 2 higher, so that the archiving will not write -again to the archived log files which exist when this function returns. -@return DB_SUCCESS or DB_ERROR */ -UNIV_INTERN -ulint +again to the archived log files which exist when this function returns. */ +static +void log_archive_stop(void) /*==================*/ { @@ -3139,13 +3137,7 @@ log_archive_stop(void) mutex_enter(&(log_sys->mutex)); - if (log_sys->archiving_state != LOG_ARCH_ON) { - - mutex_exit(&(log_sys->mutex)); - - return(DB_ERROR); - } - + ut_ad(log_sys->archiving_state == LOG_ARCH_ON); log_sys->archiving_state = LOG_ARCH_STOPPING; mutex_exit(&(log_sys->mutex)); @@ -3187,8 +3179,6 @@ log_archive_stop(void) log_sys->archiving_state = LOG_ARCH_STOPPED; mutex_exit(&(log_sys->mutex)); - - return(DB_SUCCESS); } /****************************************************************//** @@ -3930,6 +3920,7 @@ log_shutdown(void) rw_lock_free(&log_sys->checkpoint_lock); mutex_free(&log_sys->mutex); + mutex_free(&log_sys->log_flush_order_mutex); #ifdef UNIV_LOG_ARCHIVE rw_lock_free(&log_sys->archive_lock); diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc index a6ecd57ef694f..0d6140f137eae 100644 --- a/storage/xtradb/log/log0online.cc +++ b/storage/xtradb/log/log0online.cc @@ -298,7 +298,7 @@ log_online_read_bitmap_page( /* The following call prints an error message */ os_file_get_last_error(TRUE); ib_logf(IB_LOG_LEVEL_WARN, - "failed reading changed page bitmap file \'%s\'\n", + "failed reading changed page bitmap file \'%s\'", bitmap_file->name); return FALSE; } @@ -358,7 +358,7 @@ log_online_read_last_tracked_lsn(void) ib_logf(IB_LOG_LEVEL_WARN, "corruption detected in \'%s\' at offset " - UINT64PF "\n", + UINT64PF, log_bmp_sys->out.name, read_offset); } }; @@ -372,7 +372,7 @@ log_online_read_last_tracked_lsn(void) log_bmp_sys->out.offset)) { ib_logf(IB_LOG_LEVEL_WARN, "failed truncating changed page bitmap file \'%s\' to " - UINT64PF " bytes\n", + UINT64PF " bytes", log_bmp_sys->out.name, log_bmp_sys->out.offset); result = 0; } @@ -390,16 +390,8 @@ log_set_tracked_lsn( /*================*/ lsn_t tracked_lsn) /*!tracked_lsn, 0); - (void) os_atomic_increment_uint64(&log_sys->tracked_lsn, - tracked_lsn - old_value); -#else - mutex_enter(&log_sys->mutex); log_sys->tracked_lsn = tracked_lsn; - mutex_exit(&log_sys->mutex); -#endif + os_wmb; } /*********************************************************************//** @@ -424,7 +416,7 @@ log_online_can_track_missing( ib_logf(IB_LOG_LEVEL_ERROR, "last tracked LSN " LSN_PF " is ahead of tracking " "start LSN " LSN_PF ". This can be caused by " - "mismatched bitmap files.\n", + "mismatched bitmap files.", last_tracked_lsn, tracking_start_lsn); exit(1); } @@ -452,7 +444,7 @@ log_online_track_missing_on_startup( ib_logf(IB_LOG_LEVEL_WARN, "last tracked LSN in \'%s\' is " LSN_PF ", but the last checkpoint LSN is " LSN_PF ". This might be " - "due to a server crash or a very fast shutdown. ", + "due to a server crash or a very fast shutdown.", log_bmp_sys->out.name, last_tracked_lsn, tracking_start_lsn); /* See if we can fully recover the missing interval */ @@ -460,7 +452,7 @@ log_online_track_missing_on_startup( tracking_start_lsn)) { ib_logf(IB_LOG_LEVEL_INFO, - "reading the log to advance the last tracked LSN.\n"); + "reading the log to advance the last tracked LSN."); log_bmp_sys->start_lsn = ut_max(last_tracked_lsn, MIN_TRACKED_LSN); @@ -471,22 +463,22 @@ log_online_track_missing_on_startup( ut_ad(log_bmp_sys->end_lsn >= tracking_start_lsn); ib_logf(IB_LOG_LEVEL_INFO, - "continuing tracking changed pages from LSN " LSN_PF - "\n", log_bmp_sys->end_lsn); + "continuing tracking changed pages from LSN " LSN_PF, + log_bmp_sys->end_lsn); } else { ib_logf(IB_LOG_LEVEL_WARN, "the age of last tracked LSN exceeds log capacity, " "tracking-based incremental backups will work only " - "from the higher LSN!\n"); + "from the higher LSN!"); log_bmp_sys->end_lsn = log_bmp_sys->start_lsn = tracking_start_lsn; log_set_tracked_lsn(log_bmp_sys->start_lsn); ib_logf(IB_LOG_LEVEL_INFO, - "starting tracking changed pages from LSN " LSN_PF - "\n", log_bmp_sys->end_lsn); + "starting tracking changed pages from LSN " LSN_PF, + log_bmp_sys->end_lsn); } } @@ -554,7 +546,7 @@ log_online_start_bitmap_file(void) /* The following call prints an error message */ os_file_get_last_error(TRUE); ib_logf(IB_LOG_LEVEL_ERROR, - "cannot create \'%s\'\n", log_bmp_sys->out.name); + "cannot create \'%s\'", log_bmp_sys->out.name); return FALSE; } @@ -690,7 +682,7 @@ log_online_read_init(void) if (os_file_closedir(bitmap_dir)) { os_file_get_last_error(TRUE); - ib_logf(IB_LOG_LEVEL_ERROR, "cannot close \'%s\'\n", + ib_logf(IB_LOG_LEVEL_ERROR, "cannot close \'%s\'", log_bmp_sys->bmp_file_home); exit(1); } @@ -730,7 +722,7 @@ log_online_read_init(void) ib_logf(IB_LOG_LEVEL_WARN, "truncated block detected in \'%s\' at offset " - UINT64PF "\n", + UINT64PF, log_bmp_sys->out.name, log_bmp_sys->out.offset); log_bmp_sys->out.offset -= @@ -768,14 +760,14 @@ log_online_read_init(void) "last tracked LSN is " LSN_PF ", but the last " "checkpoint LSN is " LSN_PF ". The " "tracking-based incremental backups will work " - "only from the latter LSN!\n", + "only from the latter LSN!", last_tracked_lsn, tracking_start_lsn); } } ib_logf(IB_LOG_LEVEL_INFO, "starting tracking changed pages from LSN " - LSN_PF "\n", tracking_start_lsn); + LSN_PF, tracking_start_lsn); log_bmp_sys->start_lsn = tracking_start_lsn; log_set_tracked_lsn(tracking_start_lsn); } @@ -919,7 +911,7 @@ log_online_is_valid_log_seg( ib_logf(IB_LOG_LEVEL_ERROR, "log block checksum mismatch: expected " ULINTPF ", " - "calculated checksum " ULINTPF "\n", + "calculated checksum " ULINTPF, log_block_get_checksum(log_block), log_block_calc_checksum(log_block)); } @@ -1118,7 +1110,7 @@ log_online_write_bitmap_page( /* The following call prints an error message */ os_file_get_last_error(TRUE); ib_logf(IB_LOG_LEVEL_ERROR, "failed writing changed page " - "bitmap file \'%s\'\n", log_bmp_sys->out.name); + "bitmap file \'%s\'", log_bmp_sys->out.name); return FALSE; } @@ -1128,7 +1120,7 @@ log_online_write_bitmap_page( /* The following call prints an error message */ os_file_get_last_error(TRUE); ib_logf(IB_LOG_LEVEL_ERROR, "failed flushing changed page " - "bitmap file \'%s\'\n", log_bmp_sys->out.name); + "bitmap file \'%s\'", log_bmp_sys->out.name); return FALSE; } @@ -1275,8 +1267,7 @@ log_online_diagnose_inconsistent_dir( ib_logf(IB_LOG_LEVEL_WARN, "InnoDB: Warning: inconsistent bitmap file " "directory for a " - "INFORMATION_SCHEMA.INNODB_CHANGED_PAGES query" - "\n"); + "INFORMATION_SCHEMA.INNODB_CHANGED_PAGES query"); free(bitmap_files->files); } @@ -1318,7 +1309,7 @@ log_online_setup_bitmap_file_range( if (UNIV_UNLIKELY(!bitmap_dir)) { ib_logf(IB_LOG_LEVEL_ERROR, - "failed to open bitmap directory \'%s\'\n", + "failed to open bitmap directory \'%s\'", srv_data_home); return FALSE; } @@ -1368,7 +1359,7 @@ log_online_setup_bitmap_file_range( if (UNIV_UNLIKELY(os_file_closedir(bitmap_dir))) { os_file_get_last_error(TRUE); - ib_logf(IB_LOG_LEVEL_ERROR, "cannot close \'%s\'\n", + ib_logf(IB_LOG_LEVEL_ERROR, "cannot close \'%s\'", srv_data_home); return FALSE; } @@ -1389,7 +1380,7 @@ log_online_setup_bitmap_file_range( if (UNIV_UNLIKELY(!bitmap_dir)) { ib_logf(IB_LOG_LEVEL_ERROR, - "failed to open bitmap directory \'%s\'\n", + "failed to open bitmap directory \'%s\'", srv_data_home); return FALSE; } @@ -1440,7 +1431,7 @@ log_online_setup_bitmap_file_range( if (UNIV_UNLIKELY(os_file_closedir(bitmap_dir))) { os_file_get_last_error(TRUE); - ib_logf(IB_LOG_LEVEL_ERROR, "cannot close \'%s\'\n", + ib_logf(IB_LOG_LEVEL_ERROR, "cannot close \'%s\'", srv_data_home); free(bitmap_files->files); return FALSE; @@ -1515,7 +1506,7 @@ log_online_open_bitmap_file_read_only( /* Here and below assume that bitmap file names do not contain apostrophes, thus no need for ut_print_filename(). */ ib_logf(IB_LOG_LEVEL_WARN, - "error opening the changed page bitmap \'%s\'\n", + "error opening the changed page bitmap \'%s\'", bitmap_file->name); return FALSE; } @@ -1561,7 +1552,7 @@ log_online_diagnose_bitmap_eof( ib_logf(IB_LOG_LEVEL_WARN, "junk at the end of changed page bitmap file " - "\'%s\'.\n", bitmap_file->name); + "\'%s\'.", bitmap_file->name); } if (UNIV_UNLIKELY(!last_page_in_run)) { @@ -1572,7 +1563,7 @@ log_online_diagnose_bitmap_eof( for the whole server */ ib_logf(IB_LOG_LEVEL_WARN, "changed page bitmap file \'%s\' does not " - "contain a complete run at the end.\n", + "contain a complete run at the end.", bitmap_file->name); return FALSE; } @@ -1765,7 +1756,7 @@ log_online_bitmap_iterator_next( os_file_get_last_error(TRUE); ib_logf(IB_LOG_LEVEL_WARN, "failed reading changed page bitmap file " - "\'%s\'\n", i->in_files.files[i->in_i].name); + "\'%s\'", i->in_files.files[i->in_i].name); i->failed = TRUE; return FALSE; } diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index cc0bb515988e6..a99527f53ca03 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -77,10 +77,6 @@ UNIV_INTERN recv_sys_t* recv_sys = NULL; otherwise. Note that this is FALSE while a background thread is rolling back incomplete transactions. */ UNIV_INTERN ibool recv_recovery_on; -#ifdef UNIV_LOG_ARCHIVE -/** TRUE when applying redo log records from an archived log file */ -UNIV_INTERN ibool recv_recovery_from_backup_on; -#endif /* UNIV_LOG_ARCHIVE */ #ifndef UNIV_HOTBACKUP /** TRUE when recv_init_crash_recovery() has been called. */ @@ -293,10 +289,6 @@ recv_sys_var_init(void) recv_recovery_on = FALSE; -#ifdef UNIV_LOG_ARCHIVE - recv_recovery_from_backup_on = FALSE; -#endif /* UNIV_LOG_ARCHIVE */ - recv_needed_recovery = FALSE; recv_lsn_checks_on = FALSE; @@ -3748,327 +3740,6 @@ recv_reset_log_files_for_backup( } #endif /* UNIV_HOTBACKUP */ -#ifdef UNIV_LOG_ARCHIVE -/******************************************************//** -Reads from the archive of a log group and performs recovery. -@return TRUE if no more complete consistent archive files */ -static -ibool -log_group_recover_from_archive_file( -/*================================*/ - log_group_t* group) /*!< in: log group */ -{ - os_file_t file_handle; - ib_uint64_t start_lsn; - ib_uint64_t file_end_lsn; - ib_uint64_t dummy_lsn; - ib_uint64_t scanned_lsn; - ulint len; - ibool ret; - byte* buf; - os_offset_t read_offset; - os_offset_t file_size; - int input_char; - char name[OS_FILE_MAX_PATH]; - - ut_a(0); - -try_open_again: - buf = log_sys->buf; - - /* Add the file to the archive file space; open the file */ - - log_archived_file_name_gen(name, sizeof(name), - group->id, group->archived_file_no); - - file_handle = os_file_create(innodb_file_log_key, - name, OS_FILE_OPEN, - OS_FILE_LOG, OS_FILE_AIO, &ret); - - if (ret == FALSE) { -ask_again: - fprintf(stderr, - "InnoDB: Do you want to copy additional" - " archived log files\n" - "InnoDB: to the directory\n"); - fprintf(stderr, - "InnoDB: or were these all the files needed" - " in recovery?\n"); - fprintf(stderr, - "InnoDB: (Y == copy more files; N == this is all)?"); - - input_char = getchar(); - - if (input_char == (int) 'N') { - - return(TRUE); - } else if (input_char == (int) 'Y') { - - goto try_open_again; - } else { - goto ask_again; - } - } - - file_size = os_file_get_size(file_handle); - ut_a(file_size != (os_offset_t) -1); - - fprintf(stderr, "InnoDB: Opened archived log file %s\n", name); - - ret = os_file_close(file_handle); - - if (file_size < LOG_FILE_HDR_SIZE) { - fprintf(stderr, - "InnoDB: Archive file header incomplete %s\n", name); - - return(TRUE); - } - - ut_a(ret); - - /* Add the archive file as a node to the space */ - - ut_a(fil_node_create(name, 1 + file_size / UNIV_PAGE_SIZE, - group->archive_space_id, FALSE)); - ut_a(RECV_SCAN_SIZE >= LOG_FILE_HDR_SIZE); - - /* Read the archive file header */ - fil_io(OS_FILE_READ | OS_FILE_LOG, true, group->archive_space_id, 0, - 0, 0, - LOG_FILE_HDR_SIZE, buf, NULL); - - /* Check if the archive file header is consistent */ - - if (mach_read_from_4(buf + LOG_GROUP_ID) != group->id - || mach_read_from_8(buf + LOG_FILE_START_LSN) - != group->archived_file_no) { - fprintf(stderr, - "InnoDB: Archive file header inconsistent %s\n", name); - - return(TRUE); - } - - if (!mach_read_from_4(buf + LOG_FILE_ARCH_COMPLETED)) { - fprintf(stderr, - "InnoDB: Archive file not completely written %s\n", - name); - - return(TRUE); - } - - start_lsn = mach_read_from_8(buf + LOG_FILE_START_LSN); - file_end_lsn = mach_read_from_8(buf + LOG_FILE_END_LSN); - - if (!recv_sys->scanned_lsn) { - - if (recv_sys->parse_start_lsn < start_lsn) { - fprintf(stderr, - "InnoDB: Archive log file %s" - " starts from too big a lsn\n", - name); - return(TRUE); - } - - recv_sys->scanned_lsn = start_lsn; - } - - if (recv_sys->scanned_lsn != start_lsn) { - - fprintf(stderr, - "InnoDB: Archive log file %s starts from" - " a wrong lsn\n", - name); - return(TRUE); - } - - read_offset = LOG_FILE_HDR_SIZE; - - for (;;) { - len = RECV_SCAN_SIZE; - - if (read_offset + len > file_size) { - len = ut_calc_align_down(file_size - read_offset, - OS_FILE_LOG_BLOCK_SIZE); - } - - if (len == 0) { - - break; - } - -#ifdef UNIV_DEBUG - if (log_debug_writes) { - fprintf(stderr, - "InnoDB: Archive read starting at" - " lsn " LSN_PF ", len %lu from file %s\n", - start_lsn, - (ulong) len, name); - } -#endif /* UNIV_DEBUG */ - - fil_io(OS_FILE_READ | OS_FILE_LOG, true, - group->archive_space_id, 0, - read_offset / UNIV_PAGE_SIZE, - read_offset % UNIV_PAGE_SIZE, len, buf, NULL); - - ret = recv_scan_log_recs( - (buf_pool_get_n_pages() - - (recv_n_pool_free_frames * srv_buf_pool_instances)) - * UNIV_PAGE_SIZE, TRUE, buf, len, start_lsn, - &dummy_lsn, &scanned_lsn); - - if (scanned_lsn == file_end_lsn) { - - return(FALSE); - } - - if (ret) { - fprintf(stderr, - "InnoDB: Archive log file %s" - " does not scan right\n", - name); - return(TRUE); - } - - read_offset += len; - start_lsn += len; - - ut_ad(start_lsn == scanned_lsn); - } - - return(FALSE); -} - -/********************************************************//** -Recovers from archived log files, and also from log files, if they exist. -@return error code or DB_SUCCESS */ -UNIV_INTERN -dberr_t -recv_recovery_from_archive_start( -/*=============================*/ - ib_uint64_t min_flushed_lsn,/*!< in: min flushed lsn field from the - data files */ - ib_uint64_t limit_lsn, /*!< in: recover up to this lsn if - possible */ - lsn_t first_log_no) /*!< in: number of the first archived - log file to use in the recovery; the - file will be searched from - INNOBASE_LOG_ARCH_DIR specified in - server config file */ -{ - log_group_t* group; - ulint group_id; - ulint trunc_len; - ibool ret; - dberr_t err; - - ut_a(0); - - recv_sys_create(); - recv_sys_init(buf_pool_get_curr_size()); - - recv_recovery_on = TRUE; - recv_recovery_from_backup_on = TRUE; - - recv_sys->limit_lsn = limit_lsn; - - group_id = 0; - - group = UT_LIST_GET_FIRST(log_sys->log_groups); - - while (group) { - if (group->id == group_id) { - - break; - } - - group = UT_LIST_GET_NEXT(log_groups, group); - } - - if (!group) { - fprintf(stderr, - "InnoDB: There is no log group defined with id %lu!\n", - (ulong) group_id); - return(DB_ERROR); - } - - group->archived_file_no = first_log_no; - - recv_sys->parse_start_lsn = min_flushed_lsn; - - recv_sys->scanned_lsn = 0; - recv_sys->scanned_checkpoint_no = 0; - recv_sys->recovered_lsn = recv_sys->parse_start_lsn; - - recv_sys->archive_group = group; - - ret = FALSE; - - mutex_enter(&(log_sys->mutex)); - - while (!ret) { - ret = log_group_recover_from_archive_file(group); - - /* Close and truncate a possible processed archive file - from the file space */ - - trunc_len = UNIV_PAGE_SIZE - * fil_space_get_size(group->archive_space_id); - if (trunc_len > 0) { - fil_space_truncate_start(group->archive_space_id, - trunc_len); - } - - group->archived_file_no += group->file_size - LOG_FILE_HDR_SIZE; - } - - if (recv_sys->recovered_lsn < limit_lsn) { - - if (!recv_sys->scanned_lsn) { - - recv_sys->scanned_lsn = recv_sys->parse_start_lsn; - } - - mutex_exit(&(log_sys->mutex)); - - err = recv_recovery_from_checkpoint_start(LOG_ARCHIVE, - limit_lsn, - LSN_MAX, - LSN_MAX); - if (err != DB_SUCCESS) { - - return(err); - } - - mutex_enter(&(log_sys->mutex)); - } - - if (limit_lsn != LSN_MAX) { - - recv_apply_hashed_log_recs(FALSE); - - recv_reset_logs(0, FALSE, recv_sys->recovered_lsn); - } - - mutex_exit(&(log_sys->mutex)); - - return(DB_SUCCESS); -} - -/********************************************************//** -Completes recovery from archive. */ -UNIV_INTERN -void -recv_recovery_from_archive_finish(void) -/*===================================*/ -{ - recv_recovery_from_checkpoint_finish(); - - recv_recovery_from_backup_on = FALSE; -} -#endif /* UNIV_LOG_ARCHIVE */ - - void recv_dblwr_t::add(byte* page) { pages.push_back(page); diff --git a/storage/xtradb/mem/mem0pool.cc b/storage/xtradb/mem/mem0pool.cc index fe9a84d21fa16..42d0417c76882 100644 --- a/storage/xtradb/mem/mem0pool.cc +++ b/storage/xtradb/mem/mem0pool.cc @@ -280,6 +280,7 @@ mem_pool_free( /*==========*/ mem_pool_t* pool) /*!< in, own: memory pool */ { + mutex_free(&pool->mutex); ut_free(pool->buf); ut_free(pool); } diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index a28555821b7c6..0d94534d13921 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -377,6 +377,42 @@ os_get_os_version(void) } #endif /* __WIN__ */ +/***********************************************************************//** +For an EINVAL I/O error, prints a diagnostic message if innodb_flush_method +== ALL_O_DIRECT. +@return true if the diagnostic message was printed +@return false if the diagnostic message does not apply */ +static +bool +os_diagnose_all_o_direct_einval( +/*============================*/ + ulint err) /*!< in: C error code */ +{ + if ((err == EINVAL) + && (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT)) { + ib_logf(IB_LOG_LEVEL_INFO, + "The error might be caused by redo log I/O not " + "satisfying innodb_flush_method=ALL_O_DIRECT " + "requirements by the underlying file system."); + if (srv_log_block_size != 512) + ib_logf(IB_LOG_LEVEL_INFO, + "This might be caused by an incompatible " + "non-default innodb_log_block_size value %lu.", + srv_log_block_size); + ib_logf(IB_LOG_LEVEL_INFO, + "Please file a bug at https://bugs.percona.com and " + "include this error message, my.cnf settings, and " + "information about the file system where the redo log " + "resides."); + ib_logf(IB_LOG_LEVEL_INFO, + "A possible workaround is to change " + "innodb_flush_method value to something else " + "than ALL_O_DIRECT."); + return(true); + } + return(false); +} + /***********************************************************************//** Retrieves the last error number if an error occurs in a file io function. The number should be retrieved before any other OS calls (because they may @@ -512,7 +548,7 @@ os_file_get_last_error_low( "InnoDB: The error means mysqld does not have" " the access rights to\n" "InnoDB: the directory.\n"); - } else { + } else if (!os_diagnose_all_o_direct_einval(err)) { if (strerror(err) != NULL) { fprintf(stderr, "InnoDB: Error number %d" @@ -750,7 +786,7 @@ os_file_lock( #ifndef UNIV_HOTBACKUP /****************************************************************//** Creates the seek mutexes used in positioned reads and writes. */ -UNIV_INTERN +static void os_io_init_simple(void) /*===================*/ @@ -1585,7 +1621,7 @@ os_file_set_atomic_writes( #else ib_logf(IB_LOG_LEVEL_ERROR, "trying to enable atomic writes on non-supported platform! " - "Please restart with innodb_use_atomic_writes disabled.\n"); + "Please restart with innodb_use_atomic_writes disabled."); return(FALSE); #endif } @@ -2204,7 +2240,7 @@ os_file_set_size( ib_logf(IB_LOG_LEVEL_ERROR, "preallocating file " "space for file \'%s\' failed. Current size " - INT64PF ", desired size " INT64PF "\n", + INT64PF ", desired size " INT64PF, name, current_size, size); os_file_handle_error_no_exit (name, "posix_fallocate", FALSE); @@ -2672,6 +2708,9 @@ os_file_pwrite( /* Handle partial writes and signal interruptions correctly */ for (ret = 0; ret < (ssize_t) n; ) { n_written = pwrite(file, buf, (ssize_t)n - ret, offs); + DBUG_EXECUTE_IF("xb_simulate_all_o_direct_write_failure", + n_written = -1; + errno = EINVAL;); if (n_written >= 0) { ret += n_written; offs += n_written; @@ -2844,6 +2883,10 @@ os_file_read_func( try_again: ret = os_file_pread(file, buf, n, offset, trx); + DBUG_EXECUTE_IF("xb_simulate_all_o_direct_read_failure", + ret = -1; + errno = EINVAL;); + if ((ulint) ret == n) { return(TRUE); } else if (ret == -1) { @@ -3220,6 +3263,8 @@ os_file_write_func( "InnoDB: " REFMAN "operating-system-error-codes.html\n"); + os_diagnose_all_o_direct_einval(errno); + os_has_said_disk_full = TRUE; } @@ -4196,6 +4241,14 @@ os_aio_free(void) os_event_free(os_aio_segment_wait_events[i]); } +#if !defined(HAVE_ATOMIC_BUILTINS) || UNIV_WORD_SIZE < 8 + os_mutex_free(os_file_count_mutex); +#endif /* !HAVE_ATOMIC_BUILTINS || UNIV_WORD_SIZE < 8 */ + + for (ulint i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) { + os_mutex_free(os_file_seek_mutexes[i]); + } + ut_free(os_aio_segment_wait_events); os_aio_segment_wait_events = 0; os_aio_n_segments = 0; @@ -5900,7 +5953,7 @@ os_aio_print( srv_io_thread_function[i]); #ifndef __WIN__ - if (os_aio_segment_wait_events[i]->is_set) { + if (os_aio_segment_wait_events[i]->is_set()) { fprintf(file, " ev set"); } #endif /* __WIN__ */ diff --git a/storage/xtradb/os/os0sync.cc b/storage/xtradb/os/os0sync.cc index cd57abd0623da..9a92112d37ef3 100644 --- a/storage/xtradb/os/os0sync.cc +++ b/storage/xtradb/os/os0sync.cc @@ -47,27 +47,14 @@ struct os_mutex_t{ do not assume that the OS mutex supports recursive locking, though NT seems to do that */ - UT_LIST_NODE_T(os_mutex_t) os_mutex_list; - /* list of all 'slow' OS mutexes created */ }; -/** Mutex protecting counts and the lists of OS mutexes and events */ -UNIV_INTERN os_ib_mutex_t os_sync_mutex; -/** TRUE if os_sync_mutex has been initialized */ -static ibool os_sync_mutex_inited = FALSE; -/** TRUE when os_sync_free() is being executed */ -static ibool os_sync_free_called = FALSE; +// All the os_*_count variables are accessed atomically /** This is incremented by 1 in os_thread_create and decremented by 1 in -os_thread_exit */ +os_thread_exit. */ UNIV_INTERN ulint os_thread_count = 0; -/** The list of all events created */ -static UT_LIST_BASE_NODE_T(os_event) os_event_list; - -/** The list of all OS 'slow' mutexes */ -static UT_LIST_BASE_NODE_T(os_mutex_t) os_mutex_list; - UNIV_INTERN ulint os_event_count = 0; UNIV_INTERN ulint os_mutex_count = 0; UNIV_INTERN ulint os_fast_mutex_count = 0; @@ -80,11 +67,6 @@ UNIV_INTERN mysql_pfs_key_t event_os_mutex_key; UNIV_INTERN mysql_pfs_key_t os_mutex_key; #endif -/* Because a mutex is embedded inside an event and there is an -event embedded inside a mutex, on free, this generates a recursive call. -This version of the free event function doesn't acquire the global lock */ -static void os_event_free_internal(os_event_t event); - /* On Windows (Vista and later), load function pointers for condition variable handling. Those functions are not available in prior versions, so we have to use them via runtime loading, as long as we support XP. */ @@ -289,74 +271,21 @@ void os_sync_init(void) /*==============*/ { - UT_LIST_INIT(os_event_list); - UT_LIST_INIT(os_mutex_list); - - os_sync_mutex = NULL; - os_sync_mutex_inited = FALSE; - /* Now for Windows only */ os_cond_module_init(); - - os_sync_mutex = os_mutex_create(); - - os_sync_mutex_inited = TRUE; } -/*********************************************************//** -Frees created events and OS 'slow' mutexes. */ +/** Create an event semaphore, i.e., a semaphore which may just have two +states: signaled and nonsignaled. The created event is manual reset: it must be +reset explicitly by calling sync_os_reset_event. +@param[in,out] event memory block where to create the event */ UNIV_INTERN void -os_sync_free(void) -/*==============*/ -{ - os_event_t event; - os_ib_mutex_t mutex; - - os_sync_free_called = TRUE; - event = UT_LIST_GET_FIRST(os_event_list); - - while (event) { - - os_event_free(event); - - event = UT_LIST_GET_FIRST(os_event_list); - } - - mutex = UT_LIST_GET_FIRST(os_mutex_list); - - while (mutex) { - if (mutex == os_sync_mutex) { - /* Set the flag to FALSE so that we do not try to - reserve os_sync_mutex any more in remaining freeing - operations in shutdown */ - os_sync_mutex_inited = FALSE; - } - - os_mutex_free(mutex); - - mutex = UT_LIST_GET_FIRST(os_mutex_list); - } - os_sync_free_called = FALSE; -} - -/*********************************************************//** -Creates an event semaphore, i.e., a semaphore which may just have two -states: signaled and nonsignaled. The created event is manual reset: it -must be reset explicitly by calling sync_os_reset_event. -@return the event handle */ -UNIV_INTERN -os_event_t -os_event_create(void) -/*==================*/ +os_event_create(os_event_t event) { - os_event_t event; - #ifdef __WIN__ if(!srv_use_native_conditions) { - event = static_cast(ut_malloc(sizeof(*event))); - event->handle = CreateEvent(NULL, TRUE, FALSE, NULL); if (!event->handle) { fprintf(stderr, @@ -367,8 +296,6 @@ os_event_create(void) } else /* Windows with condition variables */ #endif { - event = static_cast(ut_malloc(sizeof *event)); - #ifndef PFS_SKIP_EVENT_MUTEX os_fast_mutex_init(event_os_mutex_key, &event->os_mutex); #else @@ -377,32 +304,25 @@ os_event_create(void) os_cond_init(&(event->cond_var)); - event->is_set = FALSE; - - /* We return this value in os_event_reset(), which can then be - be used to pass to the os_event_wait_low(). The value of zero - is reserved in os_event_wait_low() for the case when the - caller does not want to pass any signal_count value. To - distinguish between the two cases we initialize signal_count - to 1 here. */ - event->signal_count = 1; + event->init_count_and_set(); } - /* The os_sync_mutex can be NULL because during startup an event - can be created [ because it's embedded in the mutex/rwlock ] before - this module has been initialized */ - if (os_sync_mutex != NULL) { - os_mutex_enter(os_sync_mutex); - } - - /* Put to the list of events */ - UT_LIST_ADD_FIRST(os_event_list, os_event_list, event); + os_atomic_increment_ulint(&os_event_count, 1); +} - os_event_count++; +/*********************************************************//** +Creates an event semaphore, i.e., a semaphore which may just have two +states: signaled and nonsignaled. The created event is manual reset: it +must be reset explicitly by calling sync_os_reset_event. +@return the event handle */ +UNIV_INTERN +os_event_t +os_event_create(void) +/*==================*/ +{ + os_event_t event = static_cast(ut_malloc(sizeof(*event)));; - if (os_sync_mutex != NULL) { - os_mutex_exit(os_sync_mutex); - } + os_event_create(event); return(event); } @@ -427,11 +347,11 @@ os_event_set( os_fast_mutex_lock(&(event->os_mutex)); - if (event->is_set) { + if (UNIV_UNLIKELY(event->is_set())) { /* Do nothing */ } else { - event->is_set = TRUE; - event->signal_count += 1; + event->set(); + event->inc_signal_count(); os_cond_broadcast(&(event->cond_var)); } @@ -465,55 +385,26 @@ os_event_reset( os_fast_mutex_lock(&(event->os_mutex)); - if (!event->is_set) { + if (UNIV_UNLIKELY(!event->is_set())) { /* Do nothing */ } else { - event->is_set = FALSE; + event->reset(); } - ret = event->signal_count; + ret = event->signal_count(); os_fast_mutex_unlock(&(event->os_mutex)); return(ret); } -/**********************************************************//** -Frees an event object, without acquiring the global lock. */ -static -void -os_event_free_internal( -/*===================*/ - os_event_t event) /*!< in: event to free */ -{ -#ifdef __WIN__ - if(!srv_use_native_conditions) { - ut_a(event); - ut_a(CloseHandle(event->handle)); - } else -#endif - { - ut_a(event); - - /* This is to avoid freeing the mutex twice */ - os_fast_mutex_free(&(event->os_mutex)); - - os_cond_destroy(&(event->cond_var)); - } - - /* Remove from the list of events */ - UT_LIST_REMOVE(os_event_list, os_event_list, event); - - os_event_count--; - - ut_free(event); -} - /**********************************************************//** Frees an event object. */ UNIV_INTERN void os_event_free( /*==========*/ - os_event_t event) /*!< in: event to free */ + os_event_t event, /*!< in: event to free */ + bool free_memory)/*!< in: if true, deallocate the event + memory block too */ { ut_a(event); @@ -528,16 +419,10 @@ os_event_free( os_cond_destroy(&(event->cond_var)); } - /* Remove from the list of events */ - os_mutex_enter(os_sync_mutex); + os_atomic_decrement_ulint(&os_event_count, 1); - UT_LIST_REMOVE(os_event_list, os_event_list, event); - - os_event_count--; - - os_mutex_exit(os_sync_mutex); - - ut_free(event); + if (free_memory) + ut_free(event); } /**********************************************************//** @@ -585,10 +470,10 @@ os_event_wait_low( os_fast_mutex_lock(&event->os_mutex); if (!reset_sig_count) { - reset_sig_count = event->signal_count; + reset_sig_count = event->signal_count(); } - while (!event->is_set && event->signal_count == reset_sig_count) { + while (!event->is_set() && event->signal_count() == reset_sig_count) { os_cond_wait(&(event->cond_var), &(event->os_mutex)); /* Solaris manual said that spurious wakeups may occur: we @@ -686,11 +571,12 @@ os_event_wait_time_low( os_fast_mutex_lock(&event->os_mutex); if (!reset_sig_count) { - reset_sig_count = event->signal_count; + reset_sig_count = event->signal_count(); } do { - if (event->is_set || event->signal_count != reset_sig_count) { + if (event->is_set() + || event->signal_count() != reset_sig_count) { break; } @@ -734,18 +620,7 @@ os_mutex_create(void) mutex_str->count = 0; mutex_str->event = os_event_create(); - if (UNIV_LIKELY(os_sync_mutex_inited)) { - /* When creating os_sync_mutex itself we cannot reserve it */ - os_mutex_enter(os_sync_mutex); - } - - UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str); - - os_mutex_count++; - - if (UNIV_LIKELY(os_sync_mutex_inited)) { - os_mutex_exit(os_sync_mutex); - } + os_atomic_increment_ulint(&os_mutex_count, 1); return(mutex_str); } @@ -791,21 +666,9 @@ os_mutex_free( { ut_a(mutex); - if (UNIV_LIKELY(!os_sync_free_called)) { - os_event_free_internal(mutex->event); - } - - if (UNIV_LIKELY(os_sync_mutex_inited)) { - os_mutex_enter(os_sync_mutex); - } - - UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex); + os_event_free(mutex->event); - os_mutex_count--; - - if (UNIV_LIKELY(os_sync_mutex_inited)) { - os_mutex_exit(os_sync_mutex); - } + os_atomic_decrement_ulint(&os_mutex_count, 1); os_fast_mutex_free(static_cast(mutex->handle)); ut_free(mutex->handle); @@ -827,18 +690,7 @@ os_fast_mutex_init_func( #else ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST)); #endif - if (UNIV_LIKELY(os_sync_mutex_inited)) { - /* When creating os_sync_mutex itself (in Unix) we cannot - reserve it */ - - os_mutex_enter(os_sync_mutex); - } - - os_fast_mutex_count++; - - if (UNIV_LIKELY(os_sync_mutex_inited)) { - os_mutex_exit(os_sync_mutex); - } + os_atomic_increment_ulint(&os_fast_mutex_count, 1); } /**********************************************************//** @@ -900,17 +752,6 @@ os_fast_mutex_free_func( putc('\n', stderr); } #endif - if (UNIV_LIKELY(os_sync_mutex_inited)) { - /* When freeing the last mutexes, we have - already freed os_sync_mutex */ - - os_mutex_enter(os_sync_mutex); - } - ut_ad(os_fast_mutex_count > 0); - os_fast_mutex_count--; - - if (UNIV_LIKELY(os_sync_mutex_inited)) { - os_mutex_exit(os_sync_mutex); - } + os_atomic_decrement_ulint(&os_fast_mutex_count, 1); } diff --git a/storage/xtradb/os/os0thread.cc b/storage/xtradb/os/os0thread.cc index a862022693c97..1d417f9823c47 100644 --- a/storage/xtradb/os/os0thread.cc +++ b/storage/xtradb/os/os0thread.cc @@ -145,9 +145,7 @@ os_thread_create_func( os_thread_t thread; DWORD win_thread_id; - os_mutex_enter(os_sync_mutex); - os_thread_count++; - os_mutex_exit(os_sync_mutex); + os_atomic_increment_ulint(&os_thread_count, 1); thread = CreateThread(NULL, /* no security attributes */ 0, /* default size stack */ @@ -186,9 +184,8 @@ os_thread_create_func( exit(1); } #endif - os_mutex_enter(os_sync_mutex); - os_thread_count++; - os_mutex_exit(os_sync_mutex); + ulint new_count = os_atomic_increment_ulint(&os_thread_count, 1); + ut_a(new_count <= OS_THREAD_MAX_N); #ifdef UNIV_HPUX10 ret = pthread_create(&pthread, pthread_attr_default, func, arg); @@ -205,8 +202,6 @@ os_thread_create_func( pthread_attr_destroy(&attr); #endif - ut_a(os_thread_count <= OS_THREAD_MAX_N); - if (thread_id) { *thread_id = pthread; } @@ -233,9 +228,7 @@ os_thread_exit( pfs_delete_thread(); #endif - os_mutex_enter(os_sync_mutex); - os_thread_count--; - os_mutex_exit(os_sync_mutex); + os_atomic_decrement_ulint(&os_thread_count, 1); #ifdef __WIN__ ExitThread((DWORD) exit_value); diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index ecf7e5bb116b0..48c165bbc540c 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1992,7 +1992,8 @@ row_merge_read_clustered_index( if (max_doc_id && err == DB_SUCCESS) { /* Sync fts cache for other fts indexes to keep all fts indexes consistent in sync_doc_id. */ - err = fts_sync_table(const_cast(new_table)); + err = fts_sync_table(const_cast(new_table), + false, true); if (err == DB_SUCCESS) { fts_update_next_doc_id( diff --git a/storage/xtradb/srv/srv0conc.cc b/storage/xtradb/srv/srv0conc.cc index 6c15753246a58..63268e3a26617 100644 --- a/storage/xtradb/srv/srv0conc.cc +++ b/storage/xtradb/srv/srv0conc.cc @@ -158,6 +158,10 @@ srv_conc_free(void) { #ifndef HAVE_ATOMIC_BUILTINS os_fast_mutex_free(&srv_conc_mutex); + + for (ulint i = 0; i < OS_THREAD_MAX_N; i++) + os_event_free(srv_conc_slots[i].event); + mem_free(srv_conc_slots); srv_conc_slots = NULL; #endif /* !HAVE_ATOMIC_BUILTINS */ diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index 2b086a2fb1f81..14d272ac4c0e8 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -319,8 +319,6 @@ UNIV_INTERN ulong srv_read_ahead_threshold = 56; #ifdef UNIV_LOG_ARCHIVE UNIV_INTERN ibool srv_log_archive_on = FALSE; -UNIV_INTERN ibool srv_archive_recovery = 0; -UNIV_INTERN ib_uint64_t srv_archive_recovery_limit_lsn; #endif /* UNIV_LOG_ARCHIVE */ /* This parameter is used to throttle the number of insert buffers that are @@ -711,6 +709,10 @@ struct srv_sys_t{ srv_stats_t::ulint_ctr_1_t activity_count; /*!< For tracking server activity */ + srv_stats_t::ulint_ctr_1_t + ibuf_merge_activity_count;/*!< For tracking change + buffer merge activity, a subset + of overall server activity */ }; #ifndef HAVE_ATOMIC_BUILTINS @@ -1101,8 +1103,9 @@ srv_init(void) srv_checkpoint_completed_event = os_event_create(); + srv_redo_log_tracked_event = os_event_create(); + if (srv_track_changed_pages) { - srv_redo_log_tracked_event = os_event_create(); os_event_set(srv_redo_log_tracked_event); } @@ -1144,17 +1147,30 @@ srv_free(void) { srv_conc_free(); - /* The mutexes srv_sys->mutex and srv_sys->tasks_mutex should have - been freed by sync_close() already. */ - mem_free(srv_sys); - srv_sys = NULL; + if (!srv_read_only_mode) { - trx_i_s_cache_free(trx_i_s_cache); + for (ulint i = 0; i < srv_sys->n_sys_threads; i++) + os_event_free(srv_sys->sys_threads[i].event); - if (!srv_read_only_mode) { + os_event_free(srv_error_event); + os_event_free(srv_monitor_event); os_event_free(srv_buf_dump_event); - srv_buf_dump_event = NULL; + os_event_free(srv_checkpoint_completed_event); + os_event_free(srv_redo_log_tracked_event); + mutex_free(&srv_sys->mutex); + mutex_free(&srv_sys->tasks_mutex); } + +#ifndef HAVE_ATOMIC_BUILTINS + mutex_free(&server_mutex); +#endif + mutex_free(&srv_innodb_monitor_mutex); + mutex_free(&page_zip_stat_per_index_mutex); + + mem_free(srv_sys); + srv_sys = NULL; + + trx_i_s_cache_free(trx_i_s_cache); } /*********************************************************************//** @@ -2195,10 +2211,15 @@ DECLARE_THREAD(srv_error_monitor_thread)( Increment the server activity count. */ UNIV_INTERN void -srv_inc_activity_count(void) -/*========================*/ +srv_inc_activity_count( +/*===================*/ + bool ibuf_merge_activity) /*!< whether this activity bump + is caused by the background + change buffer merge */ { srv_sys->activity_count.inc(); + if (ibuf_merge_activity) + srv_sys->ibuf_merge_activity_count.inc(); } /**********************************************************************//** @@ -2314,7 +2335,7 @@ DECLARE_THREAD(srv_redo_log_follow_thread)( /* TODO: sync with I_S log tracking status? */ ib_logf(IB_LOG_LEVEL_ERROR, "log tracking bitmap write failed, " - "stopping log tracking thread!\n"); + "stopping log tracking thread!"); break; } os_event_set(srv_redo_log_tracked_event); @@ -2356,7 +2377,7 @@ purge_archived_logs( if (!dir) { ib_logf(IB_LOG_LEVEL_WARN, "opening archived log directory %s failed. " - "Purge archived logs are not available\n", + "Purge archived logs are not available", srv_arch_dir); /* failed to open directory */ return(DB_ERROR); @@ -2444,7 +2465,7 @@ purge_archived_logs( archived_log_filename)) { ib_logf(IB_LOG_LEVEL_WARN, - "can't delete archived log file %s.\n", + "can't delete archived log file %s.", archived_log_filename); mutex_exit(&log_sys->mutex); @@ -2552,16 +2573,49 @@ srv_get_activity_count(void) return(srv_sys->activity_count); } +/** Get current server ibuf merge activity count. +@return ibuf merge activity count */ +static +ulint +srv_get_ibuf_merge_activity_count(void) +{ + return(srv_sys->ibuf_merge_activity_count); +} + /*******************************************************************//** -Check if there has been any activity. +Check if there has been any activity. Considers background change buffer +merge as regular server activity unless a non-default +old_ibuf_merge_activity_count value is passed, in which case the merge will be +treated as keeping server idle. @return FALSE if no change in activity counter. */ UNIV_INTERN ibool srv_check_activity( /*===============*/ - ulint old_activity_count) /*!< in: old activity count */ + ulint old_activity_count, /*!< in: old activity count */ + /*!< old change buffer merge + activity count, or + ULINT_UNDEFINED */ + ulint old_ibuf_merge_activity_count) { - return(srv_sys->activity_count != old_activity_count); + ulint new_activity_count = srv_sys->activity_count; + if (old_ibuf_merge_activity_count == ULINT_UNDEFINED) + return(new_activity_count != old_activity_count); + + /* If we care about ibuf merge activity, then the server is considered + idle if all activity, if any, was due to ibuf merge. */ + ulint new_ibuf_merge_activity_count + = srv_sys->ibuf_merge_activity_count; + + ut_ad(new_ibuf_merge_activity_count <= new_activity_count); + ut_ad(new_ibuf_merge_activity_count >= old_ibuf_merge_activity_count); + ut_ad(new_activity_count >= old_activity_count); + + ulint ibuf_merge_activity_delta = + new_ibuf_merge_activity_count - old_ibuf_merge_activity_count; + ulint activity_delta = new_activity_count - old_activity_count; + + return (activity_delta > ibuf_merge_activity_delta); } /********************************************************************//** @@ -2919,6 +2973,8 @@ DECLARE_THREAD(srv_master_thread)( { srv_slot_t* slot; ulint old_activity_count = srv_get_activity_count(); + ulint old_ibuf_merge_activity_count + = srv_get_ibuf_merge_activity_count(); ib_time_t last_print_time; ut_ad(!srv_read_only_mode); @@ -2956,8 +3012,12 @@ DECLARE_THREAD(srv_master_thread)( srv_current_thread_priority = srv_master_thread_priority; - if (srv_check_activity(old_activity_count)) { + if (srv_check_activity(old_activity_count, + old_ibuf_merge_activity_count)) { + old_activity_count = srv_get_activity_count(); + old_ibuf_merge_activity_count + = srv_get_ibuf_merge_activity_count(); srv_master_do_active_tasks(); } else { srv_master_do_idle_tasks(); diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index f4d404e43a51f..20a5e5e80f629 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -2409,40 +2409,6 @@ innobase_start_or_create_for_mysql(void) create_log_files_rename(logfilename, dirnamelen, max_flushed_lsn, logfile0); -#ifdef UNIV_LOG_ARCHIVE - } else if (srv_archive_recovery) { - - ib_logf(IB_LOG_LEVEL_INFO, - " Starting archive recovery from a backup..."); - - err = recv_recovery_from_archive_start( - min_flushed_lsn, srv_archive_recovery_limit_lsn, - min_arch_log_no); - if (err != DB_SUCCESS) { - - return(DB_ERROR); - } - /* Since ibuf init is in dict_boot, and ibuf is needed - in any disk i/o, first call dict_boot */ - - err = dict_boot(); - - if (err != DB_SUCCESS) { - return(err); - } - - ib_bh = trx_sys_init_at_db_start(); - n_recovered_trx = UT_LIST_GET_LEN(trx_sys->rw_trx_list); - - /* The purge system needs to create the purge view and - therefore requires that the trx_sys is inited. */ - - trx_purge_sys_create(srv_n_purge_threads, ib_bh); - - srv_startup_is_before_trx_rollback_phase = FALSE; - - recv_recovery_from_archive_finish(); -#endif /* UNIV_LOG_ARCHIVE */ } else { /* Check if we support the max format that is stamped @@ -3058,8 +3024,7 @@ innobase_shutdown_for_mysql(void) logs_empty_and_mark_files_at_shutdown() and should have already quit or is quitting right now. */ - os_mutex_enter(os_sync_mutex); - + os_rmb; if (os_thread_count == 0) { /* All the threads have exited or are just exiting; NOTE that the threads may not have completed their @@ -3069,15 +3034,11 @@ innobase_shutdown_for_mysql(void) os_thread_exit(). Now we just sleep 0.1 seconds and hope that is enough! */ - os_mutex_exit(os_sync_mutex); - os_thread_sleep(100000); break; } - os_mutex_exit(os_sync_mutex); - os_thread_sleep(100000); } @@ -3138,26 +3099,23 @@ innobase_shutdown_for_mysql(void) que_close(); row_mysql_close(); srv_mon_free(); - sync_close(); srv_free(); fil_close(); - /* 4. Free the os_conc_mutex and all os_events and os_mutexes */ - - os_sync_free(); - - /* 5. Free all allocated memory */ + /* 4. Free all allocated memory */ pars_lexer_close(); log_mem_free(); buf_pool_free(srv_buf_pool_instances); mem_close(); + sync_close(); /* ut_free_all_mem() frees all allocated memory not freed yet in shutdown, and it will also free the ut_list_mutex, so it should be the last one for all operation */ ut_free_all_mem(); + os_rmb; if (os_thread_count != 0 || os_event_count != 0 || os_mutex_count != 0 diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc index 0b01b0836b0a2..c2eb4543fb230 100644 --- a/storage/xtradb/sync/sync0arr.cc +++ b/storage/xtradb/sync/sync0arr.cc @@ -295,21 +295,21 @@ sync_cell_get_event( ulint type = cell->request_type; if (type == SYNC_MUTEX) { - return(((ib_mutex_t*) cell->wait_object)->event); + return(&((ib_mutex_t*) cell->wait_object)->event); } else if (type == SYNC_PRIO_MUTEX) { - return(((ib_prio_mutex_t*) cell->wait_object) + return(&((ib_prio_mutex_t*) cell->wait_object) ->high_priority_event); } else if (type == RW_LOCK_WAIT_EX) { - return(((rw_lock_t*) cell->wait_object)->wait_ex_event); + return(&((rw_lock_t*) cell->wait_object)->wait_ex_event); } else if (type == PRIO_RW_LOCK_SHARED) { - return(((prio_rw_lock_t *) cell->wait_object) + return(&((prio_rw_lock_t *) cell->wait_object) ->high_priority_s_event); } else if (type == PRIO_RW_LOCK_EX) { - return(((prio_rw_lock_t *) cell->wait_object) + return(&((prio_rw_lock_t *) cell->wait_object) ->high_priority_x_event); } else { /* RW_LOCK_SHARED and RW_LOCK_EX wait on the same event */ ut_ad(type == RW_LOCK_SHARED || type == RW_LOCK_EX); - return(((rw_lock_t*) cell->wait_object)->event); + return(&((rw_lock_t*) cell->wait_object)->event); } } diff --git a/storage/xtradb/sync/sync0rw.cc b/storage/xtradb/sync/sync0rw.cc index a72730e187758..7e964fd510fd6 100644 --- a/storage/xtradb/sync/sync0rw.cc +++ b/storage/xtradb/sync/sync0rw.cc @@ -264,8 +264,8 @@ rw_lock_create_func( lock->last_x_file_name = "not yet reserved"; lock->last_s_line = 0; lock->last_x_line = 0; - lock->event = os_event_create(); - lock->wait_ex_event = os_event_create(); + os_event_create(&lock->event); + os_event_create(&lock->wait_ex_event); mutex_enter(&rw_lock_list_mutex); @@ -306,9 +306,9 @@ rw_lock_create_func( #endif cmutex_name); lock->high_priority_s_waiters = 0; - lock->high_priority_s_event = os_event_create(); + os_event_create(&lock->high_priority_s_event); lock->high_priority_x_waiters = 0; - lock->high_priority_x_event = os_event_create(); + os_event_create(&lock->high_priority_x_event); lock->high_priority_wait_ex_waiter = 0; } @@ -336,9 +336,9 @@ rw_lock_free_func( mutex = rw_lock_get_mutex(lock); #endif /* !INNODB_RW_LOCKS_USE_ATOMICS */ - os_event_free(lock->event); + os_event_free(&lock->event, false); - os_event_free(lock->wait_ex_event); + os_event_free(&lock->wait_ex_event, false); ut_ad(UT_LIST_GET_PREV(list, lock) == NULL || UT_LIST_GET_PREV(list, lock)->magic_n == RW_LOCK_MAGIC_N); @@ -368,8 +368,8 @@ rw_lock_free_func( /*==============*/ prio_rw_lock_t* lock) /*!< in: rw-lock */ { - os_event_free(lock->high_priority_s_event); - os_event_free(lock->high_priority_x_event); + os_event_free(&lock->high_priority_s_event, false); + os_event_free(&lock->high_priority_x_event, false); rw_lock_free_func(&lock->base_lock); } diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc index 7fc992bf97274..fe50e17f106be 100644 --- a/storage/xtradb/sync/sync0sync.cc +++ b/storage/xtradb/sync/sync0sync.cc @@ -209,10 +209,7 @@ UNIV_INTERN mysql_pfs_key_t sync_thread_mutex_key; /** Global list of database mutexes (not OS mutexes) created. */ UNIV_INTERN ut_list_base_node_t mutex_list; -/** Global list of priority mutexes. A subset of mutex_list */ -UNIV_INTERN UT_LIST_BASE_NODE_T(ib_prio_mutex_t) prio_mutex_list; - -/** Mutex protecting the mutex_list and prio_mutex_list variables */ +/** Mutex protecting the mutex_list variable */ UNIV_INTERN ib_mutex_t mutex_list_mutex; #ifdef UNIV_PFS_MUTEX @@ -283,7 +280,7 @@ mutex_create_func( os_fast_mutex_init(PFS_NOT_INSTRUMENTED, &mutex->os_fast_mutex); mutex->lock_word = 0; #endif - mutex->event = os_event_create(); + os_event_create(&mutex->event); mutex_set_waiters(mutex, 0); #ifdef UNIV_DEBUG mutex->magic_n = MUTEX_MAGIC_N; @@ -355,11 +352,7 @@ mutex_create_func( #endif /* UNIV_DEBUG */ cmutex_name); mutex->high_priority_waiters = 0; - mutex->high_priority_event = os_event_create(); - - mutex_enter(&mutex_list_mutex); - UT_LIST_ADD_FIRST(list, prio_mutex_list, mutex); - mutex_exit(&mutex_list_mutex); + os_event_create(&mutex->high_priority_event); } /******************************************************************//** @@ -406,7 +399,7 @@ mutex_free_func( mutex_exit(&mutex_list_mutex); } - os_event_free(mutex->event); + os_event_free(&mutex->event, false); #ifdef UNIV_MEM_DEBUG func_exit: #endif /* UNIV_MEM_DEBUG */ @@ -433,12 +426,8 @@ mutex_free_func( /*============*/ ib_prio_mutex_t* mutex) /*!< in: mutex */ { - mutex_enter(&mutex_list_mutex); - UT_LIST_REMOVE(list, prio_mutex_list, mutex); - mutex_exit(&mutex_list_mutex); - ut_a(mutex->high_priority_waiters == 0); - os_event_free(mutex->high_priority_event); + os_event_free(&mutex->high_priority_event, false); mutex_free_func(&mutex->base_mutex); } @@ -703,7 +692,7 @@ mutex_signal_object( /* The memory order of resetting the waiters field and signaling the object is important. See LEMMA 1 above. */ - os_event_set(mutex->event); + os_event_set(&mutex->event); sync_array_object_signalled(); } @@ -1584,7 +1573,6 @@ sync_init(void) /* Init the mutex list and create the mutex to protect it. */ UT_LIST_INIT(mutex_list); - UT_LIST_INIT(prio_mutex_list); mutex_create(mutex_list_mutex_key, &mutex_list_mutex, SYNC_NO_ORDER_CHECK); #ifdef UNIV_SYNC_DEBUG @@ -1636,22 +1624,21 @@ sync_thread_level_arrays_free(void) #endif /* UNIV_SYNC_DEBUG */ /******************************************************************//** -Frees the resources in InnoDB's own synchronization data structures. Use -os_sync_free() after calling this. */ +Frees the resources in InnoDB's own synchronization data structures. */ UNIV_INTERN void sync_close(void) /*===========*/ { ib_mutex_t* mutex; - ib_prio_mutex_t* prio_mutex; sync_array_close(); - for (prio_mutex = UT_LIST_GET_FIRST(prio_mutex_list); prio_mutex;) { - mutex_free(prio_mutex); - prio_mutex = UT_LIST_GET_FIRST(prio_mutex_list); - } +#ifdef UNIV_SYNC_DEBUG + os_event_free(rw_lock_debug_event); + mutex_free(&rw_lock_debug_mutex); +#endif + mutex_free(&rw_lock_list_mutex); for (mutex = UT_LIST_GET_FIRST(mutex_list); mutex != NULL; @@ -1669,7 +1656,6 @@ sync_close(void) mutex = UT_LIST_GET_FIRST(mutex_list); } - mutex_free(&mutex_list_mutex); #ifdef UNIV_SYNC_DEBUG mutex_free(&sync_thread_mutex); @@ -1679,6 +1665,8 @@ sync_close(void) sync_thread_level_arrays_free(); #endif /* UNIV_SYNC_DEBUG */ + mutex_free(&mutex_list_mutex); + sync_initialized = FALSE; } diff --git a/storage/xtradb/trx/trx0i_s.cc b/storage/xtradb/trx/trx0i_s.cc index 794ee432ca4e4..fe1a615693b3e 100644 --- a/storage/xtradb/trx/trx0i_s.cc +++ b/storage/xtradb/trx/trx0i_s.cc @@ -1466,6 +1466,8 @@ trx_i_s_cache_free( /*===============*/ trx_i_s_cache_t* cache) /*!< in, own: cache to free */ { + rw_lock_free(&cache->rw_lock); + mutex_free(&cache->last_read_mutex); hash_table_free(cache->locks_hash); ha_storage_free(cache->storage); table_cache_free(&cache->innodb_trx); From 720e04ff6760e9d04566d7fb33131fd1886ef4cd Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 21 Jun 2016 14:21:03 +0200 Subject: [PATCH 087/112] 5.6.31 --- storage/innobase/btr/btr0btr.cc | 20 +- storage/innobase/btr/btr0cur.cc | 16 +- storage/innobase/btr/btr0sea.cc | 4 +- storage/innobase/buf/buf0buddy.cc | 6 +- storage/innobase/buf/buf0buf.cc | 4 +- storage/innobase/buf/buf0dump.cc | 8 +- storage/innobase/buf/buf0flu.cc | 4 +- storage/innobase/buf/buf0lru.cc | 18 +- storage/innobase/data/data0data.cc | 7 +- storage/innobase/dict/dict0crea.cc | 12 +- storage/innobase/dict/dict0dict.cc | 14 +- storage/innobase/dict/dict0load.cc | 26 ++- storage/innobase/dict/dict0mem.cc | 4 +- storage/innobase/dict/dict0stats_bg.cc | 4 +- storage/innobase/fil/fil0fil.cc | 6 +- storage/innobase/fsp/fsp0fsp.cc | 39 ++-- storage/innobase/fts/fts0blex.cc | 26 +-- storage/innobase/fts/fts0fts.cc | 64 +++--- storage/innobase/fts/fts0opt.cc | 52 +++-- storage/innobase/fts/fts0que.cc | 28 +-- storage/innobase/fts/fts0tlex.cc | 26 +-- storage/innobase/fts/make_parser.sh | 28 +-- storage/innobase/handler/ha_innodb.cc | 79 ++++--- storage/innobase/handler/ha_innodb.h | 20 +- storage/innobase/handler/handler0alter.cc | 74 +++--- storage/innobase/ibuf/ibuf0ibuf.cc | 138 +++++------- storage/innobase/include/api0api.h | 4 +- storage/innobase/include/btr0btr.h | 84 +++---- storage/innobase/include/btr0btr.ic | 18 +- storage/innobase/include/btr0cur.h | 36 +-- storage/innobase/include/btr0pcur.h | 4 +- storage/innobase/include/btr0sea.h | 4 +- storage/innobase/include/btr0types.h | 18 +- storage/innobase/include/buf0buddy.h | 6 +- storage/innobase/include/buf0buddy.ic | 6 +- storage/innobase/include/buf0buf.h | 68 +++--- storage/innobase/include/buf0flu.h | 6 +- storage/innobase/include/buf0lru.h | 10 +- storage/innobase/include/data0data.h | 84 +++---- storage/innobase/include/data0data.ic | 8 +- storage/innobase/include/dict0boot.h | 8 +- storage/innobase/include/dict0crea.h | 8 +- storage/innobase/include/dict0crea.ic | 4 +- storage/innobase/include/dict0dict.h | 260 +++++++++++----------- storage/innobase/include/dict0dict.ic | 7 +- storage/innobase/include/dict0load.h | 4 +- storage/innobase/include/dict0mem.h | 16 +- storage/innobase/include/dict0stats.h | 10 +- storage/innobase/include/dict0stats_bg.h | 4 +- storage/innobase/include/dyn0dyn.h | 22 +- storage/innobase/include/dyn0dyn.ic | 4 +- storage/innobase/include/fil0fil.h | 20 +- storage/innobase/include/fsp0fsp.h | 18 +- storage/innobase/include/fts0ast.h | 10 +- storage/innobase/include/fts0fts.h | 46 ++-- storage/innobase/include/fts0priv.h | 88 ++++---- storage/innobase/include/fts0priv.ic | 8 +- storage/innobase/include/ha_prototypes.h | 22 +- storage/innobase/include/handler0alter.h | 10 +- storage/innobase/include/ibuf0ibuf.h | 44 ++-- storage/innobase/include/lock0lock.h | 36 +-- storage/innobase/include/lock0priv.h | 4 +- storage/innobase/include/log0recv.h | 4 +- storage/innobase/include/mach0data.h | 38 ++-- storage/innobase/include/mem0mem.h | 4 +- storage/innobase/include/mem0mem.ic | 6 +- storage/innobase/include/mtr0mtr.h | 10 +- storage/innobase/include/mtr0mtr.ic | 4 +- storage/innobase/include/os0file.h | 16 +- storage/innobase/include/os0thread.h | 4 +- storage/innobase/include/page0cur.h | 8 +- storage/innobase/include/page0page.h | 56 ++--- storage/innobase/include/page0types.h | 10 +- storage/innobase/include/page0zip.h | 50 ++--- storage/innobase/include/pars0pars.h | 6 +- storage/innobase/include/read0read.h | 4 +- storage/innobase/include/rem0cmp.h | 6 +- storage/innobase/include/rem0rec.h | 152 ++++++------- storage/innobase/include/rem0rec.ic | 5 +- storage/innobase/include/row0ftsort.h | 6 +- storage/innobase/include/row0import.h | 8 +- storage/innobase/include/row0ins.h | 14 +- storage/innobase/include/row0log.h | 32 +-- storage/innobase/include/row0merge.h | 38 ++-- storage/innobase/include/row0mysql.h | 44 ++-- storage/innobase/include/row0purge.h | 8 +- storage/innobase/include/row0quiesce.h | 8 +- storage/innobase/include/row0row.h | 30 +-- storage/innobase/include/row0sel.h | 6 +- storage/innobase/include/row0uins.h | 4 +- storage/innobase/include/row0umod.h | 4 +- storage/innobase/include/row0upd.h | 18 +- storage/innobase/include/row0vers.h | 6 +- storage/innobase/include/srv0srv.h | 6 +- storage/innobase/include/srv0start.h | 6 +- storage/innobase/include/sync0arr.h | 4 +- storage/innobase/include/sync0rw.h | 6 +- storage/innobase/include/sync0rw.ic | 4 +- storage/innobase/include/sync0sync.h | 10 +- storage/innobase/include/trx0rec.h | 14 +- storage/innobase/include/trx0roll.h | 16 +- storage/innobase/include/trx0sys.h | 6 +- storage/innobase/include/trx0trx.h | 24 +- storage/innobase/include/trx0undo.h | 14 +- storage/innobase/include/univ.i | 8 +- storage/innobase/include/ut0byte.h | 8 +- storage/innobase/include/ut0dbg.h | 4 +- storage/innobase/include/ut0mem.h | 4 +- storage/innobase/include/ut0rnd.h | 12 +- storage/innobase/include/ut0ut.h | 8 +- storage/innobase/lock/lock0lock.cc | 16 +- storage/innobase/lock/lock0wait.cc | 4 +- storage/innobase/log/log0log.cc | 6 +- storage/innobase/log/log0recv.cc | 6 +- storage/innobase/mem/mem0dbg.cc | 6 +- storage/innobase/mtr/mtr0mtr.cc | 8 +- storage/innobase/os/os0file.cc | 12 +- storage/innobase/page/page0page.cc | 4 +- storage/innobase/page/page0zip.cc | 11 +- storage/innobase/pars/lexyy.cc | 10 +- storage/innobase/pars/make_flex.sh | 12 +- storage/innobase/pars/pars0pars.cc | 8 +- storage/innobase/rem/rem0cmp.cc | 19 +- storage/innobase/rem/rem0rec.cc | 12 +- storage/innobase/row/row0ftsort.cc | 18 +- storage/innobase/row/row0import.cc | 24 +- storage/innobase/row/row0ins.cc | 30 +-- storage/innobase/row/row0log.cc | 34 +-- storage/innobase/row/row0merge.cc | 28 +-- storage/innobase/row/row0mysql.cc | 23 +- storage/innobase/row/row0purge.cc | 24 +- storage/innobase/row/row0quiesce.cc | 16 +- storage/innobase/row/row0row.cc | 18 +- storage/innobase/row/row0sel.cc | 20 +- storage/innobase/row/row0uins.cc | 10 +- storage/innobase/row/row0umod.cc | 27 +-- storage/innobase/row/row0undo.cc | 7 +- storage/innobase/row/row0upd.cc | 25 ++- storage/innobase/srv/srv0srv.cc | 16 +- storage/innobase/srv/srv0start.cc | 10 +- storage/innobase/sync/sync0sync.cc | 6 +- storage/innobase/trx/trx0purge.cc | 4 +- storage/innobase/trx/trx0rec.cc | 10 +- storage/innobase/trx/trx0roll.cc | 6 +- storage/innobase/trx/trx0trx.cc | 14 +- storage/innobase/trx/trx0undo.cc | 14 +- 146 files changed, 1536 insertions(+), 1481 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 99bb42466d016..2c5e9a175e27c 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -1102,7 +1102,7 @@ that the caller has made the reservation for free extents! @retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded (init_mtr == mtr, or the page was not previously freed in mtr) @retval block (not allocated or initialized) otherwise */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) buf_block_t* btr_page_alloc_low( /*===============*/ @@ -1971,7 +1971,7 @@ IBUF_BITMAP_FREE is unaffected by reorganization. @retval true if the operation was successful @retval false if it is a compressed page, and recompression failed */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) bool btr_page_reorganize_block( /*======================*/ @@ -2033,7 +2033,8 @@ btr_parse_page_reorganize( { ulint level; - ut_ad(ptr && end_ptr); + ut_ad(ptr != NULL); + ut_ad(end_ptr != NULL); /* If dealing with a compressed page the record has the compression level used during original compression written in @@ -2500,7 +2501,7 @@ btr_page_get_split_rec( Returns TRUE if the insert fits on the appropriate half-page with the chosen split_rec. @return true if fits */ -static __attribute__((nonnull(1,3,4,6), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1,3,4,6), warn_unused_result)) bool btr_page_insert_fits( /*=================*/ @@ -2643,7 +2644,7 @@ btr_insert_on_non_leaf_level_func( /**************************************************************//** Attaches the halves of an index page on the appropriate level in an index tree. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void btr_attach_half_pages( /*==================*/ @@ -2779,7 +2780,7 @@ btr_attach_half_pages( /*************************************************************//** Determine if a tuple is smaller than any record on the page. @return TRUE if smaller */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool btr_page_tuple_smaller( /*===================*/ @@ -3355,7 +3356,7 @@ Removes a page from the level list of pages. /*************************************************************//** Removes a page from the level list of pages. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void btr_level_list_remove_func( /*=======================*/ @@ -3371,7 +3372,8 @@ btr_level_list_remove_func( ulint prev_page_no; ulint next_page_no; - ut_ad(page && mtr); + ut_ad(page != NULL); + ut_ad(mtr != NULL); ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)); ut_ad(space == page_get_space_id(page)); /* Get the previous and next page numbers of page */ diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 1e4c31723db2a..1f43fc62b16c0 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2012, Facebook Inc. @@ -1084,7 +1084,7 @@ This has to be done either within the same mini-transaction, or by invoking ibuf_reset_free_bits() before mtr_commit(). @return pointer to inserted record if succeed, else NULL */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) rec_t* btr_cur_insert_if_possible( /*=======================*/ @@ -1127,7 +1127,7 @@ btr_cur_insert_if_possible( /*************************************************************//** For an insert, checks the locks and does the undo logging if desired. @return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */ -UNIV_INLINE __attribute__((warn_unused_result, nonnull(2,3,5,6))) +UNIV_INLINE MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,5,6))) dberr_t btr_cur_ins_lock_and_undo( /*======================*/ @@ -1653,7 +1653,7 @@ btr_cur_pessimistic_insert( /*************************************************************//** For an update, checks the locks and does the undo logging. @return DB_SUCCESS, DB_WAIT_LOCK, or error number */ -UNIV_INLINE __attribute__((warn_unused_result, nonnull(2,3,6,7))) +UNIV_INLINE MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,6,7))) dberr_t btr_cur_upd_lock_and_undo( /*======================*/ @@ -1672,7 +1672,7 @@ btr_cur_upd_lock_and_undo( const rec_t* rec; dberr_t err; - ut_ad(thr || (flags & BTR_NO_LOCKING_FLAG)); + ut_ad((thr != NULL) || (flags & BTR_NO_LOCKING_FLAG)); rec = btr_cur_get_rec(cursor); index = cursor->index; @@ -2961,7 +2961,7 @@ btr_cur_del_mark_set_clust_rec( ut_ad(page_is_leaf(page_align(rec))); #ifdef UNIV_DEBUG - if (btr_cur_print_record_ops && thr) { + if (btr_cur_print_record_ops && (thr != NULL)) { btr_cur_trx_report(thr_get_trx(thr)->id, index, "del mark "); rec_print_new(stderr, rec, offsets); } @@ -3109,7 +3109,7 @@ btr_cur_del_mark_set_sec_rec( rec = btr_cur_get_rec(cursor); #ifdef UNIV_DEBUG - if (btr_cur_print_record_ops && thr) { + if (btr_cur_print_record_ops && (thr != NULL)) { btr_cur_trx_report(thr_get_trx(thr)->id, cursor->index, "del mark "); rec_print(stderr, rec, cursor->index); @@ -4992,7 +4992,7 @@ btr_free_externally_stored_field( ulint i, /*!< in: field number of field_ref; ignored if rec == NULL */ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */ - mtr_t* local_mtr __attribute__((unused))) /*!< in: mtr + mtr_t* local_mtr MY_ATTRIBUTE((unused))) /*!< in: mtr containing the latch to data an an X-latch to the index tree */ { diff --git a/storage/innobase/btr/btr0sea.cc b/storage/innobase/btr/btr0sea.cc index df70f8a113039..dd28f50f4f675 100644 --- a/storage/innobase/btr/btr0sea.cc +++ b/storage/innobase/btr/btr0sea.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -473,7 +473,7 @@ btr_search_update_block_hash_info( /*==============================*/ btr_search_t* info, /*!< in: search info */ buf_block_t* block, /*!< in: buffer block */ - btr_cur_t* cursor __attribute__((unused))) + btr_cur_t* cursor MY_ATTRIBUTE((unused))) /*!< in: cursor */ { #ifdef UNIV_SYNC_DEBUG diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc index 958b3b5cfada3..f2ab73217e01a 100644 --- a/storage/innobase/buf/buf0buddy.cc +++ b/storage/innobase/buf/buf0buddy.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -112,7 +112,7 @@ buf_buddy_mem_invalid( /**********************************************************************//** Check if a buddy is stamped free. @return whether the buddy is free */ -UNIV_INLINE __attribute__((warn_unused_result)) +UNIV_INLINE MY_ATTRIBUTE((warn_unused_result)) bool buf_buddy_stamp_is_free( /*====================*/ @@ -225,7 +225,7 @@ Checks if a buf is free i.e.: in the zip_free[]. @retval BUF_BUDDY_STATE_FREE if fully free @retval BUF_BUDDY_STATE_USED if currently in use @retval BUF_BUDDY_STATE_PARTIALLY_USED if partially in use. */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) buf_buddy_state_t buf_buddy_is_free( /*==============*/ diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 85e44294e6081..6f206918212c9 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -3470,7 +3470,7 @@ buf_page_init_low( /********************************************************************//** Inits a page to the buffer buf_pool. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void buf_page_init( /*==========*/ diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index cb67381f0c882..ed27a70307d70 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -105,7 +105,7 @@ SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_DUMP_STATUS'; or by: SHOW STATUS LIKE 'innodb_buffer_pool_dump_status'; */ -static __attribute__((nonnull, format(printf, 2, 3))) +static MY_ATTRIBUTE((nonnull, format(printf, 2, 3))) void buf_dump_status( /*============*/ @@ -141,7 +141,7 @@ SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_LOAD_STATUS'; or by: SHOW STATUS LIKE 'innodb_buffer_pool_load_status'; */ -static __attribute__((nonnull, format(printf, 2, 3))) +static MY_ATTRIBUTE((nonnull, format(printf, 2, 3))) void buf_load_status( /*============*/ @@ -594,7 +594,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(buf_dump_thread)( /*============================*/ - void* arg __attribute__((unused))) /*!< in: a dummy parameter + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { ut_ad(!srv_read_only_mode); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 540d6383813d2..1cdd1610c4f9c 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -2384,7 +2384,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(buf_flush_page_cleaner_thread)( /*==========================================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index a1618020bca2c..13a91b7e4c4de 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -142,7 +142,7 @@ If a compressed page is freed other compressed pages may be relocated. caller needs to free the page to the free list @retval false if BUF_BLOCK_ZIP_PAGE was removed from page_hash. In this case the block is already returned to the buddy allocator. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool buf_LRU_block_remove_hashed( /*========================*/ @@ -366,7 +366,7 @@ want to hog the CPU and resources. Release the buffer pool and block mutex and try to force a context switch. Then reacquire the same mutexes. The current page is "fixed" before the release of the mutexes and then "unfixed" again once we have reacquired the mutexes. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void buf_flush_yield( /*============*/ @@ -407,7 +407,7 @@ If we have hogged the resources for too long then release the buffer pool and flush list mutex and do a thread yield. Set the current page to "sticky" so that it is not relocated during the yield. @return true if yielded */ -static __attribute__((nonnull(1), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1), warn_unused_result)) bool buf_flush_try_yield( /*================*/ @@ -450,7 +450,7 @@ buf_flush_try_yield( Removes a single page from a given tablespace inside a specific buffer pool instance. @return true if page was removed. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool buf_flush_or_remove_page( /*=====================*/ @@ -531,7 +531,7 @@ the list as they age towards the tail of the LRU. @retval DB_SUCCESS if all freed @retval DB_FAIL if not all freed @retval DB_INTERRUPTED if the transaction was interrupted */ -static __attribute__((nonnull(1), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1), warn_unused_result)) dberr_t buf_flush_or_remove_pages( /*======================*/ @@ -637,7 +637,7 @@ Remove or flush all the dirty pages that belong to a given tablespace inside a specific buffer pool instance. The pages will remain in the LRU list and will be evicted from the LRU list as they age and move towards the tail of the LRU list. */ -static __attribute__((nonnull(1))) +static MY_ATTRIBUTE((nonnull(1))) void buf_flush_dirty_pages( /*==================*/ @@ -677,7 +677,7 @@ buf_flush_dirty_pages( /******************************************************************//** Remove all pages that belong to a given tablespace inside a specific buffer pool instance when we are DISCARDing the tablespace. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void buf_LRU_remove_all_pages( /*=====================*/ @@ -825,7 +825,7 @@ buffer pool instance when we are deleting the data file(s) of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU only if buf_remove is BUF_REMOVE_FLUSH_NO_WRITE. */ -static __attribute__((nonnull(1))) +static MY_ATTRIBUTE((nonnull(1))) void buf_LRU_remove_pages( /*=================*/ diff --git a/storage/innobase/data/data0data.cc b/storage/innobase/data/data0data.cc index 179de79b69fe5..593af089b005a 100644 --- a/storage/innobase/data/data0data.cc +++ b/storage/innobase/data/data0data.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -67,7 +67,8 @@ dtuple_coll_cmp( ulint n_fields; ulint i; - ut_ad(tuple1 && tuple2); + ut_ad(tuple1 != NULL); + ut_ad(tuple2 != NULL); ut_ad(tuple1->magic_n == DATA_TUPLE_MAGIC_N); ut_ad(tuple2->magic_n == DATA_TUPLE_MAGIC_N); ut_ad(dtuple_check_typed(tuple1)); @@ -715,7 +716,7 @@ UNIV_INTERN void dtuple_convert_back_big_rec( /*========================*/ - dict_index_t* index __attribute__((unused)), /*!< in: index */ + dict_index_t* index MY_ATTRIBUTE((unused)), /*!< in: index */ dtuple_t* entry, /*!< in: entry whose data was put to vector */ big_rec_t* vector) /*!< in, own: big rec vector; it is freed in this function */ diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 30523ff2af4c7..b3edfefb9c499 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -246,7 +246,7 @@ dict_create_sys_columns_tuple( /***************************************************************//** Builds a table definition to insert. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t dict_build_table_def_step( /*======================*/ @@ -573,7 +573,7 @@ dict_create_search_tuple( /***************************************************************//** Builds an index definition row to insert. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t dict_build_index_def_step( /*======================*/ @@ -648,7 +648,7 @@ dict_build_field_def_step( /***************************************************************//** Creates an index tree for the index if it is not a member of a cluster. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t dict_create_index_tree_step( /*========================*/ @@ -1464,7 +1464,7 @@ dict_create_or_check_foreign_constraint_tables(void) /****************************************************************//** Evaluate the given foreign key SQL statement. @return error code or DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t dict_foreign_eval_sql( /*==================*/ @@ -1530,7 +1530,7 @@ dict_foreign_eval_sql( Add a single foreign key field definition to the data dictionary tables in the database. @return error code or DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t dict_create_add_foreign_field_to_dictionary( /*========================================*/ diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 67f08d57f36d2..ae4cb0b845add 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -5783,7 +5783,7 @@ dict_set_corrupted_index_cache_only( dict_index_t* index, /*!< in/out: index */ dict_table_t* table) /*!< in/out: table */ { - ut_ad(index); + ut_ad(index != NULL); ut_ad(mutex_own(&dict_sys->mutex)); ut_ad(!dict_table_is_comp(dict_sys->sys_tables)); ut_ad(!dict_table_is_comp(dict_sys->sys_indexes)); @@ -5793,8 +5793,9 @@ dict_set_corrupted_index_cache_only( if (dict_index_is_clust(index)) { dict_table_t* corrupt_table; - corrupt_table = table ? table : index->table; - ut_ad(!index->table || !table || index->table == table); + corrupt_table = (table != NULL) ? table : index->table; + ut_ad((index->table != NULL) || (table != NULL) + || index->table == table); if (corrupt_table) { corrupt_table->corrupted = TRUE; @@ -5874,11 +5875,6 @@ dict_table_get_index_on_name( { dict_index_t* index; - /* If name is NULL, just return */ - if (!name) { - return(NULL); - } - index = dict_table_get_first_index(table); while (index != NULL) { diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 69211990bfacd..9dc63ff202656 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1744,7 +1744,7 @@ dict_load_index_low( goto err_len; } type = mach_read_from_4(field); - if (type & (~0 << DICT_IT_BITS)) { + if (type & (~0U << DICT_IT_BITS)) { return("unknown SYS_INDEXES.TYPE bits"); } @@ -1783,7 +1783,7 @@ Loads definitions for table indexes. Adds them to the data dictionary cache. @return DB_SUCCESS if ok, DB_CORRUPTION if corruption of dictionary table or DB_UNSUPPORTED if table has unknown index type */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t dict_load_indexes( /*==============*/ @@ -2531,6 +2531,7 @@ dict_load_table( /* the table->fts could be created in dict_load_column when a user defined FTS_DOC_ID is present, but no FTS */ + fts_optimize_remove_table(table); fts_free(table); } else { fts_optimize_add_table(table); @@ -2596,14 +2597,13 @@ dict_load_table_on_id( btr_pcur_open_on_user_rec(sys_table_ids, tuple, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr); -check_rec: rec = btr_pcur_get_rec(&pcur); if (page_rec_is_user_rec(rec)) { /*---------------------------------------------------*/ /* Now we have the record in the secondary index containing the table ID and NAME */ - +check_rec: field = rec_get_nth_field_old( rec, DICT_FLD__SYS_TABLE_IDS__ID, &len); ut_ad(len == 8); @@ -2613,12 +2613,14 @@ dict_load_table_on_id( if (rec_get_deleted_flag(rec, 0)) { /* Until purge has completed, there may be delete-marked duplicate records - for the same SYS_TABLES.ID. - Due to Bug #60049, some delete-marked - records may survive the purge forever. */ - if (btr_pcur_move_to_next(&pcur, &mtr)) { - - goto check_rec; + for the same SYS_TABLES.ID, but different + SYS_TABLES.NAME. */ + while (btr_pcur_move_to_next(&pcur, &mtr)) { + rec = btr_pcur_get_rec(&pcur); + + if (page_rec_is_user_rec(rec)) { + goto check_rec; + } } } else { /* Now we get the table name from the record */ @@ -2787,7 +2789,7 @@ dict_load_foreign_cols( /***********************************************************************//** Loads a foreign key constraint to the dictionary cache. @return DB_SUCCESS or error code */ -static __attribute__((nonnull(1), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1), warn_unused_result)) dberr_t dict_load_foreign( /*==============*/ diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index 846ce302b08e3..b39e1e171ee8f 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -264,7 +264,7 @@ dict_mem_table_add_col( /**********************************************************************//** Renames a column of a table in the data dictionary cache. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void dict_mem_table_col_rename_low( /*==========================*/ diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 9e1f75a13a969..6f01c37977651 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -331,7 +331,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(dict_stats_thread)( /*==============================*/ - void* arg __attribute__((unused))) /*!< in: a dummy parameter + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { ut_a(!srv_read_only_mode); diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 77c1353843cee..5e1a9d6c05e83 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1875,7 +1875,7 @@ fil_set_max_space_id_if_bigger( Writes the flushed lsn and the latest archived log number to the page header of the first page of a data file of the system tablespace (space 0), which is uncompressed. */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) dberr_t fil_write_lsn_and_arch_no_to_file( /*==============================*/ @@ -1883,7 +1883,7 @@ fil_write_lsn_and_arch_no_to_file( ulint sum_of_sizes, /*!< in: combined size of previous files in space, in database pages */ lsn_t lsn, /*!< in: lsn to write */ - ulint arch_log_no __attribute__((unused))) + ulint arch_log_no MY_ATTRIBUTE((unused))) /*!< in: archived log number to write */ { byte* buf1; @@ -1970,7 +1970,7 @@ Checks the consistency of the first data page of a tablespace at database startup. @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) const char* fil_check_first_page( /*=================*/ diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 0f8d6bcc4f065..f09cbb03d004a 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -93,7 +93,7 @@ fseg_n_reserved_pages_low( /********************************************************************//** Marks a page used. The page must reside within the extents of the given segment. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void fseg_mark_page_used( /*================*/ @@ -132,7 +132,7 @@ fsp_fill_free_list( ulint space, /*!< in: space */ fsp_header_t* header, /*!< in/out: space header */ mtr_t* mtr) /*!< in/out: mini-transaction */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Allocates a single free page from a segment. This function implements the intelligent allocation strategy which tries to minimize file space @@ -161,7 +161,7 @@ fseg_alloc_free_page_low( in which the page should be initialized. If init_mtr!=mtr, but the page is already latched in mtr, do not initialize the page. */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -425,7 +425,7 @@ descriptor resides is x-locked. This function no longer extends the data file. @return pointer to the extent descriptor, NULL if the page does not exist in the space or if the offset is >= the free limit */ -UNIV_INLINE __attribute__((nonnull, warn_unused_result)) +UNIV_INLINE MY_ATTRIBUTE((nonnull, warn_unused_result)) xdes_t* xdes_get_descriptor_with_space_hdr( /*===============================*/ @@ -487,7 +487,7 @@ is necessary to make the descriptor defined, as they are uninitialized above the free limit. @return pointer to the extent descriptor, NULL if the page does not exist in the space or if the offset exceeds the free limit */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) xdes_t* xdes_get_descriptor( /*================*/ @@ -614,7 +614,7 @@ byte* fsp_parse_init_file_page( /*=====================*/ byte* ptr, /*!< in: buffer */ - byte* end_ptr __attribute__((unused)), /*!< in: buffer end */ + byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */ buf_block_t* block) /*!< in: block or NULL */ { ut_ad(ptr && end_ptr); @@ -850,7 +850,7 @@ fsp_header_get_tablespace_size(void) Tries to extend a single-table tablespace so that a page would fit in the data file. @return TRUE if success */ -static UNIV_COLD __attribute__((nonnull, warn_unused_result)) +static UNIV_COLD MY_ATTRIBUTE((nonnull, warn_unused_result)) ibool fsp_try_extend_data_file_with_pages( /*================================*/ @@ -882,7 +882,7 @@ fsp_try_extend_data_file_with_pages( /***********************************************************************//** Tries to extend the last data file of a tablespace if it is auto-extending. @return FALSE if not auto-extending */ -static UNIV_COLD __attribute__((nonnull)) +static UNIV_COLD MY_ATTRIBUTE((nonnull)) ibool fsp_try_extend_data_file( /*=====================*/ @@ -1064,7 +1064,8 @@ fsp_fill_free_list( ulint i; mtr_t ibuf_mtr; - ut_ad(header && mtr); + ut_ad(header != NULL); + ut_ad(mtr != NULL); ut_ad(page_offset(header) == FSP_HEADER_OFFSET); /* Check if we can fill free list from above the free list limit */ @@ -1236,7 +1237,7 @@ fsp_alloc_free_extent( /**********************************************************************//** Allocates a single free page from a space. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void fsp_alloc_from_free_frag( /*=====================*/ @@ -1327,7 +1328,7 @@ Allocates a single free page from a space. The page is marked as used. @retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded (init_mtr == mtr, or the page was not previously freed in mtr) @retval block (not allocated or initialized) otherwise */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) buf_block_t* fsp_alloc_free_page( /*================*/ @@ -1576,9 +1577,9 @@ fsp_seg_inode_page_get_nth_inode( /*=============================*/ page_t* page, /*!< in: segment inode page */ ulint i, /*!< in: inode index on page */ - ulint zip_size __attribute__((unused)), + ulint zip_size MY_ATTRIBUTE((unused)), /*!< in: compressed page size, or 0 */ - mtr_t* mtr __attribute__((unused))) + mtr_t* mtr MY_ATTRIBUTE((unused))) /*!< in/out: mini-transaction */ { ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size)); @@ -1877,7 +1878,7 @@ fseg_get_nth_frag_page_no( /*======================*/ fseg_inode_t* inode, /*!< in: segment inode */ ulint n, /*!< in: slot index */ - mtr_t* mtr __attribute__((unused))) + mtr_t* mtr MY_ATTRIBUTE((unused))) /*!< in/out: mini-transaction */ { ut_ad(inode && mtr); @@ -2958,7 +2959,7 @@ fsp_get_available_space_in_free_extents( /********************************************************************//** Marks a page used. The page must reside within the extents of the given segment. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void fseg_mark_page_used( /*================*/ @@ -3030,7 +3031,8 @@ fseg_free_page_low( ib_id_t seg_id; ulint i; - ut_ad(seg_inode && mtr); + ut_ad(seg_inode != NULL); + ut_ad(mtr != NULL); ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); @@ -3239,7 +3241,8 @@ fseg_free_extent( ulint descr_n_used; ulint i; - ut_ad(seg_inode && mtr); + ut_ad(seg_inode != NULL); + ut_ad(mtr != NULL); descr = xdes_get_descriptor(space, zip_size, page, mtr); diff --git a/storage/innobase/fts/fts0blex.cc b/storage/innobase/fts/fts0blex.cc index 7d0acb00a3ba2..2d71934fa0ef6 100644 --- a/storage/innobase/fts/fts0blex.cc +++ b/storage/innobase/fts/fts0blex.cc @@ -305,9 +305,9 @@ YY_BUFFER_STATE fts0b_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner YY_BUFFER_STATE fts0b_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE fts0b_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); -void *fts0balloc (yy_size_t , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); -void *fts0brealloc (void *,yy_size_t , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); -void fts0bfree (void * , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); +void *fts0balloc (yy_size_t , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); +void *fts0brealloc (void *,yy_size_t , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); +void fts0bfree (void * , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); #define yy_new_buffer fts0b_create_buffer @@ -347,7 +347,7 @@ typedef int yy_state_type; static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); +static void yy_fatal_error (yyconst char msg[] , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. @@ -451,7 +451,7 @@ static yyconst flex_int16_t yy_chk[32] = #line 1 "fts0blex.l" /***************************************************************************** -Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -579,11 +579,11 @@ extern int fts0bwrap (yyscan_t yyscanner ); #endif #ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))); +static void yy_flex_strncpy (char *,yyconst char *,int , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))); +static int yy_flex_strlen (yyconst char * , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))); #endif #ifndef YY_NO_INPUT @@ -1609,7 +1609,7 @@ YY_BUFFER_STATE fts0b_scan_bytes (yyconst char * yybytes, int _yybytes_len , y #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); @@ -1910,7 +1910,7 @@ int fts0blex_destroy (yyscan_t yyscanner) */ #ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { register int i; for ( i = 0; i < n; ++i ) @@ -1919,7 +1919,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yys #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { register int n; for ( n = 0; s[n]; ++n ) @@ -1929,12 +1929,12 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner __at } #endif -void *fts0balloc (yy_size_t size , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +void *fts0balloc (yy_size_t size , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { return (void *) malloc( size ); } -void *fts0brealloc (void * ptr, yy_size_t size , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +void *fts0brealloc (void * ptr, yy_size_t size , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those @@ -1946,7 +1946,7 @@ void *fts0brealloc (void * ptr, yy_size_t size , yyscan_t yyscanner return (void *) realloc( (char *) ptr, size ); } -void fts0bfree (void * ptr , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +void fts0bfree (void * ptr , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { free( (char *) ptr ); /* see fts0brealloc() for (char *) cast */ } diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 25047b38b9de0..22278338072fa 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -280,7 +280,7 @@ void fts_words_free( /*===========*/ ib_rbt_t* words) /*!< in: rb tree of words */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef FTS_CACHE_SIZE_DEBUG /****************************************************************//** Read the max cache size parameter from the config table. */ @@ -302,7 +302,7 @@ fts_add_doc_by_id( /*==============*/ fts_trx_table_t*ftt, /*!< in: FTS trx table */ doc_id_t doc_id, /*!< in: doc id */ - ib_vector_t* fts_indexes __attribute__((unused))); + ib_vector_t* fts_indexes MY_ATTRIBUTE((unused))); /*!< in: affected fts indexes */ #ifdef FTS_DOC_STATS_DEBUG /****************************************************************//** @@ -317,7 +317,7 @@ fts_is_word_in_index( fts_table_t* fts_table, /*!< in: table instance */ const fts_string_t* word, /*!< in: the word to check */ ibool* found) /*!< out: TRUE if exists */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* FTS_DOC_STATS_DEBUG */ /******************************************************************//** @@ -332,7 +332,7 @@ fts_update_sync_doc_id( const char* table_name, /*!< in: table name, or NULL */ doc_id_t doc_id, /*!< in: last document id */ trx_t* trx) /*!< in: update trx, or NULL */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /****************************************************************//** This function loads the default InnoDB stopword list */ @@ -1075,13 +1075,12 @@ fts_words_free( } } -/*********************************************************************//** -Clear cache. */ +/** Clear cache. +@param[in,out] cache fts cache */ UNIV_INTERN void fts_cache_clear( -/*============*/ - fts_cache_t* cache) /*!< in: cache */ + fts_cache_t* cache) { ulint i; @@ -1477,7 +1476,7 @@ fts_cache_add_doc( /****************************************************************//** Drops a table. If the table can't be found we return a SUCCESS code. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_drop_table( /*===========*/ @@ -1519,7 +1518,7 @@ fts_drop_table( /****************************************************************//** Rename a single auxiliary table due to database name change. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_rename_one_aux_table( /*=====================*/ @@ -1628,7 +1627,7 @@ Drops the common ancillary tables needed for supporting an FTS index on the given table. row_mysql_lock_data_dictionary must have been called before this. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_drop_common_tables( /*===================*/ @@ -1755,7 +1754,7 @@ Drops FTS ancillary tables needed for supporting an FTS index on the given table. row_mysql_lock_data_dictionary must have been called before this. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_drop_all_index_tables( /*======================*/ @@ -2663,7 +2662,7 @@ fts_get_next_doc_id( This function fetch the Doc ID from CONFIG table, and compare with the Doc ID supplied. And store the larger one to the CONFIG table. @return DB_SUCCESS if OK */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t fts_cmp_set_sync_doc_id( /*====================*/ @@ -2917,7 +2916,7 @@ fts_add( /*********************************************************************//** Do commit-phase steps necessary for the deletion of a row. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_delete( /*=======*/ @@ -3008,7 +3007,7 @@ fts_delete( /*********************************************************************//** Do commit-phase steps necessary for the modification of a row. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_modify( /*=======*/ @@ -3079,7 +3078,7 @@ fts_create_doc_id( The given transaction is about to be committed; do whatever is necessary from the FTS system's POV. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_commit_table( /*=============*/ @@ -3412,7 +3411,7 @@ fts_add_doc_by_id( /*==============*/ fts_trx_table_t*ftt, /*!< in: FTS trx table */ doc_id_t doc_id, /*!< in: doc id */ - ib_vector_t* fts_indexes __attribute__((unused))) + ib_vector_t* fts_indexes MY_ATTRIBUTE((unused))) /*!< in: affected fts indexes */ { mtr_t mtr; @@ -3532,7 +3531,7 @@ fts_add_doc_by_id( get_doc, clust_index, doc_pcur, offsets, &doc); if (doc.found) { - ibool success __attribute__((unused)); + ibool success MY_ATTRIBUTE((unused)); btr_pcur_store_position(doc_pcur, &mtr); mtr_commit(&mtr); @@ -3641,7 +3640,7 @@ fts_get_max_doc_id( dict_table_t* table) /*!< in: user table */ { dict_index_t* index; - dict_field_t* dfield __attribute__((unused)) = NULL; + dict_field_t* dfield MY_ATTRIBUTE((unused)) = NULL; doc_id_t doc_id = 0; mtr_t mtr; btr_pcur_t pcur; @@ -3899,7 +3898,7 @@ fts_write_node( /*********************************************************************//** Add rows to the DELETED_CACHE table. @return DB_SUCCESS if all went well else error code*/ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_sync_add_deleted_cache( /*=======================*/ @@ -3953,7 +3952,7 @@ fts_sync_add_deleted_cache( @param[in] index_cache index cache @param[in] unlock_cache whether unlock cache when write node @return DB_SUCCESS if all went well else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_sync_write_words( trx_t* trx, @@ -4089,7 +4088,7 @@ fts_sync_write_words( /*********************************************************************//** Write a single documents statistics to disk. @return DB_SUCCESS if all went well else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_sync_write_doc_stat( /*====================*/ @@ -4343,7 +4342,7 @@ fts_sync_begin( Run SYNC on the table, i.e., write out data from the index specific cache to the FTS aux INDEX table and FTS aux doc id stats table. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_sync_index( /*===========*/ @@ -4411,7 +4410,7 @@ fts_sync_index_check( /*********************************************************************//** Commit the SYNC, change state of processed doc ids etc. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_sync_commit( /*============*/ @@ -4473,13 +4472,12 @@ fts_sync_commit( return(error); } -/*********************************************************************//** -Rollback a sync operation */ +/** Rollback a sync operation +@param[in,out] sync sync state */ static void fts_sync_rollback( -/*==============*/ - fts_sync_t* sync) /*!< in: sync state */ + fts_sync_t* sync) { trx_t* trx = sync->trx; fts_cache_t* cache = sync->table->fts->cache; @@ -6169,7 +6167,7 @@ fts_update_hex_format_flag( /*********************************************************************//** Rename an aux table to HEX format. It's called when "%016llu" is used to format an object id in table name, which only happens in Windows. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_rename_one_aux_table_to_hex_format( /*===================================*/ @@ -6260,7 +6258,7 @@ Note the ids in tables are correct but the names are old ambiguous ones. This function should make sure that either all the parent table and aux tables are set DICT_TF2_FTS_AUX_HEX_NAME with flags2 or none of them are set */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_rename_aux_tables_to_hex_format_low( /*====================================*/ @@ -6414,14 +6412,14 @@ fts_fake_hex_to_dec( { ib_id_t dec_id = 0; char tmp_id[FTS_AUX_MIN_TABLE_ID_LENGTH]; - int ret __attribute__((unused)); + int ret MY_ATTRIBUTE((unused)); ret = sprintf(tmp_id, UINT64PFx, id); ut_ad(ret == 16); #ifdef _WIN32 ret = sscanf(tmp_id, "%016llu", &dec_id); #else - ret = sscanf(tmp_id, "%016"PRIu64, &dec_id); + ret = sscanf(tmp_id, "%016" PRIu64, &dec_id); #endif /* _WIN32 */ ut_ad(ret == 1); @@ -6736,7 +6734,7 @@ fts_drop_aux_table_from_vector( Check and drop all orphaned FTS auxiliary tables, those that don't have a parent table or FTS index defined on them. @return DB_SUCCESS or error code */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void fts_check_and_drop_orphaned_tables( /*===============================*/ diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 711c5f53d01c9..1cf45961ae22b 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -797,7 +797,7 @@ fts_zip_deflate_end( Read the words from the FTS INDEX. @return DB_SUCCESS if all OK, DB_TABLE_NOT_FOUND if no more indexes to search else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_index_fetch_words( /*==================*/ @@ -1131,7 +1131,7 @@ fts_optimize_lookup( /**********************************************************************//** Encode the word pos list into the node @return DB_SUCCESS or error code*/ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t fts_optimize_encode_node( /*=====================*/ @@ -1220,7 +1220,7 @@ fts_optimize_encode_node( /**********************************************************************//** Optimize the data contained in a node. @return DB_SUCCESS or error code*/ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t fts_optimize_node( /*==============*/ @@ -1318,7 +1318,7 @@ fts_optimize_node( /**********************************************************************//** Determine the starting pos within the deleted doc id vector for a word. @return delete position */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) int fts_optimize_deleted_pos( /*=====================*/ @@ -1447,7 +1447,7 @@ fts_optimize_word( /**********************************************************************//** Update the FTS index table. This is a delete followed by an insert. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_write_word( /*====================*/ @@ -1550,7 +1550,7 @@ fts_word_free( /**********************************************************************//** Optimize the word ilist and rewrite data to the FTS index. @return status one of RESTART, EXIT, ERROR */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_compact( /*=================*/ @@ -1645,7 +1645,7 @@ fts_optimize_create( /**********************************************************************//** Get optimize start time of an FTS index. @return DB_SUCCESS if all OK else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_get_index_start_time( /*==============================*/ @@ -1661,7 +1661,7 @@ fts_optimize_get_index_start_time( /**********************************************************************//** Set the optimize start time of an FTS index. @return DB_SUCCESS if all OK else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_set_index_start_time( /*==============================*/ @@ -1677,7 +1677,7 @@ fts_optimize_set_index_start_time( /**********************************************************************//** Get optimize end time of an FTS index. @return DB_SUCCESS if all OK else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_get_index_end_time( /*============================*/ @@ -1692,7 +1692,7 @@ fts_optimize_get_index_end_time( /**********************************************************************//** Set the optimize end time of an FTS index. @return DB_SUCCESS if all OK else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_set_index_end_time( /*============================*/ @@ -1912,7 +1912,7 @@ fts_optimize_set_next_word( Optimize is complete. Set the completion time, and reset the optimize start string for this FTS index to "". @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_index_completed( /*=========================*/ @@ -1952,7 +1952,7 @@ fts_optimize_index_completed( Read the list of words from the FTS auxiliary index that will be optimized in this pass. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_index_read_words( /*==========================*/ @@ -2009,7 +2009,7 @@ fts_optimize_index_read_words( Run OPTIMIZE on the given FTS index. Note: this can take a very long time (hours). @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_index( /*===============*/ @@ -2080,7 +2080,7 @@ fts_optimize_index( /**********************************************************************//** Delete the document ids in the delete, and delete cache tables. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_purge_deleted_doc_ids( /*===============================*/ @@ -2149,7 +2149,7 @@ fts_optimize_purge_deleted_doc_ids( /**********************************************************************//** Delete the document ids in the pending delete, and delete tables. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_purge_deleted_doc_id_snapshot( /*=======================================*/ @@ -2199,7 +2199,7 @@ Copy the deleted doc ids that will be purged during this optimize run to the being deleted FTS auxiliary tables. The transaction is committed upon successfull copy and rolled back on DB_DUPLICATE_KEY error. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_create_deleted_doc_id_snapshot( /*========================================*/ @@ -2237,7 +2237,7 @@ fts_optimize_create_deleted_doc_id_snapshot( Read in the document ids that are to be purged during optimize. The transaction is committed upon successfully read. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_read_deleted_doc_id_snapshot( /*======================================*/ @@ -2274,7 +2274,7 @@ Optimze all the FTS indexes, skipping those that have already been optimized, since the FTS auxiliary indexes are not guaranteed to be of the same cardinality. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_indexes( /*=================*/ @@ -2344,7 +2344,7 @@ fts_optimize_indexes( /*********************************************************************//** Cleanup the snapshot tables and the master deleted table. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_purge_snapshot( /*========================*/ @@ -2373,7 +2373,7 @@ fts_optimize_purge_snapshot( /*********************************************************************//** Reset the start time to 0 so that a new optimize can be started. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_optimize_reset_start_time( /*==========================*/ @@ -2412,7 +2412,7 @@ fts_optimize_reset_start_time( /*********************************************************************//** Run OPTIMIZE on the given table by a background thread. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t fts_optimize_table_bk( /*==================*/ @@ -2757,6 +2757,7 @@ fts_optimize_new_table( empty_slot = i; } else if (slot->table->id == table->id) { /* Already exists in our optimize queue. */ + ut_ad(slot->table_id = table->id); return(FALSE); } } @@ -2974,6 +2975,13 @@ fts_optimize_sync_table( { dict_table_t* table = NULL; + /* Prevent DROP INDEX etc. from running when we are syncing + cache in background. */ + if (!rw_lock_s_lock_nowait(&dict_operation_lock, __FILE__, __LINE__)) { + /* Exit when fail to get dict operation lock. */ + return; + } + table = dict_table_open_on_id(table_id, FALSE, DICT_TABLE_OP_NORMAL); if (table) { @@ -2983,6 +2991,8 @@ fts_optimize_sync_table( dict_table_close(table, FALSE, FALSE); } + + rw_lock_s_unlock(&dict_operation_lock); } /**********************************************************************//** diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc index fcae656176498..2c44a21a8f294 100644 --- a/storage/innobase/fts/fts0que.cc +++ b/storage/innobase/fts/fts0que.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -287,7 +287,7 @@ fts_expand_query( dict_index_t* index, /*!< in: FTS index to search */ fts_query_t* query) /*!< in: query result, to be freed by the client */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** This function finds documents that contain all words in a phrase or proximity search. And if proximity search, verify @@ -1128,7 +1128,7 @@ fts_cache_find_wildcard( /*****************************************************************//** Set difference. @return DB_SUCCESS if all go well */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_difference( /*=================*/ @@ -1220,7 +1220,7 @@ fts_query_difference( /*****************************************************************//** Intersect the token doc ids with the current set. @return DB_SUCCESS if all go well */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_intersect( /*================*/ @@ -1398,7 +1398,7 @@ fts_query_cache( /*****************************************************************//** Set union. @return DB_SUCCESS if all go well */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_union( /*============*/ @@ -2014,7 +2014,7 @@ fts_query_select( Read the rows from the FTS index, that match word and where the doc id is between first and last doc id. @return DB_SUCCESS if all go well else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_find_term( /*================*/ @@ -2154,7 +2154,7 @@ fts_query_sum( /******************************************************************** Calculate the total documents that contain a particular word (term). @return DB_SUCCESS if all go well else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_total_docs_containing_term( /*=================================*/ @@ -2233,7 +2233,7 @@ fts_query_total_docs_containing_term( /******************************************************************** Get the total number of words in a documents. @return DB_SUCCESS if all go well else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_terms_in_document( /*========================*/ @@ -2314,7 +2314,7 @@ fts_query_terms_in_document( /*****************************************************************//** Retrieve the document and match the phrase tokens. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_match_document( /*=====================*/ @@ -2360,7 +2360,7 @@ fts_query_match_document( This function fetches the original documents and count the words in between matching words to see that is in specified distance @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool fts_query_is_in_proximity_range( /*============================*/ @@ -2415,7 +2415,7 @@ fts_query_is_in_proximity_range( Iterate over the matched document ids and search the for the actual phrase in the text. @return DB_SUCCESS if all OK */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_search_phrase( /*====================*/ @@ -2503,7 +2503,7 @@ fts_query_search_phrase( /*****************************************************************//** Text/Phrase search. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_phrase_search( /*====================*/ @@ -2754,7 +2754,7 @@ fts_query_phrase_search( /*****************************************************************//** Find the word and evaluate. @return DB_SUCCESS if all go well */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_query_execute( /*==============*/ @@ -4123,7 +4123,7 @@ words in documents found in the first search pass will be used as search arguments to search the document again, thus "expand" the search result set. @return DB_SUCCESS if success, otherwise the error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t fts_expand_query( /*=============*/ diff --git a/storage/innobase/fts/fts0tlex.cc b/storage/innobase/fts/fts0tlex.cc index b744fbf0763c2..d4d9b4c48d1b7 100644 --- a/storage/innobase/fts/fts0tlex.cc +++ b/storage/innobase/fts/fts0tlex.cc @@ -305,9 +305,9 @@ YY_BUFFER_STATE fts0t_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner YY_BUFFER_STATE fts0t_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE fts0t_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); -void *fts0talloc (yy_size_t , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); -void *fts0trealloc (void *,yy_size_t , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); -void fts0tfree (void * , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); +void *fts0talloc (yy_size_t , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); +void *fts0trealloc (void *,yy_size_t , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); +void fts0tfree (void * , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); #define yy_new_buffer fts0t_create_buffer @@ -347,7 +347,7 @@ typedef int yy_state_type; static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) ); +static void yy_fatal_error (yyconst char msg[] , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. @@ -447,7 +447,7 @@ static yyconst flex_int16_t yy_chk[29] = #line 1 "fts0tlex.l" /***************************************************************************** -Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -575,11 +575,11 @@ extern int fts0twrap (yyscan_t yyscanner ); #endif #ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))); +static void yy_flex_strncpy (char *,yyconst char *,int , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))); +static int yy_flex_strlen (yyconst char * , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))); #endif #ifndef YY_NO_INPUT @@ -1602,7 +1602,7 @@ YY_BUFFER_STATE fts0t_scan_bytes (yyconst char * yybytes, int _yybytes_len , y #define YY_EXIT_FAILURE 2 #endif -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); @@ -1903,7 +1903,7 @@ int fts0tlex_destroy (yyscan_t yyscanner) */ #ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { register int i; for ( i = 0; i < n; ++i ) @@ -1912,7 +1912,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yys #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { register int n; for ( n = 0; s[n]; ++n ) @@ -1922,12 +1922,12 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner __at } #endif -void *fts0talloc (yy_size_t size , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +void *fts0talloc (yy_size_t size , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { return (void *) malloc( size ); } -void *fts0trealloc (void * ptr, yy_size_t size , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +void *fts0trealloc (void * ptr, yy_size_t size , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those @@ -1939,7 +1939,7 @@ void *fts0trealloc (void * ptr, yy_size_t size , yyscan_t yyscanner return (void *) realloc( (char *) ptr, size ); } -void fts0tfree (void * ptr , yyscan_t yyscanner __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused)) __attribute__((unused))) +void fts0tfree (void * ptr , yyscan_t yyscanner MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused)) MY_ATTRIBUTE((unused))) { free( (char *) ptr ); /* see fts0trealloc() for (char *) cast */ } diff --git a/storage/innobase/fts/make_parser.sh b/storage/innobase/fts/make_parser.sh index 2c072914c8b7f..52b63eff67454 100755 --- a/storage/innobase/fts/make_parser.sh +++ b/storage/innobase/fts/make_parser.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved. +# Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. # # 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 @@ -22,15 +22,15 @@ make -f Makefile.query echo '#include "univ.i"' > $TMPF # This is to avoid compiler warning about unused parameters. -# FIXME: gcc extension "__attribute__" causing compilation errors on windows +# FIXME: gcc extension "MY_ATTRIBUTE" causing compilation errors on windows # platform. Quote them out for now. sed -e ' -s/^\(static.*void.*yy_fatal_error.*msg.*,\)\(.*yyscanner\)/\1 \2 __attribute__((unused))/; -s/^\(static.*void.*yy_flex_strncpy.*n.*,\)\(.*yyscanner\)/\1 \2 __attribute__((unused))/; -s/^\(static.*int.*yy_flex_strlen.*s.*,\)\(.*yyscanner\)/\1 \2 __attribute__((unused))/; -s/^\(\(static\|void\).*fts0[bt]alloc.*,\)\(.*yyscanner\)/\1 \3 __attribute__((unused))/; -s/^\(\(static\|void\).*fts0[bt]realloc.*,\)\(.*yyscanner\)/\1 \3 __attribute__((unused))/; -s/^\(\(static\|void\).*fts0[bt]free.*,\)\(.*yyscanner\)/\1 \3 __attribute__((unused))/; +s/^\(static.*void.*yy_fatal_error.*msg.*,\)\(.*yyscanner\)/\1 \2 MY_ATTRIBUTE((unused))/; +s/^\(static.*void.*yy_flex_strncpy.*n.*,\)\(.*yyscanner\)/\1 \2 MY_ATTRIBUTE((unused))/; +s/^\(static.*int.*yy_flex_strlen.*s.*,\)\(.*yyscanner\)/\1 \2 MY_ATTRIBUTE((unused))/; +s/^\(\(static\|void\).*fts0[bt]alloc.*,\)\(.*yyscanner\)/\1 \3 MY_ATTRIBUTE((unused))/; +s/^\(\(static\|void\).*fts0[bt]realloc.*,\)\(.*yyscanner\)/\1 \3 MY_ATTRIBUTE((unused))/; +s/^\(\(static\|void\).*fts0[bt]free.*,\)\(.*yyscanner\)/\1 \3 MY_ATTRIBUTE((unused))/; ' < fts0blex.cc >> $TMPF mv $TMPF fts0blex.cc @@ -38,12 +38,12 @@ mv $TMPF fts0blex.cc echo '#include "univ.i"' > $TMPF sed -e ' -s/^\(static.*void.*yy_fatal_error.*msg.*,\)\(.*yyscanner\)/\1 \2 __attribute__((unused))/; -s/^\(static.*void.*yy_flex_strncpy.*n.*,\)\(.*yyscanner\)/\1 \2 __attribute__((unused))/; -s/^\(static.*int.*yy_flex_strlen.*s.*,\)\(.*yyscanner\)/\1 \2 __attribute__((unused))/; -s/^\(\(static\|void\).*fts0[bt]alloc.*,\)\(.*yyscanner\)/\1 \3 __attribute__((unused))/; -s/^\(\(static\|void\).*fts0[bt]realloc.*,\)\(.*yyscanner\)/\1 \3 __attribute__((unused))/; -s/^\(\(static\|void\).*fts0[bt]free.*,\)\(.*yyscanner\)/\1 \3 __attribute__((unused))/; +s/^\(static.*void.*yy_fatal_error.*msg.*,\)\(.*yyscanner\)/\1 \2 MY_ATTRIBUTE((unused))/; +s/^\(static.*void.*yy_flex_strncpy.*n.*,\)\(.*yyscanner\)/\1 \2 MY_ATTRIBUTE((unused))/; +s/^\(static.*int.*yy_flex_strlen.*s.*,\)\(.*yyscanner\)/\1 \2 MY_ATTRIBUTE((unused))/; +s/^\(\(static\|void\).*fts0[bt]alloc.*,\)\(.*yyscanner\)/\1 \3 MY_ATTRIBUTE((unused))/; +s/^\(\(static\|void\).*fts0[bt]realloc.*,\)\(.*yyscanner\)/\1 \3 MY_ATTRIBUTE((unused))/; +s/^\(\(static\|void\).*fts0[bt]free.*,\)\(.*yyscanner\)/\1 \3 MY_ATTRIBUTE((unused))/; ' < fts0tlex.cc >> $TMPF mv $TMPF fts0tlex.cc diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 3a9c3a44e7341..2a16f8daf24e1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1425,7 +1425,7 @@ thd_set_lock_wait_time( /********************************************************************//** Obtain the InnoDB transaction of a MySQL thread. @return reference to transaction pointer */ -__attribute__((warn_unused_result, nonnull)) +MY_ATTRIBUTE((warn_unused_result, nonnull)) static inline trx_t*& thd_to_trx( @@ -3486,7 +3486,7 @@ int innobase_end( /*=========*/ handlerton* hton, /*!< in/out: InnoDB handlerton */ - ha_panic_function type __attribute__((unused))) + ha_panic_function type MY_ATTRIBUTE((unused))) /*!< in: ha_panic() parameter */ { int err= 0; @@ -8612,7 +8612,7 @@ create_table_check_doc_id_col( /*****************************************************************//** Creates a table definition to an InnoDB database. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) int create_table_def( /*=============*/ @@ -10056,6 +10056,25 @@ ha_innobase::discard_or_import_tablespace( /* Commit the transaction in order to release the table lock. */ trx_commit_for_mysql(prebuilt->trx); + if (err == DB_SUCCESS && !discard + && dict_stats_is_persistent_enabled(dict_table)) { + dberr_t ret; + + /* Adjust the persistent statistics. */ + ret = dict_stats_update(dict_table, + DICT_STATS_RECALC_PERSISTENT); + + if (ret != DB_SUCCESS) { + push_warning_printf( + ha_thd(), + Sql_condition::WARN_LEVEL_WARN, + ER_ALTER_INFO, + "Error updating stats for table '%s'" + " after table rebuild: %s", + dict_table->name, ut_strerr(ret)); + } + } + DBUG_RETURN(convert_error_code_to_mysql(err, dict_table->flags, NULL)); } @@ -10306,7 +10325,7 @@ innobase_drop_database( /*********************************************************************//** Renames an InnoDB table. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t innobase_rename_table( /*==================*/ @@ -15216,7 +15235,7 @@ static char* srv_buffer_pool_evict; Evict all uncompressed pages of compressed tables from the buffer pool. Keep the compressed pages in the buffer pool. @return whether all uncompressed pages were evicted */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) bool innodb_buffer_pool_evict_uncompressed(void) /*=======================================*/ @@ -15544,13 +15563,13 @@ void purge_run_now_set( /*==============*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15567,13 +15586,13 @@ void purge_stop_now_set( /*===============*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15589,13 +15608,13 @@ void checkpoint_now_set( /*===============*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15616,13 +15635,13 @@ void buf_flush_list_now_set( /*===================*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15719,13 +15738,13 @@ void buffer_pool_dump_now( /*=================*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15742,13 +15761,13 @@ void buffer_pool_load_now( /*=================*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15765,13 +15784,13 @@ void buffer_pool_load_abort( /*===================*/ THD* thd /*!< in: thread handle */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), struct st_mysql_sys_var* var /*!< in: pointer to system variable */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), void* var_ptr /*!< out: where the formal string goes */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const void* save) /*!< in: immediate result from check function */ { @@ -15789,10 +15808,10 @@ which control InnoDB "status monitor" output to the error log. static void innodb_status_output_update( - THD* thd __attribute__((unused)), - struct st_mysql_sys_var* var __attribute__((unused)), - void* var_ptr __attribute__((unused)), - const void* save __attribute__((unused))) + THD* thd MY_ATTRIBUTE((unused)), + struct st_mysql_sys_var* var MY_ATTRIBUTE((unused)), + void* var_ptr MY_ATTRIBUTE((unused)), + const void* save MY_ATTRIBUTE((unused))) { *static_cast(var_ptr) = *static_cast(save); /* The lock timeout monitor thread also takes care of this diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index f735b6fef2dc8..4b1cc3ed0bd41 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -430,14 +430,14 @@ enum durability_properties thd_get_durability_property(const MYSQL_THD thd); @param off auto_increment_offset @param inc auto_increment_increment */ void thd_get_autoinc(const MYSQL_THD thd, ulong* off, ulong* inc) -__attribute__((nonnull)); +MY_ATTRIBUTE((nonnull)); /** Is strict sql_mode set. @param thd Thread object @return True if sql_mode has strict mode (all or trans), false otherwise. */ bool thd_is_strict_mode(const MYSQL_THD thd) -__attribute__((nonnull)); +MY_ATTRIBUTE((nonnull)); } /* extern "C" */ struct trx_t; @@ -475,7 +475,7 @@ innobase_index_name_is_reserved( const KEY* key_info, /*!< in: Indexes to be created */ ulint num_of_keys) /*!< in: Number of indexes to be created. */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Determines InnoDB table flags. @@ -492,7 +492,7 @@ innobase_table_flags( outside system tablespace */ ulint* flags, /*!< out: DICT_TF flags */ ulint* flags2) /*!< out: DICT_TF2 flags */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Validates the create options. We may build on this function @@ -509,7 +509,7 @@ create_options_are_invalid( columns and indexes */ HA_CREATE_INFO* create_info, /*!< in: create info. */ bool use_tablespace) /*!< in: srv_file_per_table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Retrieve the FTS Relevance Ranking result for doc with doc_id @@ -539,7 +539,7 @@ void innobase_fts_close_ranking( /*=======================*/ FT_INFO* fts_hdl) /*!< in: FTS handler */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*****************************************************************//** Initialize the table FTS stopword list @return TRUE if success */ @@ -550,7 +550,7 @@ innobase_fts_load_stopword( dict_table_t* table, /*!< in: Table has the FTS */ trx_t* trx, /*!< in: transaction */ THD* thd) /*!< in: current thread */ - __attribute__((nonnull(1,3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,3), warn_unused_result)); /** Some defines for innobase_fts_check_doc_id_index() return value */ enum fts_doc_id_index_enum { @@ -572,7 +572,7 @@ innobase_fts_check_doc_id_index( that is being altered */ ulint* fts_doc_col_no) /*!< out: The column number for Doc ID */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*******************************************************************//** Check whether the table has a unique index with FTS_DOC_ID_INDEX_NAME @@ -585,7 +585,7 @@ innobase_fts_check_doc_id_index_in_def( /*===================================*/ ulint n_key, /*!< in: Number of keys */ const KEY* key_info) /*!< in: Key definitions */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************** @return version of the extended FTS API */ diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c431a3cd37d2c..961e0818d3987 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -98,7 +98,7 @@ static const Alter_inplace_info::HA_ALTER_FLAGS INNOBASE_ALTER_NOREBUILD | Alter_inplace_info::ALTER_COLUMN_NAME; /* Report an InnoDB error to the client by invoking my_error(). */ -static UNIV_COLD __attribute__((nonnull)) +static UNIV_COLD MY_ATTRIBUTE((nonnull)) void my_error_innodb( /*============*/ @@ -195,7 +195,7 @@ innobase_fulltext_exist( Determine if ALTER TABLE needs to rebuild the table. @param ha_alter_info the DDL operation @return whether it is necessary to rebuild the table */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_need_rebuild( /*==================*/ @@ -515,7 +515,7 @@ ha_innobase::check_if_supported_inplace_alter( /*************************************************************//** Initialize the dict_foreign_t structure with supplied info @return true if added, false if duplicate foreign->id */ -static __attribute__((nonnull(1,3,5,7))) +static MY_ATTRIBUTE((nonnull(1,3,5,7))) bool innobase_init_foreign( /*==================*/ @@ -604,7 +604,7 @@ innobase_init_foreign( /*************************************************************//** Check whether the foreign key options is legit @return true if it is */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_check_fk_option( /*=====================*/ @@ -636,7 +636,7 @@ innobase_check_fk_option( /*************************************************************//** Set foreign key options @return true if successfully set */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_set_foreign_key_option( /*============================*/ @@ -681,7 +681,7 @@ innobase_set_foreign_key_option( Check if a foreign key constraint can make use of an index that is being created. @return useable index, or NULL if none found */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const KEY* innobase_find_equiv_index( /*======================*/ @@ -737,7 +737,7 @@ innobase_find_equiv_index( Find an index whose first fields are the columns in the array in the same order and is not marked for deletion @return matching index, NULL if not found */ -static __attribute__((nonnull(1,2,6), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1,2,6), warn_unused_result)) dict_index_t* innobase_find_fk_index( /*===================*/ @@ -784,7 +784,7 @@ innobase_find_fk_index( Create InnoDB foreign key structure from MySQL alter_info @retval true if successful @retval false on error (will call my_error()) */ -static __attribute__((nonnull(1,2,3,7,8), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1,2,3,7,8), warn_unused_result)) bool innobase_get_foreign_key_info( /*==========================*/ @@ -1269,7 +1269,7 @@ innobase_rec_reset( /*******************************************************************//** This function checks that index keys are sensible. @return 0 or error number */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) int innobase_check_index_keys( /*======================*/ @@ -1390,7 +1390,7 @@ innobase_check_index_keys( /*******************************************************************//** Create index field definition for key part */ -static __attribute__((nonnull(2,3))) +static MY_ATTRIBUTE((nonnull(2,3))) void innobase_create_index_field_def( /*============================*/ @@ -1437,7 +1437,7 @@ innobase_create_index_field_def( /*******************************************************************//** Create index definition for key */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void innobase_create_index_def( /*======================*/ @@ -1721,7 +1721,7 @@ ELSE ENDIF @return key definitions */ -static __attribute__((nonnull, warn_unused_result, malloc)) +static MY_ATTRIBUTE((nonnull, warn_unused_result, malloc)) index_def_t* innobase_create_key_defs( /*=====================*/ @@ -1940,7 +1940,7 @@ innobase_create_key_defs( /*******************************************************************//** Check each index column size, make sure they do not exceed the max limit @return true if index column size exceeds limit */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_check_column_length( /*=========================*/ @@ -2090,7 +2090,7 @@ online_retry_drop_indexes_low( /********************************************************************//** Drop any indexes that we were not able to free previously due to open table handles. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void online_retry_drop_indexes( /*======================*/ @@ -2120,7 +2120,7 @@ online_retry_drop_indexes( /********************************************************************//** Commit a dictionary transaction and drop any indexes that we were not able to free previously due to open table handles. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void online_retry_drop_indexes_with_trx( /*===============================*/ @@ -2149,7 +2149,7 @@ online_retry_drop_indexes_with_trx( @param drop_fk constraints being dropped @param n_drop_fk number of constraints that are being dropped @return whether the constraint is being dropped */ -inline __attribute__((pure, nonnull, warn_unused_result)) +inline MY_ATTRIBUTE((pure, nonnull, warn_unused_result)) bool innobase_dropping_foreign( /*======================*/ @@ -2176,7 +2176,7 @@ column that is being dropped or modified to NOT NULL. @retval true Not allowed (will call my_error()) @retval false Allowed */ -static __attribute__((pure, nonnull, warn_unused_result)) +static MY_ATTRIBUTE((pure, nonnull, warn_unused_result)) bool innobase_check_foreigns_low( /*========================*/ @@ -2276,7 +2276,7 @@ column that is being dropped or modified to NOT NULL. @retval true Not allowed (will call my_error()) @retval false Allowed */ -static __attribute__((pure, nonnull, warn_unused_result)) +static MY_ATTRIBUTE((pure, nonnull, warn_unused_result)) bool innobase_check_foreigns( /*====================*/ @@ -2321,7 +2321,7 @@ innobase_check_foreigns( @param dfield InnoDB data field to copy to @param field MySQL value for the column @param comp nonzero if in compact format */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void innobase_build_col_map_add( /*=======================*/ @@ -2355,7 +2355,7 @@ adding columns. @param heap Memory heap where allocated @return array of integers, mapping column numbers in the table to column numbers in altered_table */ -static __attribute__((nonnull(1,2,3,4,5,7), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1,2,3,4,5,7), warn_unused_result)) const ulint* innobase_build_col_map( /*===================*/ @@ -2492,7 +2492,7 @@ innobase_drop_fts_index_table( @param user_table InnoDB table as it is before the ALTER operation @param heap Memory heap for the allocation @return array of new column names in rebuilt_table, or NULL if not renamed */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const char** innobase_get_col_names( Alter_inplace_info* ha_alter_info, @@ -2555,7 +2555,7 @@ while preparing ALTER TABLE. @retval true Failure @retval false Success */ -static __attribute__((warn_unused_result, nonnull(1,2,3,4))) +static MY_ATTRIBUTE((warn_unused_result, nonnull(1,2,3,4))) bool prepare_inplace_alter_table_dict( /*=============================*/ @@ -3193,7 +3193,7 @@ prepare_inplace_alter_table_dict( /* Check whether an index is needed for the foreign key constraint. If so, if it is dropped, is there an equivalent index can play its role. @return true if the index is needed and can't be dropped */ -static __attribute__((nonnull(1,2,3,5), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1,2,3,5), warn_unused_result)) bool innobase_check_foreign_key_index( /*=============================*/ @@ -4069,7 +4069,7 @@ temparary index prefix @param locked TRUE=table locked, FALSE=may need to do a lazy drop @param trx the transaction */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void innobase_rollback_sec_index( /*========================*/ @@ -4103,7 +4103,7 @@ during prepare, but might not be during commit). @retval true Failure @retval false Success */ -inline __attribute__((nonnull, warn_unused_result)) +inline MY_ATTRIBUTE((nonnull, warn_unused_result)) bool rollback_inplace_alter_table( /*=========================*/ @@ -4235,7 +4235,7 @@ rollback_inplace_alter_table( @param foreign_id Foreign key constraint identifier @retval true Failure @retval false Success */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_drop_foreign_try( /*======================*/ @@ -4292,7 +4292,7 @@ innobase_drop_foreign_try( @param new_clustered whether the table has been rebuilt @retval true Failure @retval false Success */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_rename_column_try( /*=======================*/ @@ -4501,7 +4501,7 @@ innobase_rename_column_try( @param table_name Table name in MySQL @retval true Failure @retval false Success */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_rename_columns_try( /*========================*/ @@ -4551,7 +4551,7 @@ as part of commit_cache_norebuild(). @param ha_alter_info Data used during in-place alter. @param table the TABLE @param user_table InnoDB table that was being altered */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void innobase_rename_columns_cache( /*==========================*/ @@ -4595,7 +4595,7 @@ innobase_rename_columns_cache( @param altered_table MySQL table that is being altered @param old_table MySQL table as it is before the ALTER operation @return the next auto-increment value (0 if not present) */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ulonglong commit_get_autoinc( /*===============*/ @@ -4677,7 +4677,7 @@ but do not touch the data dictionary cache. @retval true Failure @retval false Success */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool innobase_update_foreign_try( /*========================*/ @@ -4760,7 +4760,7 @@ after the changes to data dictionary tables were committed. @param ctx In-place ALTER TABLE context @param user_thd MySQL connection @return InnoDB error code (should always be DB_SUCCESS) */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t innobase_update_foreign_cache( /*==========================*/ @@ -4845,7 +4845,7 @@ when rebuilding the table. @retval true Failure @retval false Success */ -inline __attribute__((nonnull, warn_unused_result)) +inline MY_ATTRIBUTE((nonnull, warn_unused_result)) bool commit_try_rebuild( /*===============*/ @@ -5007,7 +5007,7 @@ commit_try_rebuild( /** Apply the changes made during commit_try_rebuild(), to the data dictionary cache and the file system. @param ctx In-place ALTER TABLE context */ -inline __attribute__((nonnull)) +inline MY_ATTRIBUTE((nonnull)) void commit_cache_rebuild( /*=================*/ @@ -5102,7 +5102,7 @@ when not rebuilding the table. @retval true Failure @retval false Success */ -inline __attribute__((nonnull, warn_unused_result)) +inline MY_ATTRIBUTE((nonnull, warn_unused_result)) bool commit_try_norebuild( /*=================*/ @@ -5212,7 +5212,7 @@ after a successful commit_try_norebuild() call. @param trx Data dictionary transaction object (will be started and committed) @return whether all replacements were found for dropped indexes */ -inline __attribute__((nonnull, warn_unused_result)) +inline MY_ATTRIBUTE((nonnull, warn_unused_result)) bool commit_cache_norebuild( /*===================*/ diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index caf1f1a864b80..945611e62237e 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -657,7 +657,7 @@ byte* ibuf_parse_bitmap_init( /*===================*/ byte* ptr, /*!< in: buffer */ - byte* end_ptr __attribute__((unused)), /*!< in: buffer end */ + byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */ buf_block_t* block, /*!< in: block or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ { @@ -2494,7 +2494,7 @@ ibuf_get_merge_page_nos_func( /*******************************************************************//** Get the matching records for space id. @return current rec or NULL */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const rec_t* ibuf_get_user_rec( /*===============*/ @@ -2516,7 +2516,7 @@ ibuf_get_user_rec( Reads page numbers for a space id from an ibuf tree. @return a lower limit for the combined volume of records which will be merged */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ulint ibuf_get_merge_pages( /*=================*/ @@ -2624,40 +2624,22 @@ ibuf_merge_pages( } /*********************************************************************//** -Get the table instance from the table id. -@return table instance */ -static __attribute__((warn_unused_result)) -dict_table_t* -ibuf_get_table( -/*===========*/ - table_id_t table_id) /*!< in: valid table id */ -{ - rw_lock_s_lock_func(&dict_operation_lock, 0, __FILE__, __LINE__); - - dict_table_t* table = dict_table_open_on_id( - table_id, FALSE, DICT_TABLE_OP_NORMAL); - - rw_lock_s_unlock_gen(&dict_operation_lock, 0); - - return(table); -} - -/*********************************************************************//** -Contracts insert buffer trees by reading pages to the buffer pool. -@return a lower limit for the combined size in bytes of entries which -will be merged from ibuf trees to the pages read, 0 if ibuf is -empty */ -static +Contracts insert buffer trees by reading pages referring to space_id +to the buffer pool. +@returns number of pages merged.*/ +UNIV_INTERN ulint ibuf_merge_space( /*=============*/ - ulint space, /*!< in: tablespace id to merge */ - ulint* n_pages)/*!< out: number of pages to which merged */ + ulint space) /*!< in: tablespace id to merge */ { mtr_t mtr; btr_pcur_t pcur; mem_heap_t* heap = mem_heap_create(512); dtuple_t* tuple = ibuf_search_tuple_build(space, 0, heap); + ulint n_pages = 0; + + ut_ad(space < SRV_LOG_SPACE_FIRST_ID); ibuf_mtr_start(&mtr); @@ -2689,50 +2671,47 @@ ibuf_merge_space( } else { sum_sizes = ibuf_get_merge_pages( - &pcur, space, IBUF_MAX_N_PAGES_MERGED, - &pages[0], &spaces[0], &versions[0], n_pages, - &mtr); + &pcur, space, IBUF_MAX_N_PAGES_MERGED, + &pages[0], &spaces[0], &versions[0], &n_pages, + &mtr); + ib_logf(IB_LOG_LEVEL_INFO,"\n Size of pages merged %lu" + ,sum_sizes); - ++sum_sizes; } ibuf_mtr_commit(&mtr); btr_pcur_close(&pcur); - if (sum_sizes > 0) { - - ut_a(*n_pages > 0 || sum_sizes == 1); + if (n_pages > 0) { #ifdef UNIV_DEBUG - ut_ad(*n_pages <= UT_ARR_SIZE(pages)); + ut_ad(n_pages <= UT_ARR_SIZE(pages)); - for (ulint i = 0; i < *n_pages; ++i) { + for (ulint i = 0; i < n_pages; ++i) { ut_ad(spaces[i] == space); ut_ad(i == 0 || versions[i] == versions[i - 1]); } #endif /* UNIV_DEBUG */ buf_read_ibuf_merge_pages( - true, spaces, versions, pages, *n_pages); + true, spaces, versions, pages, n_pages); } - return(sum_sizes); + return(n_pages); } -/*********************************************************************//** -Contracts insert buffer trees by reading pages to the buffer pool. +/** Contract the change buffer by reading pages to the buffer pool. +@param[out] n_pages number of pages merged +@param[in] sync whether the caller waits for +the issued reads to complete @return a lower limit for the combined size in bytes of entries which will be merged from ibuf trees to the pages read, 0 if ibuf is empty */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ulint ibuf_merge( /*=======*/ - table_id_t table_id, /*!< in: if merge should be - done only for a specific - table, for all tables this - should be 0 */ ulint* n_pages, /*!< out: number of pages to which merged */ bool sync) /*!< in: TRUE if the caller @@ -2740,8 +2719,6 @@ ibuf_merge( read with the highest tablespace address to complete */ { - dict_table_t* table; - *n_pages = 0; /* We perform a dirty read of ibuf->empty, without latching @@ -2755,55 +2732,45 @@ ibuf_merge( } else if (ibuf_debug) { return(0); #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ - } else if (table_id == 0) { + } else { return(ibuf_merge_pages(n_pages, sync)); - } else if ((table = ibuf_get_table(table_id)) == 0) { - /* Table has been dropped. */ - return(0); } - - ulint volume = ibuf_merge_space(table->space, n_pages); - - dict_table_close(table, FALSE, FALSE); - - return(volume); } -/*********************************************************************//** -Contracts insert buffer trees by reading pages to the buffer pool. +/** Contract the change buffer by reading pages to the buffer pool. +@param[in] sync whether the caller waits for +the issued reads to complete @return a lower limit for the combined size in bytes of entries which -will be merged from ibuf trees to the pages read, 0 if ibuf is -empty */ +will be merged from ibuf trees to the pages read, 0 if ibuf is empty */ static ulint ibuf_contract( /*==========*/ - ibool sync) /*!< in: TRUE if the caller wants to wait for the + bool sync) /*!< in: TRUE if the caller wants to wait for the issued read with the highest tablespace address to complete */ { ulint n_pages; - return(ibuf_merge(0, &n_pages, sync)); + return(ibuf_merge_pages(&n_pages, sync)); } -/*********************************************************************//** -Contracts insert buffer trees by reading pages to the buffer pool. +/** Contract the change buffer by reading pages to the buffer pool. +@param[in] full If true, do a full contraction based +on PCT_IO(100). If false, the size of contract batch is determined +based on the current size of the change buffer. @return a lower limit for the combined size in bytes of entries which will be merged from ibuf trees to the pages read, 0 if ibuf is empty */ UNIV_INTERN ulint -ibuf_contract_in_background( -/*========================*/ - table_id_t table_id, /*!< in: if merge should be done only - for a specific table, for all tables - this should be 0 */ - ibool full) /*!< in: TRUE if the caller wants to - do a full contract based on PCT_IO(100). - If FALSE then the size of contract - batch is determined based on the - current size of the ibuf tree. */ +ibuf_merge_in_background( +/*=====================*/ + bool full) /*!< in: TRUE if the caller wants to + do a full contract based on PCT_IO(100). + If FALSE then the size of contract + batch is determined based on the + current size of the ibuf tree. */ { ulint sum_bytes = 0; ulint sum_pages = 0; @@ -2811,7 +2778,7 @@ ibuf_contract_in_background( ulint n_pages; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG - if (srv_ibuf_disable_background_merge && table_id == 0) { + if (srv_ibuf_disable_background_merge) { return(0); } #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ @@ -2840,7 +2807,7 @@ ibuf_contract_in_background( while (sum_pages < n_pages) { ulint n_bytes; - n_bytes = ibuf_merge(table_id, &n_pag2, FALSE); + n_bytes = ibuf_merge(&n_pag2, false); if (n_bytes == 0) { return(sum_bytes); @@ -3444,7 +3411,7 @@ ibuf_get_entry_counter_func( Buffer an operation in the insert/delete buffer, instead of doing it directly to the disk page, if this is possible. @return DB_SUCCESS, DB_STRONG_FAIL or other error */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t ibuf_insert_low( /*============*/ @@ -3511,8 +3478,7 @@ ibuf_insert_low( #ifdef UNIV_IBUF_DEBUG fputs("Ibuf too big\n", stderr); #endif - /* Use synchronous contract (== TRUE) */ - ibuf_contract(TRUE); + ibuf_contract(true); return(DB_STRONG_FAIL); } @@ -3935,7 +3901,7 @@ ibuf_insert( During merge, inserts to an index page a secondary index entry extracted from the insert buffer. @return newly inserted record */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) rec_t* ibuf_insert_to_index_page_low( /*==========================*/ @@ -4366,7 +4332,7 @@ ibuf_delete( /*********************************************************************//** Restores insert buffer tree cursor position @return TRUE if the position was restored; FALSE if not */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) ibool ibuf_restore_pos( /*=============*/ @@ -4421,7 +4387,7 @@ Deletes from ibuf the record on which pcur is positioned. If we have to resort to a pessimistic delete, this function commits mtr and closes the cursor. @return TRUE if mtr was committed and pcur closed in this operation */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) ibool ibuf_delete_rec( /*============*/ diff --git a/storage/innobase/include/api0api.h b/storage/innobase/include/api0api.h index e4c9c941de51a..500bf4fe3b22d 100644 --- a/storage/innobase/include/api0api.h +++ b/storage/innobase/include/api0api.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -36,7 +36,7 @@ InnoDB Native API #endif #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER) -#define UNIV_NO_IGNORE __attribute__ ((warn_unused_result)) +#define UNIV_NO_IGNORE MY_ATTRIBUTE ((warn_unused_result)) #else #define UNIV_NO_IGNORE #endif /* __GNUC__ && __GNUC__ > 2 && !__INTEL_COMPILER */ diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 305acf7e3220b..d8a4545c606bf 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -114,7 +114,7 @@ btr_corruption_report( /*==================*/ const buf_block_t* block, /*!< in: corrupted block */ const dict_index_t* index) /*!< in: index tree */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /** Assert that a B-tree page is not corrupted. @param block buffer block containing a B-tree page @@ -156,7 +156,7 @@ btr_blob_dbg_add_blob( ulint page_no, /*!< in: start page of the column */ dict_index_t* index, /*!< in/out: index tree */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Display the references to off-page columns. This function is to be called from a debugger, @@ -166,7 +166,7 @@ void btr_blob_dbg_print( /*===============*/ const dict_index_t* index) /*!< in: index tree */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Check that there are no references to off-page columns from or to the given page. Invoked when freeing or clearing a page. @@ -177,7 +177,7 @@ btr_blob_dbg_is_empty( /*==================*/ dict_index_t* index, /*!< in: index */ ulint page_no) /*!< in: page number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Modify the 'deleted' flag of a record. */ @@ -189,7 +189,7 @@ btr_blob_dbg_set_deleted_flag( dict_index_t* index, /*!< in/out: index */ const ulint* offsets,/*!< in: rec_get_offs(rec, index) */ ibool del) /*!< in: TRUE=deleted, FALSE=exists */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Change the ownership of an off-page column. */ UNIV_INTERN @@ -201,7 +201,7 @@ btr_blob_dbg_owner( const ulint* offsets,/*!< in: rec_get_offs(rec, index) */ ulint i, /*!< in: ith field in rec */ ibool own) /*!< in: TRUE=owned, FALSE=disowned */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Assert that there are no BLOB references to or from the given page. */ # define btr_blob_dbg_assert_empty(index, page_no) \ ut_a(btr_blob_dbg_is_empty(index, page_no)) @@ -221,7 +221,7 @@ btr_root_get( /*=========*/ const dict_index_t* index, /*!< in: index tree */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Checks and adjusts the root node of a tree during IMPORT TABLESPACE. @@ -231,7 +231,7 @@ dberr_t btr_root_adjust_on_import( /*======================*/ const dict_index_t* index) /*!< in: index tree */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Gets the height of the B-tree (the level of the root, when the leaf @@ -244,7 +244,7 @@ btr_height_get( /*===========*/ dict_index_t* index, /*!< in: index tree */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Gets a buffer page and declares its latching order level. */ UNIV_INLINE @@ -306,7 +306,7 @@ index_id_t btr_page_get_index_id( /*==================*/ const page_t* page) /*!< in: index page */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #ifndef UNIV_HOTBACKUP /********************************************************//** Gets the node level field in an index page. @@ -316,7 +316,7 @@ ulint btr_page_get_level_low( /*===================*/ const page_t* page) /*!< in: index page */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #define btr_page_get_level(page, mtr) btr_page_get_level_low(page) /********************************************************//** Gets the next index page number. @@ -327,7 +327,7 @@ btr_page_get_next( /*==============*/ const page_t* page, /*!< in: index page */ mtr_t* mtr) /*!< in: mini-transaction handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************//** Gets the previous index page number. @return prev page number */ @@ -337,7 +337,7 @@ btr_page_get_prev( /*==============*/ const page_t* page, /*!< in: index page */ mtr_t* mtr) /*!< in: mini-transaction handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Gets pointer to the previous user record in the tree. It is assumed that the caller has appropriate latches on the page and its neighbor. @@ -349,7 +349,7 @@ btr_get_prev_user_rec( rec_t* rec, /*!< in: record on leaf level */ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if needed, also to the previous page */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Gets pointer to the next user record in the tree. It is assumed that the caller has appropriate latches on the page and its neighbor. @@ -361,7 +361,7 @@ btr_get_next_user_rec( rec_t* rec, /*!< in: record on leaf level */ mtr_t* mtr) /*!< in: mtr holding a latch on the page, and if needed, also to the next page */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Releases the latch on a leaf page and bufferunfixes it. */ UNIV_INLINE @@ -372,7 +372,7 @@ btr_leaf_page_release( ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or BTR_MODIFY_LEAF */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Gets the child node file address in a node pointer. NOTE: the offsets array must contain all offsets for the record since @@ -386,7 +386,7 @@ btr_node_ptr_get_child_page_no( /*===========================*/ const rec_t* rec, /*!< in: node pointer record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /************************************************************//** Creates the root node for a new index tree. @return page number of the created root, FIL_NULL if did not succeed */ @@ -401,7 +401,7 @@ btr_create( index_id_t index_id,/*!< in: index id */ dict_index_t* index, /*!< in: index */ mtr_t* mtr) /*!< in: mini-transaction handle */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /************************************************************//** Frees a B-tree except the root page, which MUST be freed after this by calling btr_free_root. */ @@ -424,7 +424,7 @@ btr_free_root( or 0 for uncompressed pages */ ulint root_page_no, /*!< in: root page number */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Makes tree one level higher by splitting the root, and inserts the tuple. It is assumed that mtr contains an x-latch on the tree. @@ -447,7 +447,7 @@ btr_root_raise_and_insert( const dtuple_t* tuple, /*!< in: tuple to insert */ ulint n_ext, /*!< in: number of externally stored columns */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Reorganizes an index page. @@ -473,7 +473,7 @@ btr_page_reorganize_low( page_cur_t* cursor, /*!< in/out: page cursor */ dict_index_t* index, /*!< in: the index tree of the page */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Reorganizes an index page. @@ -492,7 +492,7 @@ btr_page_reorganize( page_cur_t* cursor, /*!< in/out: page cursor */ dict_index_t* index, /*!< in: the index tree of the page */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Decides if the page should be split at the convergence point of inserts converging to left. @@ -505,7 +505,7 @@ btr_page_get_split_rec_to_left( rec_t** split_rec)/*!< out: if split recommended, the first record on upper half page, or NULL if tuple should be first */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Decides if the page should be split at the convergence point of inserts converging to right. @@ -518,7 +518,7 @@ btr_page_get_split_rec_to_right( rec_t** split_rec)/*!< out: if split recommended, the first record on upper half page, or NULL if tuple should be first */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Splits an index page to halves and inserts the tuple. It is assumed that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is @@ -542,7 +542,7 @@ btr_page_split_and_insert( const dtuple_t* tuple, /*!< in: tuple to insert */ ulint n_ext, /*!< in: number of externally stored columns */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************//** Inserts a data tuple to a tree on a non-leaf level. It is assumed that mtr holds an x-latch on the tree. */ @@ -557,7 +557,7 @@ btr_insert_on_non_leaf_level_func( const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); # define btr_insert_on_non_leaf_level(f,i,l,t,m) \ btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m) #endif /* !UNIV_HOTBACKUP */ @@ -569,7 +569,7 @@ btr_set_min_rec_mark( /*=================*/ rec_t* rec, /*!< in/out: record */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /*************************************************************//** Deletes on the upper level the node pointer to a page. */ @@ -580,7 +580,7 @@ btr_node_ptr_delete( dict_index_t* index, /*!< in: index tree */ buf_block_t* block, /*!< in: page whose node pointer is deleted */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG /************************************************************//** Checks that the node pointer to a page is appropriate. @@ -592,7 +592,7 @@ btr_check_node_ptr( dict_index_t* index, /*!< in: index tree */ buf_block_t* block, /*!< in: index page */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ /*************************************************************//** Tries to merge the page first to the left immediate brother if such a @@ -615,7 +615,7 @@ btr_compress( ibool adjust, /*!< in: TRUE if should adjust the cursor position even if compression occurs */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Discards a page from a B-tree. This is used to remove the last record from a B-tree page: the whole page must be removed at the same time. This cannot @@ -627,7 +627,7 @@ btr_discard_page( btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on the root page */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /****************************************************************//** Parses the redo log record for setting an index record as the predefined @@ -642,7 +642,7 @@ btr_parse_set_min_rec_mark( ulint comp, /*!< in: nonzero=compact page format */ page_t* page, /*!< in: page or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ - __attribute__((nonnull(1,2), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2), warn_unused_result)); /***********************************************************//** Parses a redo log record of reorganizing a page. @return end of log record or NULL */ @@ -656,7 +656,7 @@ btr_parse_page_reorganize( bool compressed,/*!< in: true if compressed page */ buf_block_t* block, /*!< in: page to be reorganized, or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ - __attribute__((nonnull(1,2,3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3), warn_unused_result)); #ifndef UNIV_HOTBACKUP /**************************************************************//** Gets the number of pages in a B-tree. @@ -669,7 +669,7 @@ btr_get_size( ulint flag, /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */ mtr_t* mtr) /*!< in/out: mini-transaction where index is s-latched */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Allocates a new file page to be used in an index tree. NOTE: we assume that the caller has made the reservation for free extents! @@ -692,7 +692,7 @@ btr_page_alloc( mtr_t* init_mtr) /*!< in/out: mini-transaction for x-latching and initializing the page */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Frees a file page used in an index tree. NOTE: cannot free field external storage pages because the page must contain info on its level. */ @@ -703,7 +703,7 @@ btr_page_free( dict_index_t* index, /*!< in: index tree */ buf_block_t* block, /*!< in: block to be freed, x-latched */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Frees a file page used in an index tree. Can be used also to BLOB external storage pages, because the page level 0 can be given as an @@ -716,7 +716,7 @@ btr_page_free_low( buf_block_t* block, /*!< in: block to be freed, x-latched */ ulint level, /*!< in: page level */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_BTR_PRINT /*************************************************************//** Prints size info of a B-tree. */ @@ -725,7 +725,7 @@ void btr_print_size( /*===========*/ dict_index_t* index) /*!< in: index tree */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Prints directories and other info of all nodes in the index. */ UNIV_INTERN @@ -735,7 +735,7 @@ btr_print_index( dict_index_t* index, /*!< in: index */ ulint width) /*!< in: print this many entries from start and end */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* UNIV_BTR_PRINT */ /************************************************************//** Checks the size and number of fields in a record based on the definition of @@ -750,7 +750,7 @@ btr_index_rec_validate( ibool dump_on_error) /*!< in: TRUE if the function should print hex dump of record and page on error */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Checks the consistency of an index tree. @return TRUE if ok */ @@ -760,7 +760,7 @@ btr_validate_index( /*===============*/ dict_index_t* index, /*!< in: index */ const trx_t* trx) /*!< in: transaction or 0 */ - __attribute__((nonnull(1), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1), warn_unused_result)); #define BTR_N_LEAF_PAGES 1 #define BTR_TOTAL_SIZE 2 diff --git a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic index 00f50b5dcaf26..2ad01259924a6 100644 --- a/storage/innobase/include/btr0btr.ic +++ b/storage/innobase/include/btr0btr.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -159,10 +159,11 @@ ulint btr_page_get_next( /*==============*/ const page_t* page, /*!< in: index page */ - mtr_t* mtr __attribute__((unused))) + mtr_t* mtr MY_ATTRIBUTE((unused))) /*!< in: mini-transaction handle */ { - ut_ad(page && mtr); + ut_ad(page != NULL); + ut_ad(mtr != NULL); ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX) || mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_S_FIX)); @@ -181,7 +182,8 @@ btr_page_set_next( ulint next, /*!< in: next page number */ mtr_t* mtr) /*!< in: mini-transaction handle */ { - ut_ad(page && mtr); + ut_ad(page != NULL); + ut_ad(mtr != NULL); if (page_zip) { mach_write_to_4(page + FIL_PAGE_NEXT, next); @@ -199,9 +201,10 @@ ulint btr_page_get_prev( /*==============*/ const page_t* page, /*!< in: index page */ - mtr_t* mtr __attribute__((unused))) /*!< in: mini-transaction handle */ + mtr_t* mtr MY_ATTRIBUTE((unused))) /*!< in: mini-transaction handle */ { - ut_ad(page && mtr); + ut_ad(page != NULL); + ut_ad(mtr != NULL); return(mach_read_from_4(page + FIL_PAGE_PREV)); } @@ -218,7 +221,8 @@ btr_page_set_prev( ulint prev, /*!< in: previous page number */ mtr_t* mtr) /*!< in: mini-transaction handle */ { - ut_ad(page && mtr); + ut_ad(page != NULL); + ut_ad(mtr != NULL); if (page_zip) { mach_write_to_4(page + FIL_PAGE_PREV, prev); diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index f1e4406fcf70b..89b54d06a10a3 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -186,7 +186,7 @@ btr_cur_open_at_index_side_func( const char* file, /*!< in: file name */ ulint line, /*!< in: line where called */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #define btr_cur_open_at_index_side(f,i,l,c,lv,m) \ btr_cur_open_at_index_side_func(f,i,l,c,lv,__FILE__,__LINE__,m) /**********************************************************************//** @@ -235,7 +235,7 @@ btr_cur_optimistic_insert( compressed tablespace, the caller must mtr_commit(mtr) before latching any further pages */ - __attribute__((nonnull(2,3,4,5,6,7,10), warn_unused_result)); + MY_ATTRIBUTE((nonnull(2,3,4,5,6,7,10), warn_unused_result)); /*************************************************************//** Performs an insert on a page of an index tree. It is assumed that mtr holds an x-latch on the tree and on the cursor page. If the insert is @@ -266,7 +266,7 @@ btr_cur_pessimistic_insert( ulint n_ext, /*!< in: number of externally stored columns */ que_thr_t* thr, /*!< in: query thread or NULL */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull(2,3,4,5,6,7,10), warn_unused_result)); + MY_ATTRIBUTE((nonnull(2,3,4,5,6,7,10), warn_unused_result)); /*************************************************************//** See if there is enough place in the page modification log to log an update-in-place. @@ -293,7 +293,7 @@ btr_cur_update_alloc_zip_func( bool create, /*!< in: true=delete-and-insert, false=update-in-place */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifdef UNIV_DEBUG # define btr_cur_update_alloc_zip(page_zip,cursor,index,offsets,len,cr,mtr) \ btr_cur_update_alloc_zip_func(page_zip,cursor,index,offsets,len,cr,mtr) @@ -325,7 +325,7 @@ btr_cur_update_in_place( is a secondary index, the caller must mtr_commit(mtr) before latching any further pages */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /***********************************************************//** Writes a redo log record of updating a record in-place. */ UNIV_INTERN @@ -339,7 +339,7 @@ btr_cur_update_in_place_log( trx_id_t trx_id, /*!< in: transaction id */ roll_ptr_t roll_ptr, /*!< in: roll ptr */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Tries to update a record on a page in an index tree. It is assumed that mtr holds an x-latch on the page. The operation does not succeed if there is too @@ -371,7 +371,7 @@ btr_cur_optimistic_update( is a secondary index, the caller must mtr_commit(mtr) before latching any further pages */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /*************************************************************//** Performs an update of a record on a page of a tree. It is assumed that mtr holds an x-latch on the tree and on the cursor page. If the @@ -405,7 +405,7 @@ btr_cur_pessimistic_update( trx_id_t trx_id, /*!< in: transaction id */ mtr_t* mtr) /*!< in/out: mini-transaction; must be committed before latching any further pages */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /***********************************************************//** Marks a clustered index record deleted. Writes an undo log record to undo log on this delete marking. Writes in the trx id field the id @@ -422,7 +422,7 @@ btr_cur_del_mark_set_clust_rec( const ulint* offsets,/*!< in: rec_get_offsets(rec) */ que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************//** Sets a secondary index record delete mark to TRUE or FALSE. @return DB_SUCCESS, DB_LOCK_WAIT, or error number */ @@ -435,7 +435,7 @@ btr_cur_del_mark_set_sec_rec( ibool val, /*!< in: value to set */ que_thr_t* thr, /*!< in: query thread */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Tries to compress a page of the tree if it seems useful. It is assumed that mtr holds an x-latch on the tree and on the cursor page. To avoid @@ -453,7 +453,7 @@ btr_cur_compress_if_useful( ibool adjust, /*!< in: TRUE if should adjust the cursor position even if compression occurs */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************//** Removes the record on which the tree cursor is positioned. It is assumed that the mtr has an x-latch on the page where the cursor is positioned, @@ -474,7 +474,7 @@ btr_cur_optimistic_delete_func( TRUE on a leaf page of a secondary index, the mtr must be committed before latching any further pages */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); # ifdef UNIV_DEBUG # define btr_cur_optimistic_delete(cursor, flags, mtr) \ btr_cur_optimistic_delete_func(cursor, flags, mtr) @@ -510,7 +510,7 @@ btr_cur_pessimistic_delete( ulint flags, /*!< in: BTR_CREATE_FLAG or 0 */ enum trx_rb_ctx rb_ctx, /*!< in: rollback context */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** Parses a redo log record of updating a record in-place. @@ -603,7 +603,7 @@ btr_cur_disown_inherited_fields( const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ const upd_t* update, /*!< in: update vector */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull(2,3,4,5,6))); + MY_ATTRIBUTE((nonnull(2,3,4,5,6))); /** Operation code for btr_store_big_rec_extern_fields(). */ enum blob_op { @@ -623,7 +623,7 @@ ibool btr_blob_op_is_update( /*==================*/ enum blob_op op) /*!< in: operation */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*******************************************************************//** Stores the fields in big_rec_vec to the tablespace and puts pointers to @@ -648,7 +648,7 @@ btr_store_big_rec_extern_fields( mtr_t* btr_mtr, /*!< in: mtr containing the latches to the clustered index */ enum blob_op op) /*! in: operation code */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Frees the space in an externally stored field to the file space @@ -742,7 +742,7 @@ btr_push_update_extern_fields( dtuple_t* tuple, /*!< in/out: data tuple */ const upd_t* update, /*!< in: update vector */ mem_heap_t* heap) /*!< in: memory heap */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***********************************************************//** Sets a secondary index record's delete mark to the given value. This function is only used by the insert buffer merge mechanism. */ diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index cfbaacf4de319..e5b40040615da 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -155,7 +155,7 @@ btr_pcur_open_at_index_side( ulint level, /*!< in: level to search for (0=leaf) */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Gets the up_match value for a pcur after a search. @return number of matched fields at the cursor or to the right if diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h index 848bde451a01d..c95ca28057aaa 100644 --- a/storage/innobase/include/btr0sea.h +++ b/storage/innobase/include/btr0sea.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -69,7 +69,7 @@ btr_search_t* btr_search_get_info( /*================*/ dict_index_t* index) /*!< in: index */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*****************************************************************//** Creates and initializes a search info struct. @return own: search info struct */ diff --git a/storage/innobase/include/btr0types.h b/storage/innobase/include/btr0types.h index c1a4531f86151..04b69d8145cc2 100644 --- a/storage/innobase/include/btr0types.h +++ b/storage/innobase/include/btr0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -81,7 +81,7 @@ btr_blob_dbg_rbt_insert( dict_index_t* index, /*!< in/out: index tree */ const btr_blob_dbg_t* b, /*!< in: the reference */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Remove from index->blobs a reference to an off-page column. @param index the index tree @@ -94,7 +94,7 @@ btr_blob_dbg_rbt_delete( dict_index_t* index, /*!< in/out: index tree */ const btr_blob_dbg_t* b, /*!< in: the reference */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Add to index->blobs any references to off-page columns from a record. @@ -107,7 +107,7 @@ btr_blob_dbg_add_rec( dict_index_t* index, /*!< in/out: index */ const ulint* offsets,/*!< in: offsets */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Remove from index->blobs any references to off-page columns from a record. @return number of references removed */ @@ -119,7 +119,7 @@ btr_blob_dbg_remove_rec( dict_index_t* index, /*!< in/out: index */ const ulint* offsets,/*!< in: offsets */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Count and add to index->blobs any references to off-page columns from records on a page. @@ -131,7 +131,7 @@ btr_blob_dbg_add( const page_t* page, /*!< in: rewritten page */ dict_index_t* index, /*!< in/out: index */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Count and remove from index->blobs any references to off-page columns from records on a page. @@ -144,7 +144,7 @@ btr_blob_dbg_remove( const page_t* page, /*!< in: b-tree page */ dict_index_t* index, /*!< in/out: index */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Restore in index->blobs any references to off-page columns Used when page reorganize fails due to compressed page overflow. */ @@ -156,7 +156,7 @@ btr_blob_dbg_restore( const page_t* page, /*!< in: copy of original page */ dict_index_t* index, /*!< in/out: index */ const char* ctx) /*!< in: context (for logging) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Operation that processes the BLOB references of an index record @param[in] rec record on index page @@ -180,7 +180,7 @@ btr_blob_dbg_op( dict_index_t* index, /*!< in/out: index */ const char* ctx, /*!< in: context (for logging) */ const btr_blob_dbg_op_f op) /*!< in: operation on records */ - __attribute__((nonnull(1,3,4,5))); + MY_ATTRIBUTE((nonnull(1,3,4,5))); #else /* UNIV_BLOB_DEBUG */ # define btr_blob_dbg_add_rec(rec, index, offsets, ctx) ((void) 0) # define btr_blob_dbg_add(page, index, ctx) ((void) 0) diff --git a/storage/innobase/include/buf0buddy.h b/storage/innobase/include/buf0buddy.h index fab9a4b828b88..7fc4408505de4 100644 --- a/storage/innobase/include/buf0buddy.h +++ b/storage/innobase/include/buf0buddy.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -54,7 +54,7 @@ buf_buddy_alloc( storage was allocated from the LRU list and buf_pool->mutex was temporarily released */ - __attribute__((malloc, nonnull)); + MY_ATTRIBUTE((malloc, nonnull)); /**********************************************************************//** Deallocate a block. */ @@ -68,7 +68,7 @@ buf_buddy_free( be pointed to by the buffer pool */ ulint size) /*!< in: block size, up to UNIV_PAGE_SIZE */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_NONINL # include "buf0buddy.ic" diff --git a/storage/innobase/include/buf0buddy.ic b/storage/innobase/include/buf0buddy.ic index be2f950162d80..4352ebe894510 100644 --- a/storage/innobase/include/buf0buddy.ic +++ b/storage/innobase/include/buf0buddy.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -50,7 +50,7 @@ buf_buddy_alloc_low( allocated from the LRU list and buf_pool->mutex was temporarily released */ - __attribute__((malloc, nonnull)); + MY_ATTRIBUTE((malloc, nonnull)); /**********************************************************************//** Deallocate a block. */ @@ -63,7 +63,7 @@ buf_buddy_free_low( pointed to by the buffer pool */ ulint i) /*!< in: index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Get the index of buf_pool->zip_free[] for a given block size. diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index b669bd203e03b..50c54e5580b4f 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -258,7 +258,7 @@ buf_relocate( buf_page_get_state(bpage) must be BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */ buf_page_t* dpage) /*!< in/out: destination control block */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Gets the current size of buffer buf_pool in bytes. @return size in bytes */ @@ -289,7 +289,7 @@ UNIV_INLINE buf_page_t* buf_page_alloc_descriptor(void) /*===========================*/ - __attribute__((malloc)); + MY_ATTRIBUTE((malloc)); /********************************************************************//** Free a buf_page_t descriptor. */ UNIV_INLINE @@ -297,7 +297,7 @@ void buf_page_free_descriptor( /*=====================*/ buf_page_t* bpage) /*!< in: bpage descriptor to free. */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Allocates a buffer block. @@ -534,7 +534,7 @@ ulint buf_page_get_freed_page_clock( /*==========================*/ const buf_page_t* bpage) /*!< in: block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /********************************************************************//** Reads the freed_page_clock of a buffer block. @return freed_page_clock */ @@ -543,7 +543,7 @@ ulint buf_block_get_freed_page_clock( /*===========================*/ const buf_block_t* block) /*!< in: block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /********************************************************************//** Tells if a block is still close enough to the MRU end of the LRU list @@ -606,7 +606,7 @@ buf_block_buf_fix_inc_func( ulint line, /*!< in: line */ # endif /* UNIV_SYNC_DEBUG */ buf_block_t* block) /*!< in/out: block to bufferfix */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Increments the bufferfix count. */ @@ -652,7 +652,7 @@ buf_page_is_corrupted( const byte* read_buf, /*!< in: a database page */ ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Checks if a page is all zeroes. @return TRUE if the page is all zeroes */ @@ -682,7 +682,7 @@ ulint buf_block_get_lock_hash_val( /*========================*/ const buf_block_t* block) /*!< in: block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); #ifdef UNIV_DEBUG /*********************************************************************//** Finds a block in the buffer pool that points to a @@ -743,7 +743,7 @@ buf_page_print( ulint flags) /*!< in: 0 or BUF_PAGE_PRINT_NO_CRASH or BUF_PAGE_PRINT_NO_FULL */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /********************************************************************//** Decompress a block. @return TRUE if successful */ @@ -870,7 +870,7 @@ enum buf_page_state buf_block_get_state( /*================*/ const buf_block_t* block) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Sets the state of a block. */ UNIV_INLINE @@ -895,7 +895,7 @@ ibool buf_page_in_file( /*=============*/ const buf_page_t* bpage) /*!< in: pointer to control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); #ifndef UNIV_HOTBACKUP /*********************************************************************//** Determines if a block should be on unzip_LRU list. @@ -905,7 +905,7 @@ ibool buf_page_belongs_to_unzip_LRU( /*==========================*/ const buf_page_t* bpage) /*!< in: pointer to control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the mutex of a block. @@ -915,7 +915,7 @@ ib_mutex_t* buf_page_get_mutex( /*===============*/ const buf_page_t* bpage) /*!< in: pointer to control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Get the flush type of a page. @@ -925,7 +925,7 @@ buf_flush_t buf_page_get_flush_type( /*====================*/ const buf_page_t* bpage) /*!< in: buffer page */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Set the flush type of a page. */ UNIV_INLINE @@ -951,7 +951,7 @@ enum buf_io_fix buf_page_get_io_fix( /*================*/ const buf_page_t* bpage) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the io_fix state of a block. @return io_fix state */ @@ -960,7 +960,7 @@ enum buf_io_fix buf_block_get_io_fix( /*================*/ const buf_block_t* block) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Sets the io_fix state of a block. */ UNIV_INLINE @@ -1006,7 +1006,7 @@ ibool buf_page_can_relocate( /*==================*/ const buf_page_t* bpage) /*!< control block being relocated */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Determine if a block has been flagged old. @@ -1016,7 +1016,7 @@ ibool buf_page_is_old( /*============*/ const buf_page_t* bpage) /*!< in: control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Flag a block old. */ UNIV_INLINE @@ -1033,7 +1033,7 @@ unsigned buf_page_is_accessed( /*=================*/ const buf_page_t* bpage) /*!< in: control block */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************************//** Flag a block accessed. */ UNIV_INLINE @@ -1041,7 +1041,7 @@ void buf_page_set_accessed( /*==================*/ buf_page_t* bpage) /*!< in/out: control block */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Gets the buf_block_t handle of a buffered file block if an uncompressed page frame exists, or NULL. Note: even though bpage is not declared a @@ -1052,7 +1052,7 @@ buf_block_t* buf_page_get_block( /*===============*/ buf_page_t* bpage) /*!< in: control block, or NULL */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); #endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_DEBUG /*********************************************************************//** @@ -1063,7 +1063,7 @@ buf_frame_t* buf_block_get_frame( /*================*/ const buf_block_t* block) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); #else /* UNIV_DEBUG */ # define buf_block_get_frame(block) (block)->frame #endif /* UNIV_DEBUG */ @@ -1075,7 +1075,7 @@ ulint buf_page_get_space( /*===============*/ const buf_page_t* bpage) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the space id of a block. @return space id */ @@ -1084,7 +1084,7 @@ ulint buf_block_get_space( /*================*/ const buf_block_t* block) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the page number of a block. @return page number */ @@ -1093,7 +1093,7 @@ ulint buf_page_get_page_no( /*=================*/ const buf_page_t* bpage) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the page number of a block. @return page number */ @@ -1102,7 +1102,7 @@ ulint buf_block_get_page_no( /*==================*/ const buf_block_t* block) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the compressed page size of a block. @return compressed page size, or 0 */ @@ -1111,7 +1111,7 @@ ulint buf_page_get_zip_size( /*==================*/ const buf_page_t* bpage) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the compressed page size of a block. @return compressed page size, or 0 */ @@ -1120,7 +1120,7 @@ ulint buf_block_get_zip_size( /*===================*/ const buf_block_t* block) /*!< in: pointer to the control block */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /*********************************************************************//** Gets the compressed page descriptor corresponding to an uncompressed page if applicable. */ @@ -1209,7 +1209,7 @@ buf_page_address_fold( /*==================*/ ulint space, /*!< in: space id */ ulint offset) /*!< in: offset of the page within space */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /********************************************************************//** Calculates the index of a buffer pool to the buf_pool[] array. @return the position of the buffer pool in buf_pool[] */ @@ -1218,7 +1218,7 @@ ulint buf_pool_index( /*===========*/ const buf_pool_t* buf_pool) /*!< in: buffer pool */ - __attribute__((nonnull, const)); + MY_ATTRIBUTE((nonnull, const)); /******************************************************************//** Returns the buffer pool instance given a page instance @return buf_pool */ @@ -1358,7 +1358,7 @@ buf_pool_watch_is_sentinel( /*=======================*/ buf_pool_t* buf_pool, /*!< buffer pool instance */ const buf_page_t* bpage) /*!< in: block */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /****************************************************************//** Add watch for the given page to be read in. Caller must have the buffer pool @return NULL if watch set, block if the page is in the buffer pool */ @@ -1369,7 +1369,7 @@ buf_pool_watch_set( ulint space, /*!< in: space id */ ulint offset, /*!< in: page number */ ulint fold) /*!< in: buf_page_address_fold(space, offset) */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /****************************************************************//** Stop watching if the page has been read in. buf_pool_watch_set(space,offset) must have returned NULL before. */ @@ -1390,7 +1390,7 @@ buf_pool_watch_occurred( /*====================*/ ulint space, /*!< in: space id */ ulint offset) /*!< in: page number */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /********************************************************************//** Get total buffer pool statistics. */ UNIV_INTERN diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index f116720574b6f..0c5812f802c77 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -85,7 +85,7 @@ buf_flush_page_try( /*===============*/ buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */ buf_block_t* block) /*!< in/out: buffer control block */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); # endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ /*******************************************************************//** This utility flushes dirty blocks from the end of the flush list of @@ -254,7 +254,7 @@ buf_flush_ready_for_flush( buf_page_t* bpage, /*!< in: buffer control block, must be buf_page_in_file(bpage) */ buf_flush_t flush_type)/*!< in: type of flush */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #ifdef UNIV_DEBUG /******************************************************************//** diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index ecdaef685a1b9..b5d3fe0209770 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -93,7 +93,7 @@ buf_LRU_free_page( buf_page_t* bpage, /*!< in: block to be freed */ bool zip) /*!< in: true if should remove also the compressed page of an uncompressed page */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Try to free a replaceable block. @return TRUE if found and freed */ @@ -105,7 +105,7 @@ buf_LRU_scan_and_free_block( ibool scan_all) /*!< in: scan whole LRU list if TRUE, otherwise scan only 'old' blocks. */ - __attribute__((nonnull,warn_unused_result)); + MY_ATTRIBUTE((nonnull,warn_unused_result)); /******************************************************************//** Returns a free block from the buf_pool. The block is taken off the free list. If it is empty, returns NULL. @@ -146,7 +146,7 @@ buf_block_t* buf_LRU_get_free_block( /*===================*/ buf_pool_t* buf_pool) /*!< in/out: buffer pool instance */ - __attribute__((nonnull,warn_unused_result)); + MY_ATTRIBUTE((nonnull,warn_unused_result)); /******************************************************************//** Determines if the unzip_LRU list should be used for evicting a victim instead of the general LRU list. @@ -229,7 +229,7 @@ buf_LRU_free_one_page( buf_page_t* bpage) /*!< in/out: block, must contain a file page and be in a state where it can be freed; there may or may not be a hash index to the page */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /**********************************************************************//** diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h index a548c7b89b3d7..1d954bfc07cbe 100644 --- a/storage/innobase/include/data0data.h +++ b/storage/innobase/include/data0data.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -46,7 +46,7 @@ dtype_t* dfield_get_type( /*============*/ const dfield_t* field) /*!< in: SQL data field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets pointer to the data in a field. @return pointer to data */ @@ -55,7 +55,7 @@ void* dfield_get_data( /*============*/ const dfield_t* field) /*!< in: field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ # define dfield_get_type(field) (&(field)->type) # define dfield_get_data(field) ((field)->data) @@ -68,7 +68,7 @@ dfield_set_type( /*============*/ dfield_t* field, /*!< in: SQL data field */ const dtype_t* type) /*!< in: pointer to data type struct */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Gets length of field data. @return length of data; UNIV_SQL_NULL if SQL null data */ @@ -77,7 +77,7 @@ ulint dfield_get_len( /*===========*/ const dfield_t* field) /*!< in: field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Sets length in a field. */ UNIV_INLINE @@ -86,7 +86,7 @@ dfield_set_len( /*===========*/ dfield_t* field, /*!< in: field */ ulint len) /*!< in: length or UNIV_SQL_NULL */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Determines if a field is SQL NULL @return nonzero if SQL null data */ @@ -95,7 +95,7 @@ ulint dfield_is_null( /*===========*/ const dfield_t* field) /*!< in: field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Determines if a field is externally stored @return nonzero if externally stored */ @@ -104,7 +104,7 @@ ulint dfield_is_ext( /*==========*/ const dfield_t* field) /*!< in: field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Sets the "external storage" flag */ UNIV_INLINE @@ -112,7 +112,7 @@ void dfield_set_ext( /*===========*/ dfield_t* field) /*!< in/out: field */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Sets pointer to the data and length in a field. */ UNIV_INLINE @@ -122,7 +122,7 @@ dfield_set_data( dfield_t* field, /*!< in: field */ const void* data, /*!< in: data */ ulint len) /*!< in: length or UNIV_SQL_NULL */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /*********************************************************************//** Sets a data field to SQL NULL. */ UNIV_INLINE @@ -130,7 +130,7 @@ void dfield_set_null( /*============*/ dfield_t* field) /*!< in/out: field */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Writes an SQL null field full of zeros. */ UNIV_INLINE @@ -139,7 +139,7 @@ data_write_sql_null( /*================*/ byte* data, /*!< in: pointer to a buffer of size len */ ulint len) /*!< in: SQL null size in bytes */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Copies the data and len fields. */ UNIV_INLINE @@ -148,7 +148,7 @@ dfield_copy_data( /*=============*/ dfield_t* field1, /*!< out: field to copy to */ const dfield_t* field2) /*!< in: field to copy from */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Copies a data field to another. */ UNIV_INLINE @@ -157,7 +157,7 @@ dfield_copy( /*========*/ dfield_t* field1, /*!< out: field to copy to */ const dfield_t* field2) /*!< in: field to copy from */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Copies the data pointed to by a data field. */ UNIV_INLINE @@ -166,7 +166,7 @@ dfield_dup( /*=======*/ dfield_t* field, /*!< in/out: data field */ mem_heap_t* heap) /*!< in: memory heap where allocated */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /*********************************************************************//** Tests if two data fields are equal. @@ -181,7 +181,7 @@ dfield_datas_are_binary_equal( const dfield_t* field2, /*!< in: field */ ulint len) /*!< in: maximum prefix to compare, or 0 to compare the whole field length */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Tests if dfield data length and content is equal to the given. @return TRUE if equal */ @@ -192,7 +192,7 @@ dfield_data_is_binary_equal( const dfield_t* field, /*!< in: field */ ulint len, /*!< in: data length or UNIV_SQL_NULL */ const byte* data) /*!< in: data */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /*********************************************************************//** Gets number of fields in a data tuple. @@ -202,7 +202,7 @@ ulint dtuple_get_n_fields( /*================*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifdef UNIV_DEBUG /*********************************************************************//** Gets nth field of a tuple. @@ -224,7 +224,7 @@ ulint dtuple_get_info_bits( /*=================*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Sets info bits in a data tuple. */ UNIV_INLINE @@ -233,7 +233,7 @@ dtuple_set_info_bits( /*=================*/ dtuple_t* tuple, /*!< in: tuple */ ulint info_bits) /*!< in: info bits */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Gets number of fields used in record comparisons. @return number of fields used in comparisons in rem0cmp.* */ @@ -242,7 +242,7 @@ ulint dtuple_get_n_fields_cmp( /*====================*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets number of fields used in record comparisons. */ UNIV_INLINE @@ -252,7 +252,7 @@ dtuple_set_n_fields_cmp( dtuple_t* tuple, /*!< in: tuple */ ulint n_fields_cmp) /*!< in: number of fields used in comparisons in rem0cmp.* */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /* Estimate the number of bytes that are going to be allocated when creating a new dtuple_t object */ @@ -272,7 +272,7 @@ dtuple_create_from_mem( void* buf, /*!< in, out: buffer to use */ ulint buf_size, /*!< in: buffer size */ ulint n_fields) /*!< in: number of fields */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************//** Creates a data tuple to a memory heap. The default value for number @@ -286,7 +286,7 @@ dtuple_create( is created, DTUPLE_EST_ALLOC(n_fields) bytes will be allocated from this heap */ ulint n_fields)/*!< in: number of fields */ - __attribute__((nonnull, malloc)); + MY_ATTRIBUTE((nonnull, malloc)); /*********************************************************************//** Sets number of fields used in a tuple. Normally this is set in @@ -297,7 +297,7 @@ dtuple_set_n_fields( /*================*/ dtuple_t* tuple, /*!< in: tuple */ ulint n_fields) /*!< in: number of fields */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Copies a data tuple to another. This is a shallow copy; if a deep copy is desired, dfield_dup() will have to be invoked on each field. @@ -309,7 +309,7 @@ dtuple_copy( const dtuple_t* tuple, /*!< in: tuple to copy from */ mem_heap_t* heap) /*!< in: memory heap where the tuple is created */ - __attribute__((nonnull, malloc)); + MY_ATTRIBUTE((nonnull, malloc)); /**********************************************************//** The following function returns the sum of data lengths of a tuple. The space occupied by the field structs or the tuple struct is not counted. @@ -320,7 +320,7 @@ dtuple_get_data_size( /*=================*/ const dtuple_t* tuple, /*!< in: typed data tuple */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Computes the number of externally stored fields in a data tuple. @return number of fields */ @@ -329,7 +329,7 @@ ulint dtuple_get_n_ext( /*=============*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /************************************************************//** Compare two data tuples, respecting the collation of character fields. @return 1, 0 , -1 if tuple1 is greater, equal, less, respectively, @@ -340,7 +340,7 @@ dtuple_coll_cmp( /*============*/ const dtuple_t* tuple1, /*!< in: tuple 1 */ const dtuple_t* tuple2) /*!< in: tuple 2 */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /************************************************************//** Folds a prefix given as the number of fields of a tuple. @return the folded value */ @@ -353,7 +353,7 @@ dtuple_fold( ulint n_bytes,/*!< in: number of bytes to fold in an incomplete last field */ index_id_t tree_id)/*!< in: index tree id */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /*******************************************************************//** Sets types of fields binary in a tuple. */ UNIV_INLINE @@ -362,7 +362,7 @@ dtuple_set_types_binary( /*====================*/ dtuple_t* tuple, /*!< in: data tuple */ ulint n) /*!< in: number of fields to set */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Checks if a dtuple contains an SQL null value. @return TRUE if some field is SQL null */ @@ -371,7 +371,7 @@ ibool dtuple_contains_null( /*=================*/ const dtuple_t* tuple) /*!< in: dtuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************//** Checks that a data field is typed. Asserts an error if not. @return TRUE if ok */ @@ -380,7 +380,7 @@ ibool dfield_check_typed( /*===============*/ const dfield_t* field) /*!< in: data field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************//** Checks that a data tuple is typed. Asserts an error if not. @return TRUE if ok */ @@ -389,7 +389,7 @@ ibool dtuple_check_typed( /*===============*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************//** Checks that a data tuple is typed. @return TRUE if ok */ @@ -398,7 +398,7 @@ ibool dtuple_check_typed_no_assert( /*=========================*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifdef UNIV_DEBUG /**********************************************************//** Validates the consistency of a tuple which must be complete, i.e, @@ -409,7 +409,7 @@ ibool dtuple_validate( /*============*/ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ /*************************************************************//** Pretty prints a dfield value according to its data type. */ @@ -418,7 +418,7 @@ void dfield_print( /*=========*/ const dfield_t* dfield) /*!< in: dfield */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Pretty prints a dfield value according to its data type. Also the hex string is printed if a string contains non-printable characters. */ @@ -427,7 +427,7 @@ void dfield_print_also_hex( /*==================*/ const dfield_t* dfield) /*!< in: dfield */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************//** The following function prints the contents of a tuple. */ UNIV_INTERN @@ -436,7 +436,7 @@ dtuple_print( /*=========*/ FILE* f, /*!< in: output stream */ const dtuple_t* tuple) /*!< in: tuple */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Moves parts of long fields in entry to the big record vector so that the size of tuple drops below the maximum record size allowed in the @@ -453,7 +453,7 @@ dtuple_convert_big_rec( dtuple_t* entry, /*!< in/out: index entry */ ulint* n_ext) /*!< in/out: number of externally stored columns */ - __attribute__((nonnull, malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); /**************************************************************//** Puts back to entry the data stored in vector. Note that to ensure the fields in entry can accommodate the data, vector must have been created @@ -466,7 +466,7 @@ dtuple_convert_back_big_rec( dtuple_t* entry, /*!< in: entry whose data was put to vector */ big_rec_t* vector) /*!< in, own: big rec vector; it is freed in this function */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Frees the memory in a big rec vector. */ UNIV_INLINE @@ -475,7 +475,7 @@ dtuple_big_rec_free( /*================*/ big_rec_t* vector) /*!< in, own: big rec vector; it is freed in this function */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*######################################################################*/ diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic index 6937d55d211c3..11499ab928c26 100644 --- a/storage/innobase/include/data0data.ic +++ b/storage/innobase/include/data0data.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -56,7 +56,8 @@ dfield_set_type( dfield_t* field, /*!< in: SQL data field */ const dtype_t* type) /*!< in: pointer to data type struct */ { - ut_ad(field && type); + ut_ad(field != NULL); + ut_ad(type != NULL); field->type = *type; } @@ -194,7 +195,8 @@ dfield_copy_data( dfield_t* field1, /*!< out: field to copy to */ const dfield_t* field2) /*!< in: field to copy from */ { - ut_ad(field1 && field2); + ut_ad(field1 != NULL); + ut_ad(field2 != NULL); field1->data = field2->data; field1->len = field2->len; diff --git a/storage/innobase/include/dict0boot.h b/storage/innobase/include/dict0boot.h index a994c9d8ff132..477e1150f437b 100644 --- a/storage/innobase/include/dict0boot.h +++ b/storage/innobase/include/dict0boot.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -95,7 +95,7 @@ UNIV_INTERN dberr_t dict_boot(void) /*===========*/ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*****************************************************************//** Creates and initializes the data dictionary at the server bootstrap. @@ -104,7 +104,7 @@ UNIV_INTERN dberr_t dict_create(void) /*=============*/ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*********************************************************************//** Check if a table id belongs to system table. @@ -114,7 +114,7 @@ bool dict_is_sys_table( /*==============*/ table_id_t id) /*!< in: table id to check */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /* Space id and page no where the dictionary header resides */ #define DICT_HDR_SPACE 0 /* the SYSTEM tablespace */ diff --git a/storage/innobase/include/dict0crea.h b/storage/innobase/include/dict0crea.h index 67eab9058da55..6146917469a84 100644 --- a/storage/innobase/include/dict0crea.h +++ b/storage/innobase/include/dict0crea.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -123,7 +123,7 @@ dict_create_add_foreign_id( incremented if used */ const char* name, /*!< in: table name */ dict_foreign_t* foreign)/*!< in/out: foreign key */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Adds the given set of foreign key objects to the dictionary tables in the database. This function does not modify the dictionary cache. The @@ -142,7 +142,7 @@ dict_create_add_foreigns_to_dictionary( const dict_foreign_set& local_fk_set, const dict_table_t* table, trx_t* trx) - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /****************************************************************//** Creates the tablespaces and datafiles system tables inside InnoDB at server bootstrap or server start if they are not found or are @@ -177,7 +177,7 @@ dict_create_add_foreign_to_dictionary( const char* name, /*!< in: table name */ const dict_foreign_t* foreign,/*!< in: foreign key */ trx_t* trx) /*!< in/out: dictionary transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /* Table create node structure */ struct tab_node_t{ diff --git a/storage/innobase/include/dict0crea.ic b/storage/innobase/include/dict0crea.ic index 2d0d9dcb85841..1cbaa47032b55 100644 --- a/storage/innobase/include/dict0crea.ic +++ b/storage/innobase/include/dict0crea.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -33,7 +33,7 @@ UNIV_INTERN bool row_is_mysql_tmp_table_name( /*========================*/ - const char* name) __attribute__((warn_unused_result)); + const char* name) MY_ATTRIBUTE((warn_unused_result)); /*!< in: table name in the form 'database/tablename' */ diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index dea4a9a2a508d..533ddc3d43bee 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -53,7 +53,7 @@ void dict_casedn_str( /*============*/ char* a) /*!< in/out: string to put in lower case */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Get the database name length in a table name. @return database name length */ @@ -63,7 +63,7 @@ dict_get_db_name_len( /*=================*/ const char* name) /*!< in: table name in the form dbname '/' tablename */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Open a table from its database and table name, this is currently used by foreign constraint parser to get the referenced table. @@ -107,7 +107,7 @@ dict_remove_db_name( /*================*/ const char* name) /*!< in: table name in the form dbname '/' tablename */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Operation to perform when opening a table */ enum dict_table_op_t { @@ -130,7 +130,7 @@ dict_table_open_on_id( table_id_t table_id, /*!< in: table id */ ibool dict_locked, /*!< in: TRUE=data dictionary locked */ dict_table_op_t table_op) /*!< in: operation to perform */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /********************************************************************//** Decrements the count of open handles to a table. */ UNIV_INTERN @@ -142,7 +142,7 @@ dict_table_close( ibool try_drop) /*!< in: TRUE=try to drop any orphan indexes after an aborted online index creation */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Inits the data dictionary module. */ UNIV_INTERN @@ -167,7 +167,7 @@ ulint dict_col_get_mbminlen( /*==================*/ const dict_col_t* col) /*!< in: column */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets the maximum number of bytes per character. @return maximum multi-byte char size, in bytes */ @@ -176,7 +176,7 @@ ulint dict_col_get_mbmaxlen( /*==================*/ const dict_col_t* col) /*!< in: column */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Sets the minimum and maximum number of bytes per character. */ UNIV_INLINE @@ -188,7 +188,7 @@ dict_col_set_mbminmaxlen( character size, in bytes */ ulint mbmaxlen) /*!< in: minimum multi-byte character size, in bytes */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Gets the column data type. */ UNIV_INLINE @@ -197,7 +197,7 @@ dict_col_copy_type( /*===============*/ const dict_col_t* col, /*!< in: column */ dtype_t* type) /*!< out: data type */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Determine bytes of column prefix to be stored in the undo log. Please note if the table format is UNIV_FORMAT_A (< UNIV_FORMAT_B), no prefix @@ -210,7 +210,7 @@ dict_max_field_len_store_undo( dict_table_t* table, /*!< in: table */ const dict_col_t* col) /*!< in: column which index prefix is based on */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_DEBUG /*********************************************************************//** @@ -222,7 +222,7 @@ dict_col_type_assert_equal( /*=======================*/ const dict_col_t* col, /*!< in: column */ const dtype_t* type) /*!< in: data type */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ #ifndef UNIV_HOTBACKUP /***********************************************************************//** @@ -233,7 +233,7 @@ ulint dict_col_get_min_size( /*==================*/ const dict_col_t* col) /*!< in: column */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** Returns the maximum size of the column. @return maximum size */ @@ -242,7 +242,7 @@ ulint dict_col_get_max_size( /*==================*/ const dict_col_t* col) /*!< in: column */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** Returns the size of a fixed size column, 0 if not a fixed size column. @return fixed size, or 0 */ @@ -252,7 +252,7 @@ dict_col_get_fixed_size( /*====================*/ const dict_col_t* col, /*!< in: column */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. For fixed length types it is the fixed length of the type, otherwise 0. @@ -263,7 +263,7 @@ dict_col_get_sql_null_size( /*=======================*/ const dict_col_t* col, /*!< in: column */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets the column number. @return col->ind, table column position (starting from 0) */ @@ -272,7 +272,7 @@ ulint dict_col_get_no( /*============*/ const dict_col_t* col) /*!< in: column */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets the column position in the clustered index. */ UNIV_INLINE @@ -281,7 +281,7 @@ dict_col_get_clust_pos( /*===================*/ const dict_col_t* col, /*!< in: table column */ const dict_index_t* clust_index) /*!< in: clustered index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /****************************************************************//** If the given column name is reserved for InnoDB system columns, return TRUE. @@ -291,7 +291,7 @@ ibool dict_col_name_is_reserved( /*======================*/ const char* name) /*!< in: column name */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Acquire the autoinc lock. */ UNIV_INTERN @@ -299,7 +299,7 @@ void dict_table_autoinc_lock( /*====================*/ dict_table_t* table) /*!< in/out: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Unconditionally set the autoinc counter. */ UNIV_INTERN @@ -308,7 +308,7 @@ dict_table_autoinc_initialize( /*==========================*/ dict_table_t* table, /*!< in/out: table */ ib_uint64_t value) /*!< in: next value to assign to a row */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Store autoinc value when the table is evicted. @param[in] table table evicted */ @@ -333,7 +333,7 @@ ib_uint64_t dict_table_autoinc_read( /*====================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Updates the autoinc counter if the value supplied is greater than the current value. */ @@ -344,7 +344,7 @@ dict_table_autoinc_update_if_greater( dict_table_t* table, /*!< in/out: table */ ib_uint64_t value) /*!< in: value which was assigned to a row */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Release the autoinc lock. */ UNIV_INTERN @@ -352,7 +352,7 @@ void dict_table_autoinc_unlock( /*======================*/ dict_table_t* table) /*!< in/out: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Adds system columns to a table object. */ @@ -362,7 +362,7 @@ dict_table_add_system_columns( /*==========================*/ dict_table_t* table, /*!< in/out: table */ mem_heap_t* heap) /*!< in: temporary heap */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /**********************************************************************//** Adds a table object to the dictionary cache. */ @@ -373,7 +373,7 @@ dict_table_add_to_cache( dict_table_t* table, /*!< in: table */ ibool can_be_evicted, /*!< in: TRUE if can be evicted*/ mem_heap_t* heap) /*!< in: temporary heap */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Removes a table object from the dictionary cache. */ UNIV_INTERN @@ -381,7 +381,7 @@ void dict_table_remove_from_cache( /*=========================*/ dict_table_t* table) /*!< in, own: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Removes a table object from the dictionary cache. */ UNIV_INTERN @@ -404,7 +404,7 @@ dict_table_rename_in_cache( /*!< in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Removes an index from the dictionary cache. */ UNIV_INTERN @@ -413,7 +413,7 @@ dict_index_remove_from_cache( /*=========================*/ dict_table_t* table, /*!< in/out: table */ dict_index_t* index) /*!< in, own: index */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Change the id of a table object in the dictionary cache. This is used in DISCARD TABLESPACE. */ @@ -423,7 +423,7 @@ dict_table_change_id_in_cache( /*==========================*/ dict_table_t* table, /*!< in/out: table object already in cache */ table_id_t new_id) /*!< in: new id to set */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Removes a foreign constraint struct from the dictionary cache. */ UNIV_INTERN @@ -431,7 +431,7 @@ void dict_foreign_remove_from_cache( /*===========================*/ dict_foreign_t* foreign) /*!< in, own: foreign constraint */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Adds a foreign key constraint object to the dictionary cache. May free the object if there already is an object with the same identifier in. @@ -452,7 +452,7 @@ dict_foreign_add_to_cache( compatibility */ dict_err_ignore_t ignore_err) /*!< in: error to be ignored */ - __attribute__((nonnull(1), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /*********************************************************************//** Checks if a table is referenced by foreign keys. @return TRUE if table is referenced by a foreign key */ @@ -461,7 +461,7 @@ ibool dict_table_is_referenced_by_foreign_key( /*====================================*/ const dict_table_t* table) /*!< in: InnoDB table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Replace the index passed in with another equivalent index in the foreign key lists of the table. @@ -475,7 +475,7 @@ dict_foreign_replace_index( /*!< in: column names, or NULL to use table->col_names */ const dict_index_t* index) /*!< in: index to be replaced */ - __attribute__((nonnull(1,3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,3), warn_unused_result)); /**********************************************************************//** Determines whether a string starts with the specified keyword. @return TRUE if str starts with keyword */ @@ -486,7 +486,7 @@ dict_str_starts_with_keyword( THD* thd, /*!< in: MySQL thread handle */ const char* str, /*!< in: string to scan for keyword */ const char* keyword) /*!< in: keyword to look for */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function @@ -515,7 +515,7 @@ dict_create_foreign_constraints( ibool reject_fks) /*!< in: if TRUE, fail with error code DB_CANNOT_ADD_CONSTRAINT if any foreign keys are found. */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. @return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the @@ -532,7 +532,7 @@ dict_foreign_parse_drop_constraints( to drop */ const char*** constraints_to_drop) /*!< out: id's of the constraints to drop */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Returns a table object and increments its open handle count. NOTE! This is a high-level function to be used mainly from outside the @@ -551,7 +551,7 @@ dict_table_open_on_name( dict_err_ignore_t ignore_err) /*!< in: error to be ignored when loading the table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Tries to find an index whose first fields are the columns in the array, @@ -580,7 +580,7 @@ dict_foreign_find_index( /*!< in: nonzero if none of the columns must be declared NOT NULL */ - __attribute__((nonnull(1,3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,3), warn_unused_result)); /**********************************************************************//** Returns a column's name. @return column name. NOTE: not guaranteed to stay valid if table is @@ -591,7 +591,7 @@ dict_table_get_col_name( /*====================*/ const dict_table_t* table, /*!< in: table */ ulint col_nr) /*!< in: column number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Prints a table data. */ UNIV_INTERN @@ -599,7 +599,7 @@ void dict_table_print( /*=============*/ dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Outputs info on foreign keys of a table. */ UNIV_INTERN @@ -613,7 +613,7 @@ dict_print_info_on_foreign_keys( FILE* file, /*!< in: file where to print */ trx_t* trx, /*!< in: transaction */ dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Outputs info on a foreign key of a table in a format suitable for CREATE TABLE. */ @@ -625,7 +625,7 @@ dict_print_info_on_foreign_key_in_create_format( trx_t* trx, /*!< in: transaction */ dict_foreign_t* foreign, /*!< in: foreign key constraint */ ibool add_newline) /*!< in: whether to add a newline */ - __attribute__((nonnull(1,3))); + MY_ATTRIBUTE((nonnull(1,3))); /********************************************************************//** Displays the names of the index and the table. */ UNIV_INTERN @@ -635,7 +635,7 @@ dict_index_name_print( FILE* file, /*!< in: output stream */ const trx_t* trx, /*!< in: transaction */ const dict_index_t* index) /*!< in: index to print */ - __attribute__((nonnull(1,3))); + MY_ATTRIBUTE((nonnull(1,3))); /*********************************************************************//** Tries to find an index whose first fields are the columns in the array, in the same order and is not marked for deletion and is not the same @@ -664,7 +664,7 @@ dict_foreign_qualify_index( /*!< in: nonzero if none of the columns must be declared NOT NULL */ - __attribute__((nonnull(1,3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,3), warn_unused_result)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the first index on the table (the clustered index). @@ -674,7 +674,7 @@ dict_index_t* dict_table_get_first_index( /*=======================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the last index on the table. @return index, NULL if none exists */ @@ -683,7 +683,7 @@ dict_index_t* dict_table_get_last_index( /*=======================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the next index on the table. @return index, NULL if none left */ @@ -692,7 +692,7 @@ dict_index_t* dict_table_get_next_index( /*======================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ # define dict_table_get_first_index(table) UT_LIST_GET_FIRST((table)->indexes) # define dict_table_get_last_index(table) UT_LIST_GET_LAST((table)->indexes) @@ -721,7 +721,7 @@ ulint dict_index_is_clust( /*================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Check whether the index is unique. @return nonzero for unique index, zero for other indexes */ @@ -730,7 +730,7 @@ ulint dict_index_is_unique( /*=================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Check whether the index is the insert buffer tree. @return nonzero for insert buffer, zero for other indexes */ @@ -739,7 +739,7 @@ ulint dict_index_is_ibuf( /*===============*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Check whether the index is a secondary index or the insert buffer tree. @return nonzero for insert buffer, zero for other indexes */ @@ -748,7 +748,7 @@ ulint dict_index_is_sec_or_ibuf( /*======================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /************************************************************************ Gets the all the FTS indexes for the table. NOTE: must not be called for @@ -760,7 +760,7 @@ dict_table_get_all_fts_indexes( /* out: number of indexes collected */ dict_table_t* table, /* in: table */ ib_vector_t* indexes)/* out: vector for collecting FTS indexes */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Gets the number of user-defined columns in a table in the dictionary cache. @@ -770,7 +770,7 @@ ulint dict_table_get_n_user_cols( /*=======================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Gets the number of system columns in a table in the dictionary cache. @return number of system (e.g., ROW_ID) columns of a table */ @@ -779,7 +779,7 @@ ulint dict_table_get_n_sys_cols( /*======================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Gets the number of all columns (also system) in a table in the dictionary cache. @@ -789,7 +789,7 @@ ulint dict_table_get_n_cols( /*==================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Gets the approximately estimated number of rows in the table. @return estimated number of rows */ @@ -798,7 +798,7 @@ ib_uint64_t dict_table_get_n_rows( /*==================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Increment the number of rows in the table by one. Notice that this operation is not protected by any latch, the number is @@ -808,7 +808,7 @@ void dict_table_n_rows_inc( /*==================*/ dict_table_t* table) /*!< in/out: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Decrement the number of rows in the table by one. Notice that this operation is not protected by any latch, the number is @@ -818,7 +818,7 @@ void dict_table_n_rows_dec( /*==================*/ dict_table_t* table) /*!< in/out: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the nth column of a table. @@ -829,7 +829,7 @@ dict_table_get_nth_col( /*===================*/ const dict_table_t* table, /*!< in: table */ ulint pos) /*!< in: position of column */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the given system column of a table. @return pointer to column object */ @@ -839,7 +839,7 @@ dict_table_get_sys_col( /*===================*/ const dict_table_t* table, /*!< in: table */ ulint sys) /*!< in: DATA_ROW_ID, ... */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ #define dict_table_get_nth_col(table, pos) \ ((table)->cols + (pos)) @@ -855,7 +855,7 @@ dict_table_get_sys_col_no( /*======================*/ const dict_table_t* table, /*!< in: table */ ulint sys) /*!< in: DATA_ROW_ID, ... */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /********************************************************************//** Returns the minimum data size of an index record. @@ -865,7 +865,7 @@ ulint dict_index_get_min_size( /*====================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Check whether the table uses the compact page format. @@ -875,7 +875,7 @@ ibool dict_table_is_comp( /*===============*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Determine the file format of a table. @return file format version */ @@ -884,7 +884,7 @@ ulint dict_table_get_format( /*==================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Determine the file format from a dict_table_t::flags. @return file format version */ @@ -893,7 +893,7 @@ ulint dict_tf_get_format( /*===============*/ ulint flags) /*!< in: dict_table_t::flags */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /********************************************************************//** Set the various values in a dict_table_t::flags pointer. */ UNIV_INLINE @@ -904,7 +904,7 @@ dict_tf_set( rec_format_t format, /*!< in: file format */ ulint zip_ssize, /*!< in: zip shift size */ bool remote_path) /*!< in: table uses DATA DIRECTORY */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Convert a 32 bit integer table flags to the 32 bit integer that is written into the tablespace header at the offset FSP_SPACE_FLAGS and is @@ -921,7 +921,7 @@ ulint dict_tf_to_fsp_flags( /*=================*/ ulint flags) /*!< in: dict_table_t::flags */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /********************************************************************//** Extract the compressed page size from table flags. @return compressed page size, or 0 if not compressed */ @@ -930,7 +930,7 @@ ulint dict_tf_get_zip_size( /*=================*/ ulint flags) /*!< in: flags */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /********************************************************************//** Check whether the table uses the compressed compact page format. @return compressed page size, or 0 if not compressed */ @@ -939,7 +939,7 @@ ulint dict_table_zip_size( /*================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /*********************************************************************//** Obtain exclusive locks on all index trees of the table. This is to prevent @@ -950,7 +950,7 @@ void dict_table_x_lock_indexes( /*======================*/ dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Release the exclusive locks on all index tree. */ UNIV_INLINE @@ -958,7 +958,7 @@ void dict_table_x_unlock_indexes( /*========================*/ dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. @@ -969,7 +969,7 @@ dict_table_col_in_clustered_key( /*============================*/ const dict_table_t* table, /*!< in: table */ ulint n) /*!< in: column number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Check if the table has an FTS index. @return TRUE if table has an FTS index */ @@ -978,7 +978,7 @@ ibool dict_table_has_fts_index( /*=====================*/ dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Copies types of columns contained in table to tuple and sets all fields of the tuple to the SQL NULL value. This function should @@ -989,7 +989,7 @@ dict_table_copy_types( /*==================*/ dtuple_t* tuple, /*!< in/out: data tuple */ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************** Wait until all the background threads of the given table have exited, i.e., bg_threads == 0. Note: bg_threads_mutex must be reserved when @@ -1001,7 +1001,7 @@ dict_table_wait_for_bg_threads_to_exit( dict_table_t* table, /* in: table */ ulint delay) /* in: time in microseconds to wait between checks of bg_threads. */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Looks for an index with the given id. NOTE that we do not reserve the dictionary mutex: this function is for emergency purposes like @@ -1012,7 +1012,7 @@ dict_index_t* dict_index_find_on_id_low( /*======================*/ index_id_t id) /*!< in: index id */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /**********************************************************************//** Make room in the table cache by evicting an unused table. The unused table should not be part of FK relationship and currently not used in any user @@ -1038,7 +1038,7 @@ dict_index_add_to_cache( ibool strict) /*!< in: TRUE=refuse to create the index if records could be too big to fit in an B-tree page */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Removes an index from the dictionary cache. */ UNIV_INTERN @@ -1047,7 +1047,7 @@ dict_index_remove_from_cache( /*=========================*/ dict_table_t* table, /*!< in/out: table */ dict_index_t* index) /*!< in, own: index */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Gets the number of fields in the internal representation of an index, @@ -1060,7 +1060,7 @@ dict_index_get_n_fields( const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of fields in the internal representation of an index that uniquely determine the position of an index entry in the index, if @@ -1073,7 +1073,7 @@ dict_index_get_n_unique( /*====================*/ const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of fields in the internal representation of an index which uniquely determine the position of an index entry in the index, if @@ -1085,7 +1085,7 @@ dict_index_get_n_unique_in_tree( /*============================*/ const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of user-defined ordering fields in the index. In the internal representation we add the row id to the ordering fields to make all indexes @@ -1098,7 +1098,7 @@ dict_index_get_n_ordering_defined_by_user( /*======================================*/ const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the nth field of an index. @@ -1109,7 +1109,7 @@ dict_index_get_nth_field( /*=====================*/ const dict_index_t* index, /*!< in: index */ ulint pos) /*!< in: position of field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ # define dict_index_get_nth_field(index, pos) ((index)->fields + (pos)) #endif /* UNIV_DEBUG */ @@ -1122,7 +1122,7 @@ dict_index_get_nth_col( /*===================*/ const dict_index_t* index, /*!< in: index */ ulint pos) /*!< in: position of the field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the column number of the nth field in an index. @return column number */ @@ -1132,7 +1132,7 @@ dict_index_get_nth_col_no( /*======================*/ const dict_index_t* index, /*!< in: index */ ulint pos) /*!< in: position of the field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Looks for column n in an index. @return position in internal representation of the index; @@ -1143,7 +1143,7 @@ dict_index_get_nth_col_pos( /*=======================*/ const dict_index_t* index, /*!< in: index */ ulint n) /*!< in: column number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Looks for column n in an index. @return position in internal representation of the index; @@ -1156,7 +1156,7 @@ dict_index_get_nth_col_or_prefix_pos( ulint n, /*!< in: column number */ ibool inc_prefix) /*!< in: TRUE=consider column prefixes too */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Returns TRUE if the index contains a column or a prefix of that column. @return TRUE if contains the column or its prefix */ @@ -1166,7 +1166,7 @@ dict_index_contains_col_or_prefix( /*==============================*/ const dict_index_t* index, /*!< in: index */ ulint n) /*!< in: column number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Looks for a matching field in an index. The column has to be the same. The column in index must be complete, or must contain a prefix longer than the @@ -1181,7 +1181,7 @@ dict_index_get_nth_field_pos( const dict_index_t* index, /*!< in: index from which to search */ const dict_index_t* index2, /*!< in: index */ ulint n) /*!< in: field number in index2 */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Looks for column n position in the clustered index. @return position in internal representation of the clustered index */ @@ -1191,7 +1191,7 @@ dict_table_get_nth_col_pos( /*=======================*/ const dict_table_t* table, /*!< in: table */ ulint n) /*!< in: column number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Returns the position of a system column in an index. @return position, ULINT_UNDEFINED if not contained */ @@ -1201,7 +1201,7 @@ dict_index_get_sys_col_pos( /*=======================*/ const dict_index_t* index, /*!< in: index */ ulint type) /*!< in: DATA_ROW_ID, ... */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Adds a column to index. */ UNIV_INTERN @@ -1212,7 +1212,7 @@ dict_index_add_col( const dict_table_t* table, /*!< in: table */ dict_col_t* col, /*!< in: column */ ulint prefix_len) /*!< in: column prefix length */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /*******************************************************************//** Copies types of fields contained in index to tuple. */ @@ -1224,7 +1224,7 @@ dict_index_copy_types( const dict_index_t* index, /*!< in: index */ ulint n_fields) /*!< in: number of field types to copy */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /*********************************************************************//** Gets the field column. @@ -1234,7 +1234,7 @@ const dict_col_t* dict_field_get_col( /*===============*/ const dict_field_t* field) /*!< in: index field */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /**********************************************************************//** Returns an index object if it is found in the dictionary cache. @@ -1245,7 +1245,7 @@ dict_index_t* dict_index_get_if_in_cache_low( /*===========================*/ index_id_t index_id) /*!< in: index id */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /**********************************************************************//** Returns an index object if it is found in the dictionary cache. @@ -1255,7 +1255,7 @@ dict_index_t* dict_index_get_if_in_cache( /*=======================*/ index_id_t index_id) /*!< in: index id */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #ifdef UNIV_DEBUG /**********************************************************************//** @@ -1268,7 +1268,7 @@ dict_index_check_search_tuple( /*==========================*/ const dict_index_t* index, /*!< in: index tree */ const dtuple_t* tuple) /*!< in: tuple used in a search */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Whether and when to allow temporary index names */ enum check_name { /** Require all indexes to be complete. */ @@ -1288,7 +1288,7 @@ dict_table_check_for_dup_indexes( in this table */ enum check_name check) /*!< in: whether and when to allow temporary index names */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* UNIV_DEBUG */ /**********************************************************************//** Builds a node pointer out of a physical record and a page number. @@ -1306,7 +1306,7 @@ dict_index_build_node_ptr( created */ ulint level) /*!< in: level of rec in tree: 0 means leaf level */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Copies an initial segment of a physical record, long enough to specify an index entry uniquely. @@ -1322,7 +1322,7 @@ dict_index_copy_rec_order_prefix( byte** buf, /*!< in/out: memory buffer for the copied prefix, or NULL */ ulint* buf_size)/*!< in/out: buffer size */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Builds a typed data tuple out of a physical record. @return own: data tuple */ @@ -1334,7 +1334,7 @@ dict_index_build_data_tuple( rec_t* rec, /*!< in: record for which to build data tuple */ ulint n_fields,/*!< in: number of data fields */ mem_heap_t* heap) /*!< in: memory heap where tuple created */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets the space id of the root of the index tree. @return space id */ @@ -1343,7 +1343,7 @@ ulint dict_index_get_space( /*=================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Sets the space id of the root of the index tree. */ UNIV_INLINE @@ -1352,7 +1352,7 @@ dict_index_set_space( /*=================*/ dict_index_t* index, /*!< in/out: index */ ulint space) /*!< in: space id */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Gets the page number of the root of the index tree. @return page number */ @@ -1361,7 +1361,7 @@ ulint dict_index_get_page( /*================*/ const dict_index_t* tree) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Gets the read-write lock of the index tree. @return read-write lock */ @@ -1370,7 +1370,7 @@ rw_lock_t* dict_index_get_lock( /*================*/ dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Returns free space reserved for future updates of records. This is relevant only in the case of many consecutive inserts, as updates @@ -1390,7 +1390,7 @@ enum online_index_status dict_index_get_online_status( /*=========================*/ const dict_index_t* index) /*!< in: secondary index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Sets the status of online index creation. */ UNIV_INLINE @@ -1399,7 +1399,7 @@ dict_index_set_online_status( /*=========================*/ dict_index_t* index, /*!< in/out: index */ enum online_index_status status) /*!< in: status */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Determines if a secondary index is being or has been created online, or if the table is being rebuilt online, allowing concurrent modifications @@ -1413,7 +1413,7 @@ bool dict_index_is_online_ddl( /*=====================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Calculates the minimum record length in an index. */ UNIV_INTERN @@ -1421,7 +1421,7 @@ ulint dict_index_calc_min_rec_len( /*========================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Reserves the dictionary system mutex for MySQL. */ UNIV_INTERN @@ -1485,7 +1485,7 @@ dict_tables_have_same_db( dbname '/' tablename */ const char* name2) /*!< in: table name in the form dbname '/' tablename */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Removes an index from the cache */ UNIV_INTERN @@ -1494,7 +1494,7 @@ dict_index_remove_from_cache( /*=========================*/ dict_table_t* table, /*!< in/out: table */ dict_index_t* index) /*!< in, own: index */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Get index by name @return index, NULL if does not exist */ @@ -1504,7 +1504,7 @@ dict_table_get_index_on_name( /*=========================*/ dict_table_t* table, /*!< in: table */ const char* name) /*!< in: name of the index to find */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** In case there is more than one index with the same name return the index with the min(id). @@ -1515,7 +1515,7 @@ dict_table_get_index_on_name_and_min_id( /*====================================*/ dict_table_t* table, /*!< in: table */ const char* name) /*!< in: name of the index to find */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************** Check whether a column exists in an FTS index. */ UNIV_INLINE @@ -1526,7 +1526,7 @@ dict_table_is_fts_column( the offset within the vector */ ib_vector_t* indexes,/* in: vector containing only FTS indexes */ ulint col_no) /* in: col number to search for */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Move a table to the non LRU end of the LRU list. */ UNIV_INTERN @@ -1534,7 +1534,7 @@ void dict_table_move_from_lru_to_non_lru( /*================================*/ dict_table_t* table) /*!< in: table to move from LRU to non-LRU */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Move a table to the LRU list from the non-LRU list. */ UNIV_INTERN @@ -1542,7 +1542,7 @@ void dict_table_move_from_non_lru_to_lru( /*================================*/ dict_table_t* table) /*!< in: table to move from non-LRU to LRU */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Move to the most recently used segment of the LRU list. */ UNIV_INTERN @@ -1550,7 +1550,7 @@ void dict_move_to_mru( /*=============*/ dict_table_t* table) /*!< in: table to move to MRU */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Maximum number of columns in a foreign key constraint. Please Note MySQL has a much lower limit on the number of columns allowed in a foreign key @@ -1674,7 +1674,7 @@ dict_table_schema_check( != DB_TABLE_NOT_FOUND is returned */ size_t errstr_sz) /*!< in: errstr size */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /* @} */ /*********************************************************************//** @@ -1692,7 +1692,7 @@ dict_fs2utf8( size_t db_utf8_size, /*!< in: dbname_utf8 size */ char* table_utf8, /*!< out: table name, e.g. aÑŽbØc */ size_t table_utf8_size)/*!< in: table_utf8 size */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Closes the data dictionary module. */ @@ -1709,7 +1709,7 @@ ulint dict_table_is_corrupted( /*====================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Check whether the index is corrupted. @@ -1719,7 +1719,7 @@ ulint dict_index_is_corrupted( /*====================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -1732,7 +1732,7 @@ dict_set_corrupted( dict_index_t* index, /*!< in/out: index */ trx_t* trx, /*!< in/out: transaction */ const char* ctx) /*!< in: context */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Flags an index corrupted in the data dictionary cache only. This @@ -1744,7 +1744,7 @@ dict_set_corrupted_index_cache_only( /*================================*/ dict_index_t* index, /*!< in/out: index */ dict_table_t* table) /*!< in/out: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Flags a table with specified space_id corrupted in the table dictionary @@ -1764,7 +1764,7 @@ bool dict_tf_is_valid( /*=============*/ ulint flags) /*!< in: table flags */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /********************************************************************//** Check if the tablespace for the table has been discarded. @@ -1774,7 +1774,7 @@ bool dict_table_is_discarded( /*====================*/ const dict_table_t* table) /*!< in: table to check */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************//** Check if it is a temporary table. @@ -1784,7 +1784,7 @@ bool dict_table_is_temporary( /*====================*/ const dict_table_t* table) /*!< in: table to check */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #ifndef UNIV_HOTBACKUP /*********************************************************************//** @@ -1795,7 +1795,7 @@ void dict_index_zip_success( /*===================*/ dict_index_t* index) /*!< in/out: index to be updated. */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** This function should be called whenever a page compression attempt fails. Updates the compression padding information. */ @@ -1804,7 +1804,7 @@ void dict_index_zip_failure( /*===================*/ dict_index_t* index) /*!< in/out: index to be updated. */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Return the optimal page size, for which page will likely compress. @return page size beyond which page may not compress*/ @@ -1814,7 +1814,7 @@ dict_index_zip_pad_optimal_page_size( /*=================================*/ dict_index_t* index) /*!< in: index for which page size is requested */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Convert table flag to row format string. @return row format name */ diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index fac54d9488bc5..6fc6098f3d9c3 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -80,7 +80,8 @@ dict_col_copy_type( const dict_col_t* col, /*!< in: column */ dtype_t* type) /*!< out: data type */ { - ut_ad(col && type); + ut_ad(col != NULL); + ut_ad(type != NULL); type->mtype = col->mtype; type->prtype = col->prtype; @@ -357,7 +358,7 @@ UNIV_INLINE ulint dict_table_get_n_sys_cols( /*======================*/ - const dict_table_t* table __attribute__((unused))) /*!< in: table */ + const dict_table_t* table MY_ATTRIBUTE((unused))) /*!< in: table */ { ut_ad(table); ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 030190b1a8e7a..dcbc3de8e942f 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -243,7 +243,7 @@ dict_load_foreigns( bool check_charsets, /*!< in: whether to check charset compatibility */ dict_err_ignore_t ignore_err) /*!< in: error to be ignored */ - __attribute__((nonnull(1), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /********************************************************************//** Prints to the standard output information on all tables found in the data dictionary system table. */ diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 6f9dd75ee1060..4b49976642dfa 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -150,19 +150,19 @@ allows InnoDB to update_create_info() accordingly. */ /** Bit mask of the COMPACT field */ #define DICT_TF_MASK_COMPACT \ - ((~(~0 << DICT_TF_WIDTH_COMPACT)) \ + ((~(~0U << DICT_TF_WIDTH_COMPACT)) \ << DICT_TF_POS_COMPACT) /** Bit mask of the ZIP_SSIZE field */ #define DICT_TF_MASK_ZIP_SSIZE \ - ((~(~0 << DICT_TF_WIDTH_ZIP_SSIZE)) \ + ((~(~0U << DICT_TF_WIDTH_ZIP_SSIZE)) \ << DICT_TF_POS_ZIP_SSIZE) /** Bit mask of the ATOMIC_BLOBS field */ #define DICT_TF_MASK_ATOMIC_BLOBS \ - ((~(~0 << DICT_TF_WIDTH_ATOMIC_BLOBS)) \ + ((~(~0U << DICT_TF_WIDTH_ATOMIC_BLOBS)) \ << DICT_TF_POS_ATOMIC_BLOBS) /** Bit mask of the DATA_DIR field */ #define DICT_TF_MASK_DATA_DIR \ - ((~(~0 << DICT_TF_WIDTH_DATA_DIR)) \ + ((~(~0U << DICT_TF_WIDTH_DATA_DIR)) \ << DICT_TF_POS_DATA_DIR) /** Return the value of the COMPACT field */ @@ -196,7 +196,7 @@ for unknown bits in order to protect backward incompatibility. */ /* @{ */ /** Total number of bits in table->flags2. */ #define DICT_TF2_BITS 7 -#define DICT_TF2_BIT_MASK ~(~0 << DICT_TF2_BITS) +#define DICT_TF2_BIT_MASK ~(~0U << DICT_TF2_BITS) /** TEMPORARY; TRUE for tables from CREATE TEMPORARY TABLE. */ #define DICT_TF2_TEMPORARY 1 @@ -276,7 +276,7 @@ dict_mem_table_add_col( ulint mtype, /*!< in: main datatype */ ulint prtype, /*!< in: precise type */ ulint len) /*!< in: precision */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /**********************************************************************//** Renames a column of a table in the data dictionary cache. */ UNIV_INTERN @@ -287,7 +287,7 @@ dict_mem_table_col_rename( unsigned nth_col,/*!< in: column index */ const char* from, /*!< in: old column name */ const char* to) /*!< in: new column name */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** This function populates a dict_col_t memory structure with supplied information. */ diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 186f90e3694db..35ee1a00d8a7e 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2009, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2009, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -77,7 +77,7 @@ dict_stats_set_persistent( dict_table_t* table, /*!< in/out: table */ ibool ps_on, /*!< in: persistent stats explicitly enabled */ ibool ps_off) /*!< in: persistent stats explicitly disabled */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Check whether persistent statistics is enabled for a given table. @@ -87,7 +87,7 @@ ibool dict_stats_is_persistent_enabled( /*=============================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Set the auto recalc flag for a given table (only honored for a persistent @@ -127,7 +127,7 @@ void dict_stats_deinit( /*==============*/ dict_table_t* table) /*!< in/out: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Calculates new estimates for table and index statistics. The statistics @@ -179,7 +179,7 @@ void dict_stats_update_for_index( /*========================*/ dict_index_t* index) /*!< in/out: index */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Renames a table in InnoDB persistent stats storage. diff --git a/storage/innobase/include/dict0stats_bg.h b/storage/innobase/include/dict0stats_bg.h index e866ab419fef6..82cd2b468b9f7 100644 --- a/storage/innobase/include/dict0stats_bg.h +++ b/storage/innobase/include/dict0stats_bg.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -74,7 +74,7 @@ bool dict_stats_stop_bg( /*===============*/ dict_table_t* table) /*!< in/out: table */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*****************************************************************//** Wait until background stats thread has stopped using the specified table. diff --git a/storage/innobase/include/dyn0dyn.h b/storage/innobase/include/dyn0dyn.h index 7f23302d1ff5a..1bd10b6bf58bc 100644 --- a/storage/innobase/include/dyn0dyn.h +++ b/storage/innobase/include/dyn0dyn.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -48,7 +48,7 @@ dyn_array_create( /*=============*/ dyn_array_t* arr) /*!< in/out memory buffer of size sizeof(dyn_array_t) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /************************************************************//** Frees a dynamic array. */ UNIV_INLINE @@ -56,7 +56,7 @@ void dyn_array_free( /*===========*/ dyn_array_t* arr) /*!< in,own: dyn array */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Makes room on top of a dyn array and returns a pointer to a buffer in it. After copying the elements, the caller must close the buffer using @@ -69,7 +69,7 @@ dyn_array_open( dyn_array_t* arr, /*!< in: dynamic array */ ulint size) /*!< in: size in bytes of the buffer; MUST be smaller than DYN_ARRAY_DATA_SIZE! */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Closes the buffer returned by dyn_array_open. */ UNIV_INLINE @@ -78,7 +78,7 @@ dyn_array_close( /*============*/ dyn_array_t* arr, /*!< in: dynamic array */ const byte* ptr) /*!< in: end of used space */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Makes room on top of a dyn array and returns a pointer to the added element. The caller must copy the element to @@ -90,7 +90,7 @@ dyn_array_push( /*===========*/ dyn_array_t* arr, /*!< in/out: dynamic array */ ulint size) /*!< in: size in bytes of the element */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /************************************************************//** Returns pointer to an element in dyn array. @return pointer to element */ @@ -101,7 +101,7 @@ dyn_array_get_element( const dyn_array_t* arr, /*!< in: dyn array */ ulint pos) /*!< in: position of element in bytes from array start */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /************************************************************//** Returns the size of stored data in a dyn array. @return data size in bytes */ @@ -110,7 +110,7 @@ ulint dyn_array_get_data_size( /*====================*/ const dyn_array_t* arr) /*!< in: dyn array */ - __attribute__((nonnull, warn_unused_result, pure)); + MY_ATTRIBUTE((nonnull, warn_unused_result, pure)); /************************************************************//** Gets the first block in a dyn array. @param arr dyn array @@ -144,7 +144,7 @@ ulint dyn_block_get_used( /*===============*/ const dyn_block_t* block) /*!< in: dyn array block */ - __attribute__((nonnull, warn_unused_result, pure)); + MY_ATTRIBUTE((nonnull, warn_unused_result, pure)); /********************************************************************//** Gets pointer to the start of data in a dyn array block. @return pointer to data */ @@ -153,7 +153,7 @@ byte* dyn_block_get_data( /*===============*/ const dyn_block_t* block) /*!< in: dyn array block */ - __attribute__((nonnull, warn_unused_result, pure)); + MY_ATTRIBUTE((nonnull, warn_unused_result, pure)); /********************************************************//** Pushes n bytes to a dyn array. */ UNIV_INLINE @@ -163,7 +163,7 @@ dyn_push_string( dyn_array_t* arr, /*!< in/out: dyn array */ const byte* str, /*!< in: string to write */ ulint len) /*!< in: string length */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*#################################################################*/ diff --git a/storage/innobase/include/dyn0dyn.ic b/storage/innobase/include/dyn0dyn.ic index 0296554e2eeed..f18f2e6dff995 100644 --- a/storage/innobase/include/dyn0dyn.ic +++ b/storage/innobase/include/dyn0dyn.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -36,7 +36,7 @@ dyn_block_t* dyn_array_add_block( /*================*/ dyn_array_t* arr) /*!< in/out: dyn array */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of used bytes in a dyn array block. diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 43c9162914fed..4d2913846b58e 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -233,7 +233,7 @@ fil_node_create( ulint id, /*!< in: space id where to append */ ibool is_raw) /*!< in: TRUE if a raw device or a raw disk partition */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifdef UNIV_LOG_ARCHIVE /****************************************************************//** Drops files from the start of a file space, so that its size is cut by @@ -400,7 +400,7 @@ fil_read_first_page( lsn values in data files */ lsn_t* max_flushed_lsn) /*!< out: max of flushed lsn values in data files */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*******************************************************************//** Increments the count of pending operation, if space is not being deleted. @return TRUE if being deleted, and operation should be skipped */ @@ -488,7 +488,7 @@ dberr_t fil_discard_tablespace( /*===================*/ ulint id) /*!< in: space id */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /** Test if a tablespace file can be renamed to a new filepath by checking @@ -597,7 +597,7 @@ fil_create_new_single_table_tablespace( ulint size) /*!< in: the initial size of the tablespace file in pages, must be >= FIL_IBD_FILE_INITIAL_SIZE */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /********************************************************************//** Tries to open a single-table tablespace and optionally checks the space id is @@ -631,7 +631,7 @@ fil_open_single_table_tablespace( const char* tablename, /*!< in: table name in the databasename/tablename format */ const char* filepath) /*!< in: tablespace filepath */ - __attribute__((nonnull(5), warn_unused_result)); + MY_ATTRIBUTE((nonnull(5), warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /********************************************************************//** @@ -780,7 +780,7 @@ fil_io( appropriately aligned */ void* message) /*!< in: message for aio handler if non-sync aio used, else ignored */ - __attribute__((nonnull(8))); + MY_ATTRIBUTE((nonnull(8))); /**********************************************************************//** Waits for an aio operation to complete. This function is used to write the handler for completed requests. The aio array of pending requests is divided @@ -975,7 +975,7 @@ fil_tablespace_iterate( dict_table_t* table, ulint n_io_buffers, PageCallback& callback) - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Checks if a single-table tablespace for a given table name exists in the @@ -999,7 +999,7 @@ fil_get_space_names( /*================*/ space_name_list_t& space_name_list) /*!< in/out: Vector for collecting the names. */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /** Generate redo log for swapping two .ibd files @param[in] old_table old table @@ -1014,7 +1014,7 @@ fil_mtr_rename_log( const dict_table_t* new_table, const char* tmp_name, mtr_t* mtr) - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Finds the given page_no of the given space id from the double write buffer, diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index a587ccc9f20d3..099cb8edc14d9 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -83,23 +83,23 @@ is found in a remote location, not the default data directory. */ /** Bit mask of the POST_ANTELOPE field */ #define FSP_FLAGS_MASK_POST_ANTELOPE \ - ((~(~0 << FSP_FLAGS_WIDTH_POST_ANTELOPE)) \ + ((~(~0U << FSP_FLAGS_WIDTH_POST_ANTELOPE)) \ << FSP_FLAGS_POS_POST_ANTELOPE) /** Bit mask of the ZIP_SSIZE field */ #define FSP_FLAGS_MASK_ZIP_SSIZE \ - ((~(~0 << FSP_FLAGS_WIDTH_ZIP_SSIZE)) \ + ((~(~0U << FSP_FLAGS_WIDTH_ZIP_SSIZE)) \ << FSP_FLAGS_POS_ZIP_SSIZE) /** Bit mask of the ATOMIC_BLOBS field */ #define FSP_FLAGS_MASK_ATOMIC_BLOBS \ - ((~(~0 << FSP_FLAGS_WIDTH_ATOMIC_BLOBS)) \ + ((~(~0U << FSP_FLAGS_WIDTH_ATOMIC_BLOBS)) \ << FSP_FLAGS_POS_ATOMIC_BLOBS) /** Bit mask of the PAGE_SSIZE field */ #define FSP_FLAGS_MASK_PAGE_SSIZE \ - ((~(~0 << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \ + ((~(~0U << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \ << FSP_FLAGS_POS_PAGE_SSIZE) /** Bit mask of the DATA_DIR field */ #define FSP_FLAGS_MASK_DATA_DIR \ - ((~(~0 << FSP_FLAGS_WIDTH_DATA_DIR)) \ + ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \ << FSP_FLAGS_POS_DATA_DIR) /** Return the value of the POST_ANTELOPE field */ @@ -510,7 +510,7 @@ fseg_alloc_free_page_general( in which the page should be initialized. If init_mtr!=mtr, but the page is already latched in mtr, do not initialize the page. */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /**********************************************************************//** Reserves free pages from a tablespace. All mini-transactions which may use several pages from the tablespace should call this function beforehand @@ -579,7 +579,7 @@ fseg_page_is_free( fseg_header_t* seg_header, /*!< in: segment header */ ulint space, /*!< in: space id */ ulint page) /*!< in: page offset */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************************//** Frees part of a segment. This function can be used to free a segment by repeatedly calling this function in different mini-transactions. @@ -675,7 +675,7 @@ bool fsp_flags_is_valid( /*===============*/ ulint flags) /*!< in: tablespace flags */ - __attribute__((warn_unused_result, const)); + MY_ATTRIBUTE((warn_unused_result, const)); /********************************************************************//** Determine if the tablespace is compressed from dict_table_t::flags. @return TRUE if compressed, FALSE if not compressed */ diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h index b2380f78b396d..50f62063893e0 100644 --- a/storage/innobase/include/fts0ast.h +++ b/storage/innobase/include/fts0ast.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -200,7 +200,7 @@ fts_ast_visit( and ignored processing an operator, currently we only ignore FTS_IGNORE operator */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Process (nested) sub-expression, create a new result set to store the sub-expression result by processing nodes under current sub-expression @@ -213,7 +213,7 @@ fts_ast_visit_sub_exp( fts_ast_node_t* node, /*!< in: instance to traverse*/ fts_ast_callback visitor, /*!< in: callback */ void* arg) /*!< in: callback arg */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************** Create a lex instance.*/ UNIV_INTERN @@ -223,7 +223,7 @@ fts_lexer_create( ibool boolean_mode, /*!< in: query type */ const byte* query, /*!< in: query string */ ulint query_len) /*!< in: query string len */ - __attribute__((nonnull, malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); /******************************************************************** Free an fts_lexer_t instance.*/ UNIV_INTERN @@ -232,7 +232,7 @@ fts_lexer_free( /*===========*/ fts_lexer_t* fts_lexer) /*!< in: lexer instance to free */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Create an ast string object, with NUL-terminator, so the string diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 9f7b0216d9b88..68d4d333245d9 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -94,7 +94,10 @@ those defined in mysql file ft_global.h */ /** Threshold where our optimize thread automatically kicks in */ #define FTS_OPTIMIZE_THRESHOLD 10000000 -#define FTS_DOC_ID_MAX_STEP 10000 +/** Threshold to avoid exhausting of doc ids. Consecutive doc id difference +should not exceed FTS_DOC_ID_MAX_STEP */ +#define FTS_DOC_ID_MAX_STEP 65535 + /** Variable specifying the FTS parallel sort degree */ extern ulong fts_sort_pll_degree; @@ -408,7 +411,7 @@ fts_get_next_doc_id( /*================*/ const dict_table_t* table, /*!< in: table */ doc_id_t* doc_id) /*!< out: new document id */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Update the next and last Doc ID in the CONFIG table to be the input "doc_id" value (+ 1). We would do so after each FTS index build or @@ -421,7 +424,7 @@ fts_update_next_doc_id( const dict_table_t* table, /*!< in: table */ const char* table_name, /*!< in: table name, or NULL */ doc_id_t doc_id) /*!< in: DOC ID to set */ - __attribute__((nonnull(2))); + MY_ATTRIBUTE((nonnull(2))); /******************************************************************//** Create a new document id . @@ -437,7 +440,7 @@ fts_create_doc_id( current row that is being inserted. */ mem_heap_t* heap) /*!< in: heap */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Create a new fts_doc_ids_t. @return new fts_doc_ids_t. */ @@ -466,7 +469,7 @@ fts_trx_add_op( fts_row_state state, /*!< in: state of the row */ ib_vector_t* fts_indexes) /*!< in: FTS indexes affected (NULL=all) */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /******************************************************************//** Free an FTS trx. */ @@ -491,7 +494,7 @@ fts_create_common_tables( index */ const char* name, /*!< in: table name */ bool skip_doc_id_index) /*!< in: Skip index on doc id */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Wrapper function of fts_create_index_tables_low(), create auxiliary tables for an FTS index @@ -503,7 +506,7 @@ fts_create_index_tables( trx_t* trx, /*!< in: transaction handle */ const dict_index_t* index) /*!< in: the FTS index instance */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Creates the column specific ancillary tables needed for supporting an FTS index on the given table. row_mysql_lock_data_dictionary must have @@ -519,7 +522,7 @@ fts_create_index_tables_low( instance */ const char* table_name, /*!< in: the table name */ table_id_t table_id) /*!< in: the table id */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Add the FTS document id hidden column. */ UNIV_INTERN @@ -528,7 +531,7 @@ fts_add_doc_id_column( /*==================*/ dict_table_t* table, /*!< in/out: Table with FTS index */ mem_heap_t* heap) /*!< in: temporary memory heap, or NULL */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /*********************************************************************//** Drops the ancillary tables needed for supporting an FTS index on the @@ -542,7 +545,7 @@ fts_drop_tables( trx_t* trx, /*!< in: transaction */ dict_table_t* table) /*!< in: table has the FTS index */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** The given transaction is about to be committed; do whatever is necessary from the FTS system's POV. @@ -552,7 +555,7 @@ dberr_t fts_commit( /*=======*/ trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** FTS Query entry point. @@ -569,7 +572,7 @@ fts_query( in bytes */ fts_result_t** result) /*!< out: query result, to be freed by the caller.*/ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Retrieve the FTS Relevance Ranking result for doc with doc_id @@ -687,7 +690,7 @@ dberr_t fts_optimize_table( /*===============*/ dict_table_t* table) /*!< in: table to optimiza */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Startup the optimize thread and create the work queue. */ @@ -713,7 +716,7 @@ fts_drop_index_tables( /*==================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index) /*!< in: Index to drop */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Remove the table from the OPTIMIZER's list. We do wait for @@ -754,7 +757,7 @@ fts_savepoint_take( trx_t* trx, /*!< in: transaction */ fts_trx_t* fts_trx, /*!< in: fts transaction */ const char* name) /*!< in: savepoint name */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Refresh last statement savepoint. */ UNIV_INTERN @@ -762,7 +765,7 @@ void fts_savepoint_laststmt_refresh( /*===========================*/ trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Release the savepoint data identified by name. */ UNIV_INTERN @@ -780,13 +783,12 @@ fts_cache_destroy( /*==============*/ fts_cache_t* cache); /*!< in: cache*/ -/*********************************************************************//** -Clear cache. */ +/** Clear cache. +@param[in,out] cache fts cache */ UNIV_INTERN void fts_cache_clear( -/*============*/ - fts_cache_t* cache); /*!< in: cache */ + fts_cache_t* cache); /*********************************************************************//** Initialize things in cache. */ @@ -831,7 +833,7 @@ fts_drop_index_split_tables( /*========================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index) /*!< in: fts instance */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Run SYNC on the table, i.e., write out data from the cache to the FTS auxiliary INDEX table and clear the cache at the end. @@ -1023,7 +1025,7 @@ fts_drop_index( dict_table_t* table, /*!< in: Table where indexes are dropped */ dict_index_t* index, /*!< in: Index to be dropped */ trx_t* trx) /*!< in: Transaction for the drop */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /****************************************************************//** Rename auxiliary tables for all fts index for a table diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h index b4d9e1d41ecf2..2d4e9d88fd1a5 100644 --- a/storage/innobase/include/fts0priv.h +++ b/storage/innobase/include/fts0priv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -121,7 +121,7 @@ fts_parse_sql( fts_table_t* fts_table, /*!< in: FTS aux table */ pars_info_t* info, /*!< in: info struct, or NULL */ const char* sql) /*!< in: SQL string to evaluate */ - __attribute__((nonnull(3), malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull(3), malloc, warn_unused_result)); /******************************************************************//** Evaluate a parsed SQL statement @return DB_SUCCESS or error code */ @@ -131,7 +131,7 @@ fts_eval_sql( /*=========*/ trx_t* trx, /*!< in: transaction */ que_t* graph) /*!< in: Parsed statement */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Construct the name of an ancillary FTS table for the given table. @return own: table name, must be freed with mem_free() */ @@ -141,7 +141,7 @@ fts_get_table_name( /*===============*/ const fts_table_t* fts_table) /*!< in: FTS aux table info */ - __attribute__((nonnull, malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); /******************************************************************//** Construct the column specification part of the SQL string for selecting the indexed FTS columns for the given table. Adds the necessary bound @@ -164,7 +164,7 @@ fts_get_select_columns_str( dict_index_t* index, /*!< in: FTS index */ pars_info_t* info, /*!< in/out: parser info */ mem_heap_t* heap) /*!< in: memory heap */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** define for fts_doc_fetch_by_doc_id() "option" value, defines whether we want to get Doc whose ID is equal to or greater or smaller than supplied @@ -191,7 +191,7 @@ fts_doc_fetch_by_doc_id( callback, /*!< in: callback to read records */ void* arg) /*!< in: callback arg */ - __attribute__((nonnull(6))); + MY_ATTRIBUTE((nonnull(6))); /*******************************************************************//** Callback function for fetch that stores the text of an FTS document, @@ -203,7 +203,7 @@ fts_query_expansion_fetch_doc( /*==========================*/ void* row, /*!< in: sel_node_t* */ void* user_arg) /*!< in: fts_doc_t* */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************** Write out a single word's data as new entry/entries in the INDEX table. @return DB_SUCCESS if all OK. */ @@ -216,7 +216,7 @@ fts_write_node( fts_table_t* fts_table, /*!< in: the FTS aux index */ fts_string_t* word, /*!< in: word in UTF-8 */ fts_node_t* node) /*!< in: node columns */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Tokenize a document. */ UNIV_INTERN @@ -227,7 +227,7 @@ fts_tokenize_document( tokenize */ fts_doc_t* result) /*!< out: if provided, save result tokens here */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /*******************************************************************//** Continue to tokenize a document. */ @@ -241,7 +241,7 @@ fts_tokenize_document_next( tokens from this tokenization */ fts_doc_t* result) /*!< out: if provided, save result tokens here */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /******************************************************************//** Initialize a document. */ UNIV_INTERN @@ -249,7 +249,7 @@ void fts_doc_init( /*=========*/ fts_doc_t* doc) /*!< in: doc to initialize */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Do a binary search for a doc id in the array @@ -263,7 +263,7 @@ fts_bsearch( int lower, /*!< in: lower bound of array*/ int upper, /*!< in: upper bound of array*/ doc_id_t doc_id) /*!< in: doc id to lookup */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Free document. */ UNIV_INTERN @@ -271,7 +271,7 @@ void fts_doc_free( /*=========*/ fts_doc_t* doc) /*!< in: document */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Free fts_optimizer_word_t instanace.*/ UNIV_INTERN @@ -279,7 +279,7 @@ void fts_word_free( /*==========*/ fts_word_t* word) /*!< in: instance to free.*/ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Read the rows from the FTS inde @return DB_SUCCESS or error code */ @@ -293,7 +293,7 @@ fts_index_fetch_nodes( const fts_string_t* word, /*!< in: the word to fetch */ fts_fetch_t* fetch) /*!< in: fetch callback.*/ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Create a fts_optimizer_word_t instance. @return new instance */ @@ -304,7 +304,7 @@ fts_word_init( fts_word_t* word, /*!< in: word to initialize */ byte* utf8, /*!< in: UTF-8 string */ ulint len) /*!< in: length of string in bytes */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Compare two fts_trx_table_t instances, we actually compare the table id's here. @@ -315,7 +315,7 @@ fts_trx_table_cmp( /*==============*/ const void* v1, /*!< in: id1 */ const void* v2) /*!< in: id2 */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Compare a table id with a trx_table_t table id. @return < 0 if n1 < n2, 0 if n1 == n2, > 0 if n1 > n2 */ @@ -325,7 +325,7 @@ fts_trx_table_id_cmp( /*=================*/ const void* p1, /*!< in: id1 */ const void* p2) /*!< in: id2 */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Commit a transaction. @return DB_SUCCESS if all OK */ @@ -334,7 +334,7 @@ dberr_t fts_sql_commit( /*===========*/ trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Rollback a transaction. @return DB_SUCCESS if all OK */ @@ -343,7 +343,7 @@ dberr_t fts_sql_rollback( /*=============*/ trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Parse an SQL string. %s is replaced with the table's id. Don't acquire the dict mutex @@ -355,7 +355,7 @@ fts_parse_sql_no_dict_lock( fts_table_t* fts_table, /*!< in: table with FTS index */ pars_info_t* info, /*!< in: parser info */ const char* sql) /*!< in: SQL string to evaluate */ - __attribute__((nonnull(3), malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull(3), malloc, warn_unused_result)); /******************************************************************//** Get value from config table. The caller must ensure that enough space is allocated for value to hold the column contents @@ -370,7 +370,7 @@ fts_config_get_value( this parameter name */ fts_string_t* value) /*!< out: value read from config table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Get value specific to an FTS index from the config table. The caller must ensure that enough space is allocated for value to hold the @@ -386,7 +386,7 @@ fts_config_get_index_value( this parameter name */ fts_string_t* value) /*!< out: value read from config table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Set the value in the config table for name. @return DB_SUCCESS or error code */ @@ -400,7 +400,7 @@ fts_config_set_value( this parameter name */ const fts_string_t* value) /*!< in: value to update */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /****************************************************************//** Set an ulint value in the config table. @return DB_SUCCESS if all OK else error code */ @@ -412,7 +412,7 @@ fts_config_set_ulint( fts_table_t* fts_table, /*!< in: the indexed FTS table */ const char* name, /*!< in: param name */ ulint int_value) /*!< in: value */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Set the value specific to an FTS index in the config table. @return DB_SUCCESS or error code */ @@ -426,7 +426,7 @@ fts_config_set_index_value( this parameter name */ fts_string_t* value) /*!< out: value read from config table */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Increment the value in the config table for column name. @return DB_SUCCESS or error code */ @@ -439,7 +439,7 @@ fts_config_increment_value( const char* name, /*!< in: increment config value for this parameter name */ ulint delta) /*!< in: increment by this much */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Increment the per index value in the config table for column name. @return DB_SUCCESS or error code */ @@ -452,7 +452,7 @@ fts_config_increment_index_value( const char* name, /*!< in: increment config value for this parameter name */ ulint delta) /*!< in: increment by this much */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Get an ulint value from the config table. @return DB_SUCCESS or error code */ @@ -464,7 +464,7 @@ fts_config_get_index_ulint( dict_index_t* index, /*!< in: FTS index */ const char* name, /*!< in: param name */ ulint* int_value) /*!< out: value */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Set an ulint value int the config table. @return DB_SUCCESS or error code */ @@ -476,7 +476,7 @@ fts_config_set_index_ulint( dict_index_t* index, /*!< in: FTS index */ const char* name, /*!< in: param name */ ulint int_value) /*!< in: value */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Get an ulint value from the config table. @return DB_SUCCESS or error code */ @@ -488,7 +488,7 @@ fts_config_get_ulint( fts_table_t* fts_table, /*!< in: the indexed FTS table */ const char* name, /*!< in: param name */ ulint* int_value) /*!< out: value */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Search cache for word. @return the word node vector if found else NULL */ @@ -500,7 +500,7 @@ fts_cache_find_word( index_cache, /*!< in: cache to search */ const fts_string_t* text) /*!< in: word to search for */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Check cache for deleted doc id. @return TRUE if deleted */ @@ -511,7 +511,7 @@ fts_cache_is_deleted_doc_id( const fts_cache_t* cache, /*!< in: cache ito search */ doc_id_t doc_id) /*!< in: doc id to search for */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Append deleted doc ids to vector and sort the vector. */ UNIV_INTERN @@ -546,7 +546,7 @@ fts_get_total_word_count( trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: for this index */ ulint* total) /*!< out: total words */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /******************************************************************//** Search the index specific cache for a particular FTS index. @@ -559,7 +559,7 @@ fts_find_index_cache( cache, /*!< in: cache to search */ const dict_index_t* index) /*!< in: index to search for */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Write the table id to the given buffer (including final NUL). Buffer must be at least FTS_AUX_MIN_TABLE_ID_LENGTH bytes long. @@ -570,10 +570,10 @@ fts_write_object_id( /*================*/ ib_id_t id, /*!< in: a table/index id */ char* str, /*!< in: buffer to write the id to */ - bool hex_format __attribute__((unused))) + bool hex_format MY_ATTRIBUTE((unused))) /*!< in: true for fixed hex format, false for old ambiguous format */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Read the table id from the string generated by fts_write_object_id(). @return TRUE if parse successful */ @@ -583,7 +583,7 @@ fts_read_object_id( /*===============*/ ib_id_t* id, /*!< out: a table id */ const char* str) /*!< in: buffer to read from */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Get the table id. @return number of bytes written */ @@ -596,7 +596,7 @@ fts_get_table_id( char* table_id) /*!< out: table id, must be at least FTS_AUX_MIN_TABLE_ID_LENGTH bytes long */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Add the table to add to the OPTIMIZER's list. */ UNIV_INTERN @@ -604,7 +604,7 @@ void fts_optimize_add_table( /*===================*/ dict_table_t* table) /*!< in: table to add */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Optimize a table. */ UNIV_INTERN @@ -612,7 +612,7 @@ void fts_optimize_do_table( /*==================*/ dict_table_t* table) /*!< in: table to optimize */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Construct the prefix name of an FTS table. @return own: table name, must be freed with mem_free() */ @@ -622,7 +622,7 @@ fts_get_table_name_prefix( /*======================*/ const fts_table_t* fts_table) /*!< in: Auxiliary table type */ - __attribute__((nonnull, malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); /******************************************************************//** Add node positions. */ UNIV_INTERN @@ -633,7 +633,7 @@ fts_cache_node_add_positions( fts_node_t* node, /*!< in: word node */ doc_id_t doc_id, /*!< in: doc id */ ib_vector_t* positions) /*!< in: fts_token_t::positions */ - __attribute__((nonnull(2,4))); + MY_ATTRIBUTE((nonnull(2,4))); /******************************************************************//** Create the config table name for retrieving index specific value. @@ -644,7 +644,7 @@ fts_config_create_index_param_name( /*===============================*/ const char* param, /*!< in: base name of param */ const dict_index_t* index) /*!< in: index for config */ - __attribute__((nonnull, malloc, warn_unused_result)); + MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); #ifndef UNIV_NONINL #include "fts0priv.ic" diff --git a/storage/innobase/include/fts0priv.ic b/storage/innobase/include/fts0priv.ic index 2d07c60f98085..88f2d67c7b898 100644 --- a/storage/innobase/include/fts0priv.ic +++ b/storage/innobase/include/fts0priv.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -33,7 +33,7 @@ fts_write_object_id( /*================*/ ib_id_t id, /* in: a table/index id */ char* str, /* in: buffer to write the id to */ - bool hex_format __attribute__((unused))) + bool hex_format MY_ATTRIBUTE((unused))) /* in: true for fixed hex format, false for old ambiguous format */ { @@ -53,7 +53,7 @@ fts_write_object_id( /* Use this to construct old(5.6.14 and 5.7.3) windows ambiguous aux table names */ DBUG_EXECUTE_IF("innodb_test_wrong_windows_fts_aux_table_name", - return(sprintf(str, "%016"PRIu64, id));); + return(sprintf(str, "%016" PRIu64, id));); DBUG_EXECUTE_IF("innodb_test_wrong_fts_aux_table_name", return(sprintf(str, UINT64PFx, id));); @@ -66,7 +66,7 @@ fts_write_object_id( // FIXME: Use ut_snprintf(), so does following one. return(sprintf(str, "%016llu", id)); #else /* _WIN32 */ - return(sprintf(str, "%016"PRIu64, id)); + return(sprintf(str, "%016" PRIu64, id)); #endif /* _WIN32 */ } diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 8a962a988804e..a7f9ff8038d50 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2006, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -135,7 +135,7 @@ enum durability_properties thd_requested_durability( /*=====================*/ const THD* thd) /*!< in: thread handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Returns true if the transaction this thread is processing has edited @@ -176,7 +176,7 @@ innobase_mysql_cmp( const unsigned char* b, /*!< in: data field */ unsigned int b_length) /*!< in: data field length, not UNIV_SQL_NULL */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**************************************************************//** Converts a MySQL type to an InnoDB type. Note that this function returns the 'mtype' of InnoDB. InnoDB differentiates between MySQL's old <= 4.1 @@ -192,7 +192,7 @@ get_innobase_type_from_mysql_type( and unsigned integer types are 'unsigned types' */ const void* field) /*!< in: MySQL Field */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Get the variable length bounds of the given character set. */ @@ -290,7 +290,7 @@ innobase_get_stmt( /*==============*/ THD* thd, /*!< in: MySQL thread handle */ size_t* length) /*!< out: length of the SQL statement */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** This function is used to find the storage length in bytes of the first n characters for prefix indexes using a multibyte character set. The function @@ -316,7 +316,7 @@ enum icp_result innobase_index_cond( /*================*/ void* file) /*!< in/out: pointer to ha_innobase */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Returns true if the thread supports XA, global value of innodb_supports_xa if thd is NULL. @@ -452,7 +452,7 @@ innobase_format_name( const char* name, /*!< in: index or table name to format */ ibool is_index_name) /*!< in: index name */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Corresponds to Sql_condition:enum_warning_level. */ enum ib_log_level_t { @@ -482,7 +482,7 @@ ib_errf( ib_uint32_t code, /*!< MySQL error code */ const char* format, /*!< printf format */ ...) /*!< Args */ - __attribute__((format(printf, 4, 5))); + MY_ATTRIBUTE((format(printf, 4, 5))); /******************************************************************//** Use this when the args are passed to the format string from @@ -513,7 +513,7 @@ ib_logf( ib_log_level_t level, /*!< in: warning level */ const char* format, /*!< printf format */ ...) /*!< Args */ - __attribute__((format(printf, 2, 3))); + MY_ATTRIBUTE((format(printf, 2, 3))); /******************************************************************//** Returns the NUL terminated value of glob_hostname. @@ -559,7 +559,7 @@ innobase_next_autoinc( ulonglong step, /*!< in: AUTOINC increment step */ ulonglong offset, /*!< in: AUTOINC offset */ ulonglong max_value) /*!< in: max value for type */ - __attribute__((pure, warn_unused_result)); + MY_ATTRIBUTE((pure, warn_unused_result)); /********************************************************************//** Get the upper limit of the MySQL integral and floating-point type. @@ -569,7 +569,7 @@ ulonglong innobase_get_int_col_max_value( /*===========================*/ const Field* field) /*!< in: MySQL field */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /********************************************************************** Check if the length of the identifier exceeds the maximum allowed. diff --git a/storage/innobase/include/handler0alter.h b/storage/innobase/include/handler0alter.h index 66b963ae39a13..3dd6c99eb6d8b 100644 --- a/storage/innobase/include/handler0alter.h +++ b/storage/innobase/include/handler0alter.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -32,7 +32,7 @@ innobase_rec_to_mysql( const dict_index_t* index, /*!< in: index */ const ulint* offsets)/*!< in: rec_get_offsets( rec, index, ...) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Copies an InnoDB index entry to table->record[0]. */ @@ -43,7 +43,7 @@ innobase_fields_to_mysql( struct TABLE* table, /*!< in/out: MySQL table */ const dict_index_t* index, /*!< in: InnoDB index */ const dfield_t* fields) /*!< in: InnoDB index fields */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Copies an InnoDB row to table->record[0]. */ @@ -54,7 +54,7 @@ innobase_row_to_mysql( struct TABLE* table, /*!< in/out: MySQL table */ const dict_table_t* itab, /*!< in: InnoDB table */ const dtuple_t* row) /*!< in: InnoDB row */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Resets table->record[0]. */ @@ -63,7 +63,7 @@ void innobase_rec_reset( /*===============*/ struct TABLE* table) /*!< in/out: MySQL table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Generate the next autoinc based on a snapshot of the session auto_increment_increment and auto_increment_offset variables. */ diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h index 9c3b686c99807..3ee16f57fb860 100644 --- a/storage/innobase/include/ibuf0ibuf.h +++ b/storage/innobase/include/ibuf0ibuf.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -118,7 +118,7 @@ void ibuf_mtr_start( /*===========*/ mtr_t* mtr) /*!< out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***************************************************************//** Commits an insert buffer mini-transaction. */ UNIV_INLINE @@ -126,7 +126,7 @@ void ibuf_mtr_commit( /*============*/ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Initializes an ibuf bitmap page. */ UNIV_INTERN @@ -252,7 +252,7 @@ ibool ibuf_inside( /*========*/ const mtr_t* mtr) /*!< in: mini-transaction */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /***********************************************************************//** Checks if a page address is an ibuf bitmap page (level 3 page) address. @return TRUE if a bitmap page */ @@ -285,7 +285,7 @@ ibuf_page_low( is not one of the fixed address ibuf pages, or NULL, in which case a new transaction is created. */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #ifdef UNIV_DEBUG /** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. Must not be called when recv_no_ibuf_operations==TRUE. @@ -364,23 +364,31 @@ void ibuf_delete_for_discarded_space( /*============================*/ ulint space); /*!< in: space id */ -/*********************************************************************//** -Contracts insert buffer trees by reading pages to the buffer pool. +/** Contract the change buffer by reading pages to the buffer pool. +@param[in] full If true, do a full contraction based +on PCT_IO(100). If false, the size of contract batch is determined +based on the current size of the change buffer. @return a lower limit for the combined size in bytes of entries which will be merged from ibuf trees to the pages read, 0 if ibuf is empty */ UNIV_INTERN ulint -ibuf_contract_in_background( -/*========================*/ - table_id_t table_id, /*!< in: if merge should be done only - for a specific table, for all tables - this should be 0 */ - ibool full); /*!< in: TRUE if the caller wants to - do a full contract based on PCT_IO(100). - If FALSE then the size of contract - batch is determined based on the - current size of the ibuf tree. */ +ibuf_merge_in_background( + bool full); /*!< in: TRUE if the caller wants to + do a full contract based on PCT_IO(100). + If FALSE then the size of contract + batch is determined based on the + current size of the ibuf tree. */ + +/** Contracts insert buffer trees by reading pages referring to space_id +to the buffer pool. +@returns number of pages merged.*/ +UNIV_INTERN +ulint +ibuf_merge_space( +/*=============*/ + ulint space); /*!< in: space id */ + #endif /* !UNIV_HOTBACKUP */ /*********************************************************************//** Parses a redo log record of an ibuf bitmap page init. @@ -445,7 +453,7 @@ ibuf_check_bitmap_on_import( /*========================*/ const trx_t* trx, /*!< in: transaction */ ulint space_id) /*!< in: tablespace identifier */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO #define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 6d5ed35d5d89f..ce4052769bc64 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -266,7 +266,7 @@ lock_rec_expl_exist_on_page( /*========================*/ ulint space, /*!< in: space id */ ulint page_no)/*!< in: page number */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*********************************************************************//** Checks if locks of other transactions prevent an immediate insert of a record. If they do, first tests if the query thread should anyway @@ -289,7 +289,7 @@ lock_rec_insert_check_and_lock( inserted record maybe should inherit LOCK_GAP type locks from the successor record */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Checks if locks of other transactions prevent an immediate modify (update, delete mark, or delete unmark) of a clustered index record. If they do, @@ -310,7 +310,7 @@ lock_clust_rec_modify_check_and_lock( dict_index_t* index, /*!< in: clustered index */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /*********************************************************************//** Checks if locks of other transactions prevent an immediate modify (delete mark or delete unmark) of a secondary index record. @@ -331,7 +331,7 @@ lock_sec_rec_modify_check_and_lock( que_thr_t* thr, /*!< in: query thread (can be NULL if BTR_NO_LOCKING_FLAG) */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((warn_unused_result, nonnull(2,3,4,6))); + MY_ATTRIBUTE((warn_unused_result, nonnull(2,3,4,6))); /*********************************************************************//** Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record. @@ -418,7 +418,7 @@ lock_clust_rec_read_check_and_lock_alt( ulint gap_mode,/*!< in: LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Checks that a record is seen in a consistent read. @return true if sees, or false if an earlier version of the record @@ -450,7 +450,7 @@ lock_sec_rec_cons_read_sees( should be read or passed over by a read cursor */ const read_view_t* view) /*!< in: consistent read view */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Locks the specified database table in the mode given. If the lock cannot be granted immediately, the query thread is put to wait. @@ -465,7 +465,7 @@ lock_table( in dictionary cache */ enum lock_mode mode, /*!< in: lock mode */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Creates a table IX lock object for a resurrected transaction. */ UNIV_INTERN @@ -520,7 +520,7 @@ lock_rec_fold( /*==========*/ ulint space, /*!< in: space */ ulint page_no)/*!< in: page number */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*********************************************************************//** Calculates the hash value of a page file address: used in inserting or searching for a lock in the hash table. @@ -570,7 +570,7 @@ lock_is_table_exclusive( /*====================*/ const dict_table_t* table, /*!< in: table */ const trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Checks if a lock request lock1 has to wait for request lock2. @return TRUE if lock1 has to wait for lock2 to be removed */ @@ -594,7 +594,7 @@ lock_report_trx_id_insanity( dict_index_t* index, /*!< in: index */ const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */ trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Prints info of a table lock. */ UNIV_INTERN @@ -621,7 +621,7 @@ lock_print_info_summary( /*====================*/ FILE* file, /*!< in: file where to print */ ibool nowait) /*!< in: whether to wait for the lock mutex */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Prints info of locks for each transaction. This function assumes that the caller holds the lock mutex and more importantly it will release the lock @@ -641,7 +641,7 @@ ulint lock_number_of_rows_locked( /*=======================*/ const trx_lock_t* trx_lock) /*!< in: transaction locks */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Gets the type of a lock. Non-inline version for using outside of the @@ -799,7 +799,7 @@ dberr_t lock_trx_handle_wait( /*=================*/ trx_t* trx) /*!< in/out: trx lock state */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Get the number of locks on a table. @return number of locks */ @@ -808,7 +808,7 @@ ulint lock_table_get_n_locks( /*===================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG /*********************************************************************//** Checks that a transaction id is sensible, i.e., not in the future. @@ -821,7 +821,7 @@ lock_check_trx_id_sanity( const rec_t* rec, /*!< in: user record */ dict_index_t* index, /*!< in: index */ const ulint* offsets) /*!< in: rec_get_offsets(rec, index) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Check if the transaction holds any locks on the sys tables or its records. @@ -831,7 +831,7 @@ const lock_t* lock_trx_has_sys_table_locks( /*=========================*/ const trx_t* trx) /*!< in: transaction to check */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*******************************************************************//** Check if the transaction holds an exclusive lock on a record. @@ -844,7 +844,7 @@ lock_trx_has_rec_x_lock( const dict_table_t* table, /*!< in: table to check */ const buf_block_t* block, /*!< in: buffer block of the record */ ulint heap_no)/*!< in: record heap number */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ /** Lock modes and types */ diff --git a/storage/innobase/include/lock0priv.h b/storage/innobase/include/lock0priv.h index 9f7ab9f76b6e7..2d9584833ffa1 100644 --- a/storage/innobase/include/lock0priv.h +++ b/storage/innobase/include/lock0priv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -117,7 +117,7 @@ lock_clust_rec_some_has_impl( const rec_t* rec, /*!< in: user record */ const dict_index_t* index, /*!< in: clustered index */ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "lock0priv.ic" diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 8ede49d4ecc5e..f4c7b4ed88207 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -51,7 +51,7 @@ recv_read_checkpoint_info_for_backup( lsn_t* first_header_lsn) /*!< out: lsn of of the start of the first log file */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Scans the log segment and n_bytes_scanned is set to the length of valid log scanned. */ diff --git a/storage/innobase/include/mach0data.h b/storage/innobase/include/mach0data.h index d0087f56aaafe..9859def0adc9f 100644 --- a/storage/innobase/include/mach0data.h +++ b/storage/innobase/include/mach0data.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -53,7 +53,7 @@ ulint mach_read_from_1( /*=============*/ const byte* b) /*!< in: pointer to byte */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*******************************************************//** The following function is used to store data in two consecutive bytes. We store the most significant byte to the lower address. */ @@ -72,7 +72,7 @@ ulint mach_read_from_2( /*=============*/ const byte* b) /*!< in: pointer to two bytes */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /********************************************************//** The following function is used to convert a 16-bit data item @@ -84,7 +84,7 @@ uint16 mach_encode_2( /*==========*/ ulint n) /*!< in: integer in machine-dependent format */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /********************************************************//** The following function is used to convert a 16-bit data item from the canonical format, for fast bytewise equality test @@ -95,7 +95,7 @@ ulint mach_decode_2( /*==========*/ uint16 n) /*!< in: 16-bit integer in canonical format */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*******************************************************//** The following function is used to store data in 3 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -114,7 +114,7 @@ ulint mach_read_from_3( /*=============*/ const byte* b) /*!< in: pointer to 3 bytes */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*******************************************************//** The following function is used to store data in four consecutive bytes. We store the most significant byte to the lowest address. */ @@ -133,7 +133,7 @@ ulint mach_read_from_4( /*=============*/ const byte* b) /*!< in: pointer to four bytes */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a ulint in a compressed form (1..5 bytes). @return stored size in bytes */ @@ -151,7 +151,7 @@ ulint mach_get_compressed_size( /*=====================*/ ulint n) /*!< in: ulint integer to be stored */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*********************************************************//** Reads a ulint in a compressed form. @return read integer */ @@ -160,7 +160,7 @@ ulint mach_read_compressed( /*=================*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*******************************************************//** The following function is used to store data in 6 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -179,7 +179,7 @@ ib_uint64_t mach_read_from_6( /*=============*/ const byte* b) /*!< in: pointer to 6 bytes */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*******************************************************//** The following function is used to store data in 7 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -198,7 +198,7 @@ ib_uint64_t mach_read_from_7( /*=============*/ const byte* b) /*!< in: pointer to 7 bytes */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*******************************************************//** The following function is used to store data in 8 consecutive bytes. We store the most significant byte to the lowest address. */ @@ -217,7 +217,7 @@ ib_uint64_t mach_read_from_8( /*=============*/ const byte* b) /*!< in: pointer to 8 bytes */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a 64-bit integer in a compressed form (5..9 bytes). @return size in bytes */ @@ -243,7 +243,7 @@ ib_uint64_t mach_ull_read_compressed( /*=====================*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a 64-bit integer in a compressed form (1..11 bytes). @return size in bytes */ @@ -261,7 +261,7 @@ ulint mach_ull_get_much_compressed_size( /*==============================*/ ib_uint64_t n) /*!< in: 64-bit integer to be stored */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*********************************************************//** Reads a 64-bit integer in a compressed form. @return the value read */ @@ -270,7 +270,7 @@ ib_uint64_t mach_ull_read_much_compressed( /*==========================*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Reads a ulint in a compressed form if the log record fully contains it. @return pointer to end of the stored field, NULL if not complete */ @@ -301,7 +301,7 @@ double mach_double_read( /*=============*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a double. It is stored in a little-endian format. */ UNIV_INLINE @@ -318,7 +318,7 @@ float mach_float_read( /*============*/ const byte* b) /*!< in: pointer to memory from where to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a float. It is stored in a little-endian format. */ UNIV_INLINE @@ -336,7 +336,7 @@ mach_read_from_n_little_endian( /*===========================*/ const byte* buf, /*!< in: from where to read */ ulint buf_size) /*!< in: from how many bytes to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a ulint in the little-endian format. */ UNIV_INLINE @@ -354,7 +354,7 @@ ulint mach_read_from_2_little_endian( /*===========================*/ const byte* buf) /*!< in: from where to read */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************//** Writes a ulint in the little-endian format. */ UNIV_INLINE diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h index f30034f3074f4..de9b8b29fd9c7 100644 --- a/storage/innobase/include/mem0mem.h +++ b/storage/innobase/include/mem0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -353,7 +353,7 @@ mem_heap_printf( /*============*/ mem_heap_t* heap, /*!< in: memory heap */ const char* format, /*!< in: format string */ - ...) __attribute__ ((format (printf, 2, 3))); + ...) MY_ATTRIBUTE ((format (printf, 2, 3))); #ifdef MEM_PERIODIC_CHECK /******************************************************************//** diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic index 0d983d69e1a3a..63e68150b61da 100644 --- a/storage/innobase/include/mem0mem.ic +++ b/storage/innobase/include/mem0mem.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2010, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -476,9 +476,9 @@ void mem_heap_free_func( /*===============*/ mem_heap_t* heap, /*!< in, own: heap to be freed */ - const char* file_name __attribute__((unused)), + const char* file_name MY_ATTRIBUTE((unused)), /*!< in: file name where freed */ - ulint line __attribute__((unused))) + ulint line MY_ATTRIBUTE((unused))) { mem_block_t* block; mem_block_t* prev_block; diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index ed7fd76d425a2..db4e028e93120 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -207,7 +207,7 @@ void mtr_start( /*======*/ mtr_t* mtr) /*!< out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***************************************************************//** Commits a mini-transaction. */ UNIV_INTERN @@ -215,7 +215,7 @@ void mtr_commit( /*=======*/ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************//** Sets and returns a savepoint in mtr. @return savepoint */ @@ -308,7 +308,7 @@ mtr_memo_release( mtr_t* mtr, /*!< in/out: mini-transaction */ void* object, /*!< in: object */ ulint type) /*!< in: object type: MTR_MEMO_S_LOCK, ... */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG # ifndef UNIV_HOTBACKUP /**********************************************************//** @@ -321,7 +321,7 @@ mtr_memo_contains( mtr_t* mtr, /*!< in: mtr */ const void* object, /*!< in: object to search */ ulint type) /*!< in: type of object */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /**********************************************************//** Checks if memo contains the given page. diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index a9f024302209b..3f897ae1d101d 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -37,7 +37,7 @@ ibool mtr_block_dirtied( /*==============*/ const buf_block_t* block) /*!< in: block being x-fixed */ - __attribute__((nonnull,warn_unused_result)); + MY_ATTRIBUTE((nonnull,warn_unused_result)); /***************************************************************//** Starts a mini-transaction. */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 13631732b1a9d..f047302c60c84 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -1,6 +1,6 @@ /*********************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. Portions of this file contain modifications contributed and copyrighted @@ -529,7 +529,7 @@ os_file_create_simple_no_error_handling_func( OS_FILE_READ_ALLOW_DELETE; the last option is used by a backup program reading the file */ ibool* success)/*!< out: TRUE if succeed, FALSE if error */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /****************************************************************//** Tries to disable OS caching on an opened file descriptor. */ UNIV_INTERN @@ -563,7 +563,7 @@ os_file_create_func( function source code for the exact rules */ ulint type, /*!< in: OS_DATA_FILE or OS_LOG_FILE */ ibool* success)/*!< out: TRUE if succeed, FALSE if error */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** Deletes a file. The file has to be closed before calling this. @return TRUE if success */ @@ -629,7 +629,7 @@ pfs_os_file_create_simple_func( ibool* success,/*!< out: TRUE if succeed, FALSE if error */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /****************************************************************//** NOTE! Please use the corresponding macro @@ -654,7 +654,7 @@ pfs_os_file_create_simple_no_error_handling_func( ibool* success,/*!< out: TRUE if succeed, FALSE if error */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /****************************************************************//** NOTE! Please use the corresponding macro os_file_create(), not directly @@ -682,7 +682,7 @@ pfs_os_file_create_func( ibool* success,/*!< out: TRUE if succeed, FALSE if error */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** NOTE! Please use the corresponding macro os_file_close(), not directly @@ -861,7 +861,7 @@ os_offset_t os_file_get_size( /*=============*/ os_file_t file) /*!< in: handle to a file */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /***********************************************************************//** Write the specified number of zeros to a newly created file. @return TRUE if success */ @@ -873,7 +873,7 @@ os_file_set_size( null-terminated string */ os_file_t file, /*!< in: handle to a file */ os_offset_t size) /*!< in: file size */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** Truncates a file at its current position. @return TRUE if success */ diff --git a/storage/innobase/include/os0thread.h b/storage/innobase/include/os0thread.h index 37c54afae8032..9a1ada8fa0dff 100644 --- a/storage/innobase/include/os0thread.h +++ b/storage/innobase/include/os0thread.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -125,7 +125,7 @@ os_thread_exit( /*===========*/ void* exit_value) /*!< in: exit value; in Windows this void* is cast as a DWORD */ - UNIV_COLD __attribute__((noreturn)); + UNIV_COLD MY_ATTRIBUTE((noreturn)); /*****************************************************************//** Returns the thread identifier of current thread. @return current thread identifier */ diff --git a/storage/innobase/include/page0cur.h b/storage/innobase/include/page0cur.h index b1ad49b49150d..f04667ff29c2c 100644 --- a/storage/innobase/include/page0cur.h +++ b/storage/innobase/include/page0cur.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -180,7 +180,7 @@ page_cur_tuple_insert( mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */ ulint n_ext, /*!< in: number of externally stored columns */ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */ - __attribute__((nonnull(1,2,3,4,5), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,4,5), warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** Inserts a record next to page cursor. Returns pointer to inserted record if @@ -218,7 +218,7 @@ page_cur_insert_rec_low( const rec_t* rec, /*!< in: pointer to a physical record */ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */ - __attribute__((nonnull(1,2,3,4), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result)); /***********************************************************//** Inserts a record next to page cursor on a compressed and uncompressed page. Returns pointer to inserted record if succeed, i.e., @@ -240,7 +240,7 @@ page_cur_insert_rec_zip( const rec_t* rec, /*!< in: pointer to a physical record */ ulint* offsets,/*!< in/out: rec_get_offsets(rec, index) */ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL */ - __attribute__((nonnull(1,2,3,4), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result)); /*************************************************************//** Copies records from page to a newly created page, from a given record onward, including that record. Infimum and supremum records are not copied. diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index 0bd0a009cae83..0dd5bb53d9ef7 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -165,7 +165,7 @@ page_t* page_align( /*=======*/ const void* ptr) /*!< in: pointer to page frame */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /************************************************************//** Gets the offset within a page. @return offset from the start of the page */ @@ -174,7 +174,7 @@ ulint page_offset( /*========*/ const void* ptr) /*!< in: pointer to page frame */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*************************************************************//** Returns the max trx id field value. */ UNIV_INLINE @@ -232,7 +232,7 @@ page_header_get_offs( /*=================*/ const page_t* page, /*!< in: page */ ulint field) /*!< in: PAGE_FREE, ... */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*************************************************************//** Returns the pointer stored in the given header field, or NULL. */ @@ -292,7 +292,7 @@ page_rec_get_nth_const( /*===================*/ const page_t* page, /*!< in: page */ ulint nth) /*!< in: nth record */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /************************************************************//** Returns the nth record of the record list. This is the inverse function of page_rec_get_n_recs_before(). @@ -303,7 +303,7 @@ page_rec_get_nth( /*=============*/ page_t* page, /*< in: page */ ulint nth) /*!< in: nth record */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /************************************************************//** @@ -316,7 +316,7 @@ rec_t* page_get_middle_rec( /*================*/ page_t* page) /*!< in: page */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************//** Compares a data tuple to a physical record. Differs from the function cmp_dtuple_rec_with_match in the way that the record must reside on an @@ -524,7 +524,7 @@ bool page_is_leaf( /*=========*/ const page_t* page) /*!< in: page */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /************************************************************//** Determine whether the page is empty. @return true if the page is empty (PAGE_N_RECS = 0) */ @@ -533,7 +533,7 @@ bool page_is_empty( /*==========*/ const page_t* page) /*!< in: page */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /************************************************************//** Determine whether the page contains garbage. @return true if the page contains garbage (PAGE_GARBAGE is not 0) */ @@ -542,7 +542,7 @@ bool page_has_garbage( /*=============*/ const page_t* page) /*!< in: page */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /************************************************************//** Gets the pointer to the next record on the page. @return pointer to next record */ @@ -614,7 +614,7 @@ ibool page_rec_is_user_rec_low( /*=====================*/ ulint offset) /*!< in: record offset on page */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /************************************************************//** TRUE if the record is the supremum record on a page. @return TRUE if the supremum record */ @@ -623,7 +623,7 @@ ibool page_rec_is_supremum_low( /*=====================*/ ulint offset) /*!< in: record offset on page */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /************************************************************//** TRUE if the record is the infimum record on a page. @return TRUE if the infimum record */ @@ -632,7 +632,7 @@ ibool page_rec_is_infimum_low( /*====================*/ ulint offset) /*!< in: record offset on page */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /************************************************************//** TRUE if the record is a user record on the page. @@ -642,7 +642,7 @@ ibool page_rec_is_user_rec( /*=================*/ const rec_t* rec) /*!< in: record */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /************************************************************//** TRUE if the record is the supremum record on a page. @return TRUE if the supremum record */ @@ -651,7 +651,7 @@ ibool page_rec_is_supremum( /*=================*/ const rec_t* rec) /*!< in: record */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /************************************************************//** TRUE if the record is the infimum record on a page. @@ -661,7 +661,7 @@ ibool page_rec_is_infimum( /*================*/ const rec_t* rec) /*!< in: record */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /***************************************************************//** Looks for the record which owns the given record. @return the owner record */ @@ -681,7 +681,7 @@ page_rec_write_field( ulint i, /*!< in: index of the field to update */ ulint val, /*!< in: value to write */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /************************************************************//** Returns the maximum combined size of records which can be inserted on top @@ -711,7 +711,7 @@ ulint page_get_free_space_of_empty( /*=========================*/ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /**********************************************************//** Returns the base extra size of a physical record. This is the size of the fixed header, independent of the record size. @@ -797,7 +797,7 @@ page_create_zip( ulint level, /*!< in: the B-tree level of the page */ trx_id_t max_trx_id, /*!< in: PAGE_MAX_TRX_ID */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************//** Empty a previously created B-tree index page. */ UNIV_INTERN @@ -807,7 +807,7 @@ page_create_empty( buf_block_t* block, /*!< in/out: B-tree block */ dict_index_t* index, /*!< in: the index of the page */ mtr_t* mtr) /*!< in/out: mini-transaction */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /*************************************************************//** Differs from page_copy_rec_list_end, because this function does not touch the lock table and max trx id on page or compress the page. @@ -846,7 +846,7 @@ page_copy_rec_list_end( rec_t* rec, /*!< in: record on page */ dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Copies records from page to new_page, up to the given record, NOT including that record. Infimum and supremum records are not copied. @@ -868,7 +868,7 @@ page_copy_rec_list_start( rec_t* rec, /*!< in: record on page */ dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Deletes records from a page from a given record onward, including that record. The infimum and supremum records are not deleted. */ @@ -885,7 +885,7 @@ page_delete_rec_list_end( records in the end of the chain to delete, or ULINT_UNDEFINED if not known */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Deletes records from page, up to the given record, NOT including that record. Infimum and supremum records are not deleted. */ @@ -897,7 +897,7 @@ page_delete_rec_list_start( buf_block_t* block, /*!< in: buffer block of the page */ dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*************************************************************//** Moves record list end to another page. Moved records include split_rec. @@ -918,7 +918,7 @@ page_move_rec_list_end( rec_t* split_rec, /*!< in: first record to move */ dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull(1, 2, 4, 5))); + MY_ATTRIBUTE((nonnull(1, 2, 4, 5))); /*************************************************************//** Moves record list start to another page. Moved records do not include split_rec. @@ -938,7 +938,7 @@ page_move_rec_list_start( rec_t* split_rec, /*!< in: first record not to move */ dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull(1, 2, 4, 5))); + MY_ATTRIBUTE((nonnull(1, 2, 4, 5))); /****************************************************************//** Splits a directory slot which owns too many records. */ UNIV_INTERN @@ -949,7 +949,7 @@ page_dir_split_slot( page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed part will be written, or NULL */ ulint slot_no)/*!< in: the directory slot */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /*************************************************************//** Tries to balance the given directory slot with too few records with the upper neighbor, so that there are at least the minimum number @@ -962,7 +962,7 @@ page_dir_balance_slot( page_t* page, /*!< in/out: index page */ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */ ulint slot_no)/*!< in: the directory slot */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /**********************************************************//** Parses a log record of a record list end or start deletion. @return end of log record or NULL */ diff --git a/storage/innobase/include/page0types.h b/storage/innobase/include/page0types.h index 95143a4bb4497..196712760db69 100644 --- a/storage/innobase/include/page0types.h +++ b/storage/innobase/include/page0types.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -129,7 +129,7 @@ page_zip_rec_set_deleted( page_zip_des_t* page_zip,/*!< in/out: compressed page */ const byte* rec, /*!< in: record on the uncompressed page */ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Write the "owned" flag of a record on a compressed page. The n_owned field @@ -141,7 +141,7 @@ page_zip_rec_set_owned( page_zip_des_t* page_zip,/*!< in/out: compressed page */ const byte* rec, /*!< in: record on the uncompressed page */ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Shift the dense page directory when a record is deleted. */ @@ -154,7 +154,7 @@ page_zip_dir_delete( dict_index_t* index, /*!< in: index of rec */ const ulint* offsets,/*!< in: rec_get_offsets(rec) */ const byte* free) /*!< in: previous start of the free list */ - __attribute__((nonnull(1,2,3,4))); + MY_ATTRIBUTE((nonnull(1,2,3,4))); /**********************************************************************//** Add a slot to the dense page directory. */ @@ -165,5 +165,5 @@ page_zip_dir_add_slot( page_zip_des_t* page_zip, /*!< in/out: compressed page */ ulint is_clustered) /*!< in: nonzero for clustered index, zero for others */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif diff --git a/storage/innobase/include/page0zip.h b/storage/innobase/include/page0zip.h index 9d3b78ed2fcca..3a23bcb7396fa 100644 --- a/storage/innobase/include/page0zip.h +++ b/storage/innobase/include/page0zip.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -58,7 +58,7 @@ ulint page_zip_get_size( /*==============*/ const page_zip_des_t* page_zip) /*!< in: compressed page */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /**********************************************************************//** Set the size of a compressed page in bytes. */ UNIV_INLINE @@ -81,7 +81,7 @@ page_zip_rec_needs_ext( ulint n_fields, /*!< in: number of fields in the record; ignored if zip_size == 0 */ ulint zip_size) /*!< in: compressed page size in bytes, or 0 */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /**********************************************************************//** Determine the guaranteed free space on an empty page. @@ -92,7 +92,7 @@ page_zip_empty_size( /*================*/ ulint n_fields, /*!< in: number of columns in the index */ ulint zip_size) /*!< in: compressed page size in bytes */ - __attribute__((const)); + MY_ATTRIBUTE((const)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -127,7 +127,7 @@ page_zip_compress( dict_index_t* index, /*!< in: index of the B-tree node */ ulint level, /*!< in: compression level */ mtr_t* mtr) /*!< in: mini-transaction, or NULL */ - __attribute__((nonnull(1,2,3))); + MY_ATTRIBUTE((nonnull(1,2,3))); /**********************************************************************//** Decompress a page. This function should tolerate errors on the compressed @@ -145,7 +145,7 @@ page_zip_decompress( FALSE=verify but do not copy some page header fields that should not change after page creation */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); #ifdef UNIV_DEBUG /**********************************************************************//** @@ -172,7 +172,7 @@ page_zip_validate_low( const dict_index_t* index, /*!< in: index of the page, if known */ ibool sloppy) /*!< in: FALSE=strict, TRUE=ignore the MIN_REC_FLAG */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************************//** Check that the compressed and decompressed pages match. */ UNIV_INTERN @@ -182,7 +182,7 @@ page_zip_validate( const page_zip_des_t* page_zip,/*!< in: compressed page */ const page_t* page, /*!< in: uncompressed page */ const dict_index_t* index) /*!< in: index of the page, if known */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); #endif /* UNIV_ZIP_DEBUG */ /**********************************************************************//** @@ -195,7 +195,7 @@ page_zip_max_ins_size( /*==================*/ const page_zip_des_t* page_zip,/*!< in: compressed page */ ibool is_clust)/*!< in: TRUE if clustered index */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /**********************************************************************//** Determine if enough space is available in the modification log. @@ -209,7 +209,7 @@ page_zip_available( ulint length, /*!< in: combined size of the record */ ulint create) /*!< in: nonzero=add the record to the heap */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /**********************************************************************//** Write data to the uncompressed header portion of a page. The data must @@ -222,7 +222,7 @@ page_zip_write_header( const byte* str, /*!< in: address on the uncompressed page */ ulint length, /*!< in: length of the data */ mtr_t* mtr) /*!< in: mini-transaction, or NULL */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************************//** Write an entire record on the compressed page. The data must already @@ -236,7 +236,7 @@ page_zip_write_rec( dict_index_t* index, /*!< in: the index the record belongs to */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ ulint create) /*!< in: nonzero=insert, zero=update */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***********************************************************//** Parses a log record of writing a BLOB pointer of a record. @@ -265,7 +265,7 @@ page_zip_write_blob_ptr( ulint n, /*!< in: column index */ mtr_t* mtr) /*!< in: mini-transaction handle, or NULL if no logging is needed */ - __attribute__((nonnull(1,2,3,4))); + MY_ATTRIBUTE((nonnull(1,2,3,4))); /***********************************************************//** Parses a log record of writing the node pointer of a record. @@ -290,7 +290,7 @@ page_zip_write_node_ptr( ulint size, /*!< in: data size of rec */ ulint ptr, /*!< in: node pointer */ mtr_t* mtr) /*!< in: mini-transaction, or NULL */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************************//** Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */ @@ -304,7 +304,7 @@ page_zip_write_trx_id_and_roll_ptr( ulint trx_id_col,/*!< in: column number of TRX_ID in rec */ trx_id_t trx_id, /*!< in: transaction identifier */ roll_ptr_t roll_ptr)/*!< in: roll_ptr */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Write the "deleted" flag of a record on a compressed page. The flag must @@ -316,7 +316,7 @@ page_zip_rec_set_deleted( page_zip_des_t* page_zip,/*!< in/out: compressed page */ const byte* rec, /*!< in: record on the uncompressed page */ ulint flag) /*!< in: the deleted flag (nonzero=TRUE) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Write the "owned" flag of a record on a compressed page. The n_owned field @@ -328,7 +328,7 @@ page_zip_rec_set_owned( page_zip_des_t* page_zip,/*!< in/out: compressed page */ const byte* rec, /*!< in: record on the uncompressed page */ ulint flag) /*!< in: the owned flag (nonzero=TRUE) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Insert a record to the dense page directory. */ @@ -355,7 +355,7 @@ page_zip_dir_delete( const ulint* offsets, /*!< in: rec_get_offsets(rec) */ const byte* free) /*!< in: previous start of the free list */ - __attribute__((nonnull(1,2,3,4))); + MY_ATTRIBUTE((nonnull(1,2,3,4))); /**********************************************************************//** Add a slot to the dense page directory. */ @@ -366,7 +366,7 @@ page_zip_dir_add_slot( page_zip_des_t* page_zip, /*!< in/out: compressed page */ ulint is_clustered) /*!< in: nonzero for clustered index, zero for others */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***********************************************************//** Parses a log record of writing to the header of a page. @@ -394,7 +394,7 @@ page_zip_write_header( const byte* str, /*!< in: address on the uncompressed page */ ulint length, /*!< in: length of the data */ mtr_t* mtr) /*!< in: mini-transaction, or NULL */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************************//** Reorganize and compress a page. This is a low-level operation for @@ -417,7 +417,7 @@ page_zip_reorganize( m_start, m_end, m_nonempty */ dict_index_t* index, /*!< in: index of the B-tree node */ mtr_t* mtr) /*!< in: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /**********************************************************************//** Copy the records of a page byte for byte. Do not copy the page header @@ -436,7 +436,7 @@ page_zip_copy_recs( const page_t* src, /*!< in: page */ dict_index_t* index, /*!< in: index of the B-tree */ mtr_t* mtr) /*!< in: mini-transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -450,7 +450,7 @@ page_zip_parse_compress( byte* end_ptr,/*!< in: buffer end */ page_t* page, /*!< out: uncompressed page */ page_zip_des_t* page_zip)/*!< out: compressed page */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************************//** Calculate the compressed page checksum. @@ -462,7 +462,7 @@ page_zip_calc_checksum( const void* data, /*!< in: compressed page */ ulint size, /*!< in: size of compressed page */ srv_checksum_algorithm_t algo) /*!< in: algorithm to use */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Verify a compressed page's checksum. @@ -496,7 +496,7 @@ page_zip_parse_compress_no_data( page_t* page, /*!< in: uncompressed page */ page_zip_des_t* page_zip, /*!< out: compressed page */ dict_index_t* index) /*!< in: index */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************************//** Reset the counters used for filling diff --git a/storage/innobase/include/pars0pars.h b/storage/innobase/include/pars0pars.h index 65ff753382879..73585c78a6aff 100644 --- a/storage/innobase/include/pars0pars.h +++ b/storage/innobase/include/pars0pars.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -472,7 +472,7 @@ pars_complete_graph_for_exec( query graph, or NULL for dummy graph */ trx_t* trx, /*!< in: transaction handle */ mem_heap_t* heap) /*!< in: memory heap from which allocated */ - __attribute__((nonnull(2,3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(2,3), warn_unused_result)); /****************************************************************//** Create parser info struct. @@ -628,7 +628,7 @@ pars_info_bind_ull_literal( pars_info_t* info, /*!< in: info struct */ const char* name, /*!< in: name */ const ib_uint64_t* val) /*!< in: value */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /****************************************************************//** Add bound id. */ diff --git a/storage/innobase/include/read0read.h b/storage/innobase/include/read0read.h index 980faddf98ecc..ae75cfac6f583 100644 --- a/storage/innobase/include/read0read.h +++ b/storage/innobase/include/read0read.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -82,7 +82,7 @@ read_view_sees_trx_id( /*==================*/ const read_view_t* view, /*!< in: read view */ trx_id_t trx_id) /*!< in: trx id */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Prints a read view to stderr. */ UNIV_INTERN diff --git a/storage/innobase/include/rem0cmp.h b/storage/innobase/include/rem0cmp.h index cb3c85ac2c8c2..65116229fdce4 100644 --- a/storage/innobase/include/rem0cmp.h +++ b/storage/innobase/include/rem0cmp.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -174,7 +174,7 @@ cmp_dtuple_rec_with_match_low( bytes within the first field not completely matched; when function returns, contains the value for current comparison */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #define cmp_dtuple_rec_with_match(tuple,rec,offsets,fields,bytes) \ cmp_dtuple_rec_with_match_low( \ tuple,rec,offsets,dtuple_get_n_fields_cmp(tuple),fields,bytes) @@ -218,7 +218,7 @@ cmp_rec_rec_simple( struct TABLE* table) /*!< in: MySQL table, for reporting duplicate key value if applicable, or NULL */ - __attribute__((nonnull(1,2,3,4), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,4), warn_unused_result)); /*************************************************************//** This function is used to compare two physical records. Only the common first fields are compared, and if an externally stored field is diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 8e7d5ff2d4893..971709fd2c871 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -98,7 +98,7 @@ rec_get_next_ptr_const( /*===================*/ const rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to get the pointer of the next chained record on the same page. @@ -109,7 +109,7 @@ rec_get_next_ptr( /*=============*/ rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to get the offset of the next chained record on the same page. @@ -120,7 +120,7 @@ rec_get_next_offs( /*==============*/ const rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the next record offset field of an old-style record. */ @@ -130,7 +130,7 @@ rec_set_next_offs_old( /*==================*/ rec_t* rec, /*!< in: old-style physical record */ ulint next) /*!< in: offset of the next record */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to set the next record offset field of a new-style record. */ @@ -140,7 +140,7 @@ rec_set_next_offs_new( /*==================*/ rec_t* rec, /*!< in/out: new-style physical record */ ulint next) /*!< in: offset of the next record */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to get the number of fields in an old-style record. @@ -150,7 +150,7 @@ ulint rec_get_n_fields_old( /*=================*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to get the number of fields in a record. @@ -161,7 +161,7 @@ rec_get_n_fields( /*=============*/ const rec_t* rec, /*!< in: physical record */ const dict_index_t* index) /*!< in: record descriptor */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to get the number of records owned by the previous directory record. @@ -171,7 +171,7 @@ ulint rec_get_n_owned_old( /*================*/ const rec_t* rec) /*!< in: old-style physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the number of owned records. */ UNIV_INLINE @@ -180,7 +180,7 @@ rec_set_n_owned_old( /*================*/ rec_t* rec, /*!< in: old-style physical record */ ulint n_owned) /*!< in: the number of owned */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to get the number of records owned by the previous directory record. @@ -190,7 +190,7 @@ ulint rec_get_n_owned_new( /*================*/ const rec_t* rec) /*!< in: new-style physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the number of owned records. */ UNIV_INLINE @@ -200,7 +200,7 @@ rec_set_n_owned_new( rec_t* rec, /*!< in/out: new-style physical record */ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */ ulint n_owned)/*!< in: the number of owned */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /******************************************************//** The following function is used to retrieve the info bits of a record. @@ -211,7 +211,7 @@ rec_get_info_bits( /*==============*/ const rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the info bits of a record. */ UNIV_INLINE @@ -220,7 +220,7 @@ rec_set_info_bits_old( /*==================*/ rec_t* rec, /*!< in: old-style physical record */ ulint bits) /*!< in: info bits */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to set the info bits of a record. */ UNIV_INLINE @@ -229,7 +229,7 @@ rec_set_info_bits_new( /*==================*/ rec_t* rec, /*!< in/out: new-style physical record */ ulint bits) /*!< in: info bits */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function retrieves the status bits of a new-style record. @return status bits */ @@ -238,7 +238,7 @@ ulint rec_get_status( /*===========*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the status bits of a new-style record. */ @@ -248,7 +248,7 @@ rec_set_status( /*===========*/ rec_t* rec, /*!< in/out: physical record */ ulint bits) /*!< in: info bits */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to retrieve the info and status @@ -260,7 +260,7 @@ rec_get_info_and_status_bits( /*=========================*/ const rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the info and status bits of a record. (Only compact records have status bits.) */ @@ -270,7 +270,7 @@ rec_set_info_and_status_bits( /*=========================*/ rec_t* rec, /*!< in/out: compact physical record */ ulint bits) /*!< in: info bits */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function tells if record is delete marked. @@ -281,7 +281,7 @@ rec_get_deleted_flag( /*=================*/ const rec_t* rec, /*!< in: physical record */ ulint comp) /*!< in: nonzero=compact page format */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the deleted bit. */ UNIV_INLINE @@ -290,7 +290,7 @@ rec_set_deleted_flag_old( /*=====================*/ rec_t* rec, /*!< in: old-style physical record */ ulint flag) /*!< in: nonzero if delete marked */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to set the deleted bit. */ UNIV_INLINE @@ -300,7 +300,7 @@ rec_set_deleted_flag_new( rec_t* rec, /*!< in/out: new-style physical record */ page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */ ulint flag) /*!< in: nonzero if delete marked */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /******************************************************//** The following function tells if a new-style record is a node pointer. @return TRUE if node pointer */ @@ -309,7 +309,7 @@ ibool rec_get_node_ptr_flag( /*==================*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to get the order number of an old-style record in the heap of the index page. @@ -319,7 +319,7 @@ ulint rec_get_heap_no_old( /*================*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the heap number field in an old-style record. */ @@ -329,7 +329,7 @@ rec_set_heap_no_old( /*================*/ rec_t* rec, /*!< in: physical record */ ulint heap_no)/*!< in: the heap number */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to get the order number of a new-style record in the heap of the index page. @@ -339,7 +339,7 @@ ulint rec_get_heap_no_new( /*================*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the heap number field in a new-style record. */ @@ -349,7 +349,7 @@ rec_set_heap_no_new( /*================*/ rec_t* rec, /*!< in/out: physical record */ ulint heap_no)/*!< in: the heap number */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** The following function is used to test whether the data offsets in the record are stored in one-byte or two-byte format. @@ -359,7 +359,7 @@ ibool rec_get_1byte_offs_flag( /*====================*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** The following function is used to set the 1-byte offsets flag. */ @@ -369,7 +369,7 @@ rec_set_1byte_offs_flag( /*====================*/ rec_t* rec, /*!< in: physical record */ ibool flag) /*!< in: TRUE if 1byte form */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** Returns the offset of nth field end if the record is stored in the 1-byte @@ -382,7 +382,7 @@ rec_1_get_field_end_info( /*=====================*/ const rec_t* rec, /*!< in: record */ ulint n) /*!< in: field index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Returns the offset of nth field end if the record is stored in the 2-byte @@ -396,7 +396,7 @@ rec_2_get_field_end_info( /*=====================*/ const rec_t* rec, /*!< in: record */ ulint n) /*!< in: field index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Returns nonzero if the field is stored off-page. @@ -408,7 +408,7 @@ rec_2_is_field_extern( /*==================*/ const rec_t* rec, /*!< in: record */ ulint n) /*!< in: field index */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Determine how many of the first n columns in a compact @@ -421,7 +421,7 @@ rec_get_n_extern_new( const rec_t* rec, /*!< in: compact physical record */ const dict_index_t* index, /*!< in: record descriptor */ ulint n) /*!< in: number of columns to scan */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************//** The following function determines the offsets to each field @@ -446,9 +446,9 @@ rec_get_offsets_func( #endif /* UNIV_DEBUG */ mem_heap_t** heap) /*!< in/out: memory heap */ #ifdef UNIV_DEBUG - __attribute__((nonnull(1,2,5,7),warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,5,7),warn_unused_result)); #else /* UNIV_DEBUG */ - __attribute__((nonnull(1,2,5),warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,5),warn_unused_result)); #endif /* UNIV_DEBUG */ #ifdef UNIV_DEBUG @@ -475,7 +475,7 @@ rec_get_offsets_reverse( 0=leaf node */ ulint* offsets)/*!< in/out: array consisting of offsets[0] allocated elements */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG /************************************************************//** Validates offsets returned by rec_get_offsets(). @@ -488,7 +488,7 @@ rec_offs_validate( const dict_index_t* index, /*!< in: record descriptor or NULL */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull(3), warn_unused_result)); + MY_ATTRIBUTE((nonnull(3), warn_unused_result)); /************************************************************//** Updates debug data in offsets, in order to avoid bogus rec_offs_validate() failures. */ @@ -500,7 +500,7 @@ rec_offs_make_valid( const dict_index_t* index, /*!< in: record descriptor */ ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #else # define rec_offs_make_valid(rec, index, offsets) ((void) 0) #endif /* UNIV_DEBUG */ @@ -517,7 +517,7 @@ rec_get_nth_field_offs_old( ulint n, /*!< in: index of the field */ ulint* len) /*!< out: length of the field; UNIV_SQL_NULL if SQL null */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #define rec_get_nth_field_old(rec, n, len) \ ((rec) + rec_get_nth_field_offs_old(rec, n, len)) /************************************************************//** @@ -531,7 +531,7 @@ rec_get_nth_field_size( /*===================*/ const rec_t* rec, /*!< in: record */ ulint n) /*!< in: index of the field */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /************************************************************//** The following function is used to get an offset to the nth data field in a record. @@ -544,7 +544,7 @@ rec_get_nth_field_offs( ulint n, /*!< in: index of the field */ ulint* len) /*!< out: length of the field; UNIV_SQL_NULL if SQL null */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #define rec_get_nth_field(rec, offsets, n, len) \ ((rec) + rec_get_nth_field_offs(offsets, n, len)) /******************************************************//** @@ -556,7 +556,7 @@ ulint rec_offs_comp( /*==========*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Determine if the offsets are for a record containing externally stored columns. @@ -566,7 +566,7 @@ ulint rec_offs_any_extern( /*================*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Determine if the offsets are for a record containing null BLOB pointers. @return first field containing a null BLOB pointer, or NULL if none found */ @@ -576,7 +576,7 @@ rec_offs_any_null_extern( /*=====================*/ const rec_t* rec, /*!< in: record */ const ulint* offsets) /*!< in: rec_get_offsets(rec) */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Returns nonzero if the extern bit is set in nth field of rec. @return nonzero if externally stored */ @@ -586,7 +586,7 @@ rec_offs_nth_extern( /*================*/ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ ulint n) /*!< in: nth field */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Returns nonzero if the SQL NULL bit is set in nth field of rec. @return nonzero if SQL NULL */ @@ -596,7 +596,7 @@ rec_offs_nth_sql_null( /*==================*/ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ ulint n) /*!< in: nth field */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Gets the physical size of a field. @return length of field */ @@ -606,7 +606,7 @@ rec_offs_nth_size( /*==============*/ const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ ulint n) /*!< in: nth field */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /******************************************************//** Returns the number of extern bits set in a record. @@ -616,7 +616,7 @@ ulint rec_offs_n_extern( /*==============*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /***********************************************************//** This is used to modify the value of an already existing field in a record. The previous value must have exactly the same size as the new value. If len @@ -636,7 +636,7 @@ rec_set_nth_field( length as the previous value. If SQL null, previous value must be SQL null. */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /**********************************************************//** The following function returns the data size of an old-style physical record, that is the sum of field lengths. SQL null fields @@ -648,7 +648,7 @@ ulint rec_get_data_size_old( /*==================*/ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /**********************************************************//** The following function returns the number of allocated elements for an array of offsets. @@ -658,7 +658,7 @@ ulint rec_offs_get_n_alloc( /*=================*/ const ulint* offsets)/*!< in: array for rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /**********************************************************//** The following function sets the number of allocated elements for an array of offsets. */ @@ -669,7 +669,7 @@ rec_offs_set_n_alloc( ulint* offsets, /*!< out: array for rec_get_offsets(), must be allocated */ ulint n_alloc) /*!< in: number of elements */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #define rec_offs_init(offsets) \ rec_offs_set_n_alloc(offsets, (sizeof offsets) / sizeof *offsets) /**********************************************************//** @@ -680,7 +680,7 @@ ulint rec_offs_n_fields( /*==============*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /**********************************************************//** The following function returns the data size of a physical record, that is the sum of field lengths. SQL null fields @@ -692,7 +692,7 @@ ulint rec_offs_data_size( /*===============*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /**********************************************************//** Returns the total size of record minus data size of record. The value returned by the function is the distance from record @@ -703,7 +703,7 @@ ulint rec_offs_extra_size( /*================*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /**********************************************************//** Returns the total size of a physical record. @return size */ @@ -712,7 +712,7 @@ ulint rec_offs_size( /*==========*/ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #ifdef UNIV_DEBUG /**********************************************************//** Returns a pointer to the start of the record. @@ -723,7 +723,7 @@ rec_get_start( /*==========*/ const rec_t* rec, /*!< in: pointer to record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); /**********************************************************//** Returns a pointer to the end of the record. @return pointer to end */ @@ -733,7 +733,7 @@ rec_get_end( /*========*/ const rec_t* rec, /*!< in: pointer to record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #else /* UNIV_DEBUG */ # define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets)) # define rec_get_end(rec, offsets) ((rec) + rec_offs_data_size(offsets)) @@ -748,7 +748,7 @@ rec_copy( void* buf, /*!< in: buffer */ const rec_t* rec, /*!< in: physical record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /**********************************************************//** Determines the size of a data tuple prefix in a temporary file. @@ -761,7 +761,7 @@ rec_get_converted_size_temp( const dfield_t* fields, /*!< in: array of data fields */ ulint n_fields,/*!< in: number of data fields */ ulint* extra) /*!< out: extra size */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /******************************************************//** Determine the offset to each field in temporary file. @@ -774,7 +774,7 @@ rec_init_offsets_temp( const dict_index_t* index, /*!< in: record descriptor */ ulint* offsets)/*!< in/out: array of offsets; in: n=rec_offs_n_fields(offsets) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************//** Builds a temporary file record out of a data tuple. @@ -787,7 +787,7 @@ rec_convert_dtuple_to_temp( const dict_index_t* index, /*!< in: record descriptor */ const dfield_t* fields, /*!< in: array of data fields */ ulint n_fields) /*!< in: number of fields */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**************************************************************//** Copies the first n fields of a physical record to a new physical record in @@ -805,7 +805,7 @@ rec_copy_prefix_to_buf( for the copied prefix, or NULL */ ulint* buf_size) /*!< in/out: buffer size */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /************************************************************//** Folds a prefix of a physical record to a ulint. @return the folded value */ @@ -821,7 +821,7 @@ rec_fold( ulint n_bytes, /*!< in: number of bytes to fold in an incomplete last field */ index_id_t tree_id) /*!< in: index tree id */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /*********************************************************//** Builds a physical record out of a data tuple and @@ -837,7 +837,7 @@ rec_convert_dtuple_to_rec( const dtuple_t* dtuple, /*!< in: data tuple */ ulint n_ext) /*!< in: number of externally stored columns */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /**********************************************************//** Returns the extra size of an old-style physical record if we know its data size and number of fields. @@ -849,7 +849,7 @@ rec_get_converted_extra_size( ulint data_size, /*!< in: data size */ ulint n_fields, /*!< in: number of fields */ ulint n_ext) /*!< in: number of externally stored columns */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /**********************************************************//** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. @return total size */ @@ -861,7 +861,7 @@ rec_get_converted_size_comp_prefix( const dfield_t* fields, /*!< in: array of data fields */ ulint n_fields,/*!< in: number of data fields */ ulint* extra) /*!< out: extra size */ - __attribute__((warn_unused_result, nonnull(1,2))); + MY_ATTRIBUTE((warn_unused_result, nonnull(1,2))); /**********************************************************//** Determines the size of a data tuple in ROW_FORMAT=COMPACT. @return total size */ @@ -877,7 +877,7 @@ rec_get_converted_size_comp( const dfield_t* fields, /*!< in: array of data fields */ ulint n_fields,/*!< in: number of data fields */ ulint* extra) /*!< out: extra size */ - __attribute__((nonnull(1,3))); + MY_ATTRIBUTE((nonnull(1,3))); /**********************************************************//** The following function returns the size of a data tuple when converted to a physical record. @@ -889,7 +889,7 @@ rec_get_converted_size( dict_index_t* index, /*!< in: record descriptor */ const dtuple_t* dtuple, /*!< in: data tuple */ ulint n_ext) /*!< in: number of externally stored columns */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); #ifndef UNIV_HOTBACKUP /**************************************************************//** Copies the first n fields of a physical record to a data tuple. @@ -904,7 +904,7 @@ rec_copy_prefix_to_dtuple( ulint n_fields, /*!< in: number of fields to copy */ mem_heap_t* heap) /*!< in: memory heap */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /***************************************************************//** Validates the consistency of a physical record. @@ -915,7 +915,7 @@ rec_validate( /*=========*/ const rec_t* rec, /*!< in: physical record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***************************************************************//** Prints an old-style physical record. */ UNIV_INTERN @@ -924,7 +924,7 @@ rec_print_old( /*==========*/ FILE* file, /*!< in: file where to print */ const rec_t* rec) /*!< in: physical record */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_HOTBACKUP /***************************************************************//** Prints a physical record in ROW_FORMAT=COMPACT. Ignores the @@ -936,7 +936,7 @@ rec_print_comp( FILE* file, /*!< in: file where to print */ const rec_t* rec, /*!< in: physical record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***************************************************************//** Prints a physical record. */ UNIV_INTERN @@ -946,7 +946,7 @@ rec_print_new( FILE* file, /*!< in: file where to print */ const rec_t* rec, /*!< in: physical record */ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***************************************************************//** Prints a physical record. */ UNIV_INTERN @@ -956,7 +956,7 @@ rec_print( FILE* file, /*!< in: file where to print */ const rec_t* rec, /*!< in: physical record */ const dict_index_t* index) /*!< in: record descriptor */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); # ifdef UNIV_DEBUG /************************************************************//** @@ -968,7 +968,7 @@ rec_get_trx_id( /*===========*/ const rec_t* rec, /*!< in: record */ const dict_index_t* index) /*!< in: clustered index */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); # endif /* UNIV_DEBUG */ #endif /* UNIV_HOTBACKUP */ diff --git a/storage/innobase/include/rem0rec.ic b/storage/innobase/include/rem0rec.ic index a539320dd2a4e..5811a77a48b76 100644 --- a/storage/innobase/include/rem0rec.ic +++ b/storage/innobase/include/rem0rec.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1540,7 +1540,8 @@ rec_copy( ulint extra_len; ulint data_len; - ut_ad(rec && buf); + ut_ad(rec != NULL); + ut_ad(buf != NULL); ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_validate(rec, offsets)); diff --git a/storage/innobase/include/row0ftsort.h b/storage/innobase/include/row0ftsort.h index 4e04a099140be..e949ba302b94b 100644 --- a/storage/innobase/include/row0ftsort.h +++ b/storage/innobase/include/row0ftsort.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2010, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -187,7 +187,7 @@ row_fts_psort_info_init( instantiated */ fts_psort_t** merge) /*!< out: parallel merge info to be instantiated */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Clean up and deallocate FTS parallel sort structures, and close temparary merge sort files */ @@ -275,5 +275,5 @@ row_fts_merge_insert( fts_psort_t* psort_info, /*!< parallel sort info */ ulint id) /* !< in: which auxiliary table's data to insert to */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* row0ftsort_h */ diff --git a/storage/innobase/include/row0import.h b/storage/innobase/include/row0import.h index aa46fdb7c27b2..a821c230a3b26 100644 --- a/storage/innobase/include/row0import.h +++ b/storage/innobase/include/row0import.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -46,7 +46,7 @@ row_import_for_mysql( dict_table_t* table, /*!< in/out: table */ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Update the DICT_TF2_DISCARDED flag in SYS_TABLES. @@ -64,7 +64,7 @@ row_import_update_discarded_flag( bool dict_locked) /*!< in: Set to true if the caller already owns the dict_sys_t:: mutex. */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Update the (space, root page) of a table's indexes from the values @@ -83,7 +83,7 @@ row_import_update_index_root( bool dict_locked) /*!< in: Set to true if the caller already owns the dict_sys_t:: mutex. */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "row0import.ic" #endif diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index 2a892d2f5dfc8..71ee39070ef2d 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -53,7 +53,7 @@ row_ins_check_foreign_constraint( table, else the referenced table */ dtuple_t* entry, /*!< in: index entry for index */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Creates an insert node struct. @return own: insert node struct */ @@ -98,7 +98,7 @@ row_ins_clust_index_entry_low( dtuple_t* entry, /*!< in/out: index entry to insert */ ulint n_ext, /*!< in: number of externally stored columns */ que_thr_t* thr) /*!< in: query thread or NULL */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***************************************************************//** Tries to insert an entry into a secondary index. If a record with exactly the same fields is found, the other record is necessarily marked deleted. @@ -123,7 +123,7 @@ row_ins_sec_index_entry_low( trx_id_t trx_id, /*!< in: PAGE_MAX_TRX_ID during row_log_table_apply(), or 0 */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***************************************************************//** Tries to insert the externally stored fields (off-page columns) of a clustered index entry. @@ -142,7 +142,7 @@ row_ins_index_entry_big_rec_func( const void* thd, /*!< in: connection, or NULL */ #endif /* DBUG_OFF */ ulint line) /*!< in: line number of caller */ - __attribute__((nonnull(1,2,3,4,5,6), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,4,5,6), warn_unused_result)); #ifdef DBUG_OFF # define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd,file,line) \ row_ins_index_entry_big_rec_func(e,big,ofs,heap,index,file,line) @@ -164,7 +164,7 @@ row_ins_clust_index_entry( dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr, /*!< in: query thread */ ulint n_ext) /*!< in: number of externally stored columns */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***************************************************************//** Inserts an entry into a secondary index. Tries first optimistic, then pessimistic descent down the tree. If the entry matches enough @@ -178,7 +178,7 @@ row_ins_sec_index_entry( dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************//** Inserts a row to a table. This is a high-level function used in SQL execution graphs. diff --git a/storage/innobase/include/row0log.h b/storage/innobase/include/row0log.h index 5eed390acedbc..ec14556588b85 100644 --- a/storage/innobase/include/row0log.h +++ b/storage/innobase/include/row0log.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -54,7 +54,7 @@ row_log_allocate( const ulint* col_map,/*!< in: mapping of old column numbers to new ones, or NULL if !table */ const char* path) /*!< in: where to create temporary file */ - __attribute__((nonnull(1), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1), warn_unused_result)); /******************************************************//** Free the row log for an index that was being created online. */ @@ -63,7 +63,7 @@ void row_log_free( /*=========*/ row_log_t*& log) /*!< in,own: row log */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** Free the row log for an index on which online creation was aborted. */ @@ -72,7 +72,7 @@ void row_log_abort_sec( /*==============*/ dict_index_t* index) /*!< in/out: index (x-latched) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************//** Try to log an operation to a secondary index that is @@ -87,7 +87,7 @@ row_log_online_op_try( const dtuple_t* tuple, /*!< in: index tuple */ trx_id_t trx_id) /*!< in: transaction ID for insert, or 0 for delete */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************//** Logs an operation to a secondary index that is (or was) being created. */ UNIV_INTERN @@ -98,7 +98,7 @@ row_log_online_op( const dtuple_t* tuple, /*!< in: index tuple */ trx_id_t trx_id) /*!< in: transaction ID for insert, or 0 for delete */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /******************************************************//** Gets the error status of the online index rebuild log. @@ -109,7 +109,7 @@ row_log_table_get_error( /*====================*/ const dict_index_t* index) /*!< in: clustered index of a table that is being rebuilt online */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************//** Logs a delete operation to a table that is being rebuilt. @@ -125,7 +125,7 @@ row_log_table_delete( const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */ const byte* sys) /*!< in: DB_TRX_ID,DB_ROLL_PTR that should be logged, or NULL to use those in rec */ - UNIV_COLD __attribute__((nonnull(1,2,3))); + UNIV_COLD MY_ATTRIBUTE((nonnull(1,2,3))); /******************************************************//** Logs an update operation to a table that is being rebuilt. @@ -141,7 +141,7 @@ row_log_table_update( const ulint* offsets,/*!< in: rec_get_offsets(rec,index) */ const dtuple_t* old_pk) /*!< in: row_log_table_get_pk() before the update */ - UNIV_COLD __attribute__((nonnull(1,2,3))); + UNIV_COLD MY_ATTRIBUTE((nonnull(1,2,3))); /******************************************************//** Constructs the old PRIMARY KEY and DB_TRX_ID,DB_ROLL_PTR @@ -161,7 +161,7 @@ row_log_table_get_pk( byte* sys, /*!< out: DB_TRX_ID,DB_ROLL_PTR for row_log_table_delete(), or NULL */ mem_heap_t** heap) /*!< in/out: memory heap where allocated */ - UNIV_COLD __attribute__((nonnull(1,2,5), warn_unused_result)); + UNIV_COLD MY_ATTRIBUTE((nonnull(1,2,5), warn_unused_result)); /******************************************************//** Logs an insert to a table that is being rebuilt. @@ -175,7 +175,7 @@ row_log_table_insert( dict_index_t* index, /*!< in/out: clustered index, S-latched or X-latched */ const ulint* offsets)/*!< in: rec_get_offsets(rec,index) */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /******************************************************//** Notes that a BLOB is being freed during online ALTER TABLE. */ UNIV_INTERN @@ -184,7 +184,7 @@ row_log_table_blob_free( /*====================*/ dict_index_t* index, /*!< in/out: clustered index, X-latched */ ulint page_no)/*!< in: starting page number of the BLOB */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /******************************************************//** Notes that a BLOB is being allocated during online ALTER TABLE. */ UNIV_INTERN @@ -193,7 +193,7 @@ row_log_table_blob_alloc( /*=====================*/ dict_index_t* index, /*!< in/out: clustered index, X-latched */ ulint page_no)/*!< in: starting page number of the BLOB */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /******************************************************//** Apply the row_log_table log to a table upon completing rebuild. @return DB_SUCCESS, or error code on failure */ @@ -206,7 +206,7 @@ row_log_table_apply( /*!< in: old table */ struct TABLE* table) /*!< in/out: MySQL table (for reporting duplicates) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************//** Get the latest transaction ID that has invoked row_log_online_op() @@ -217,7 +217,7 @@ trx_id_t row_log_get_max_trx( /*================*/ dict_index_t* index) /*!< in: index, must be locked */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************//** Merge the row log to the index upon completing index creation. @@ -231,7 +231,7 @@ row_log_apply( dict_index_t* index, /*!< in/out: secondary index */ struct TABLE* table) /*!< in/out: MySQL table (for reporting duplicates) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "row0log.ic" diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index 06e9fec544b59..9d3395f373456 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -127,7 +127,7 @@ row_merge_dup_report( /*=================*/ row_merge_dup_t* dup, /*!< in/out: for reporting duplicates */ const dfield_t* entry) /*!< in: duplicate index entry */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Sets an exclusive lock on a table, for the duration of creating indexes. @return error code or DB_SUCCESS */ @@ -138,7 +138,7 @@ row_merge_lock_table( trx_t* trx, /*!< in/out: transaction */ dict_table_t* table, /*!< in: table to lock */ enum lock_mode mode) /*!< in: LOCK_X or LOCK_S */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Drop indexes that were created before an error occurred. The data dictionary must have been locked exclusively by the caller, @@ -149,7 +149,7 @@ row_merge_drop_indexes_dict( /*========================*/ trx_t* trx, /*!< in/out: dictionary transaction */ table_id_t table_id)/*!< in: table identifier */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Drop those indexes which were created before an error occurred. The data dictionary must have been locked exclusively by the caller, @@ -162,7 +162,7 @@ row_merge_drop_indexes( dict_table_t* table, /*!< in/out: table containing the indexes */ ibool locked) /*!< in: TRUE=table locked, FALSE=may need to do a lazy drop */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Drop all partially created indexes during crash recovery. */ UNIV_INTERN @@ -178,7 +178,7 @@ UNIV_INTERN int row_merge_file_create_low( const char* path) - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /*********************************************************************//** Destroy a merge file. And de-register the file from Performance Schema if UNIV_PFS_IO is defined. */ @@ -214,7 +214,7 @@ row_merge_rename_tables_dict( old_table->name */ const char* tmp_name, /*!< in: new name for old_table */ trx_t* trx) /*!< in/out: dictionary transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Rename an index in the dictionary that was created. The data @@ -228,7 +228,7 @@ row_merge_rename_index_to_add( trx_t* trx, /*!< in/out: transaction */ table_id_t table_id, /*!< in: table identifier */ index_id_t index_id) /*!< in: index identifier */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Rename an index in the dictionary that is to be dropped. The data dictionary must have been locked exclusively by the caller, because @@ -241,7 +241,7 @@ row_merge_rename_index_to_drop( trx_t* trx, /*!< in/out: transaction */ table_id_t table_id, /*!< in: table identifier */ index_id_t index_id) /*!< in: index identifier */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Create the index and load in to the dictionary. @return index, or NULL on error */ @@ -274,7 +274,7 @@ row_merge_drop_table( /*=================*/ trx_t* trx, /*!< in: transaction */ dict_table_t* table) /*!< in: table instance to drop */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Build indexes on a table by reading a clustered index, creating a temporary file containing index entries, merge sorting @@ -307,7 +307,7 @@ row_merge_build_indexes( AUTO_INCREMENT column, or ULINT_UNDEFINED if none is added */ ib_sequence_t& sequence) /*!< in/out: autoinc sequence */ - __attribute__((nonnull(1,2,3,5,6,8), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,5,6,8), warn_unused_result)); /********************************************************************//** Write a buffer to a block. */ UNIV_INTERN @@ -317,7 +317,7 @@ row_merge_buf_write( const row_merge_buf_t* buf, /*!< in: sorted buffer */ const merge_file_t* of, /*!< in: output file */ row_merge_block_t* block) /*!< out: buffer for writing to file */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Sort a buffer. */ UNIV_INTERN @@ -327,7 +327,7 @@ row_merge_buf_sort( row_merge_buf_t* buf, /*!< in/out: sort buffer */ row_merge_dup_t* dup) /*!< in/out: reporter of duplicates (NULL if non-unique index) */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /********************************************************************//** Write a merge block to the file system. @return TRUE if request was successful, FALSE if fail */ @@ -347,7 +347,7 @@ row_merge_buf_t* row_merge_buf_empty( /*================*/ row_merge_buf_t* buf) /*!< in,own: sort buffer */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /** Create a merge file in the given location. @param[out] merge_file merge file structure @@ -373,7 +373,7 @@ row_merge_sort( index entries */ row_merge_block_t* block, /*!< in/out: 3 buffers */ int* tmpfd) /*!< in/out: temporary file handle */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Allocate a sort buffer. @return own: sort buffer */ @@ -382,7 +382,7 @@ row_merge_buf_t* row_merge_buf_create( /*=================*/ dict_index_t* index) /*!< in: secondary index */ - __attribute__((warn_unused_result, nonnull, malloc)); + MY_ATTRIBUTE((warn_unused_result, nonnull, malloc)); /*********************************************************************//** Deallocate a sort buffer. */ UNIV_INTERN @@ -390,7 +390,7 @@ void row_merge_buf_free( /*===============*/ row_merge_buf_t* buf) /*!< in,own: sort buffer to be freed */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Destroy a merge file. */ UNIV_INTERN @@ -398,7 +398,7 @@ void row_merge_file_destroy( /*===================*/ merge_file_t* merge_file) /*!< in/out: merge file structure */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Read a merge block from the file system. @return TRUE if request was successful, FALSE if fail */ @@ -428,5 +428,5 @@ row_merge_read_rec( or NULL on end of list (non-NULL on I/O error) */ ulint* offsets)/*!< out: offsets of mrec */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* row0merge.h */ diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 06c07002c2b59..fc1846b76f312 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -167,7 +167,7 @@ row_mysql_handle_errors( trx_t* trx, /*!< in: transaction */ que_thr_t* thr, /*!< in: query thread, or NULL */ trx_savept_t* savept) /*!< in: savepoint, or NULL */ - __attribute__((nonnull(1,2))); + MY_ATTRIBUTE((nonnull(1,2))); /********************************************************************//** Create a prebuilt struct for a MySQL table handle. @return own: a prebuilt struct */ @@ -209,7 +209,7 @@ row_lock_table_autoinc_for_mysql( /*=============================*/ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL table handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Sets a table lock on the table mentioned in prebuilt. @return error code or DB_SUCCESS */ @@ -225,7 +225,7 @@ row_lock_table_for_mysql( prebuilt->select_lock_type */ ulint mode) /*!< in: lock mode of table (ignored if table==NULL) */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /*********************************************************************//** Does an insert for MySQL. @return error code or DB_SUCCESS */ @@ -236,7 +236,7 @@ row_insert_for_mysql( byte* mysql_rec, /*!< in: row in the MySQL format */ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Builds a dummy query graph used in selects. */ UNIV_INTERN @@ -276,7 +276,7 @@ row_update_for_mysql( the MySQL format */ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this session is using a READ COMMITTED or READ UNCOMMITTED isolation level. @@ -297,7 +297,7 @@ row_unlock_for_mysql( the records under pcur and clust_pcur, and we do not need to reposition the cursors. */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Checks if a table name contains the string "/#sql" which denotes temporary tables in MySQL. @@ -306,7 +306,7 @@ UNIV_INTERN bool row_is_mysql_tmp_table_name( /*========================*/ - const char* name) __attribute__((warn_unused_result)); + const char* name) MY_ATTRIBUTE((warn_unused_result)); /*!< in: table name in the form 'database/tablename' */ @@ -331,7 +331,7 @@ row_update_cascade_for_mysql( upd_node_t* node, /*!< in: update node used in the cascade or set null operation */ dict_table_t* table) /*!< in: table where we do the operation */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Locks the data dictionary exclusively for performing a table create or other data dictionary modification operation. */ @@ -387,7 +387,7 @@ row_create_table_for_mysql( added to the data dictionary cache) */ trx_t* trx, /*!< in/out: transaction */ bool commit) /*!< in: if true, commit the transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Does an index creation operation for MySQL. TODO: currently failure to create an index results in dropping the whole table! This is no problem @@ -406,7 +406,7 @@ row_create_index_for_mysql( index columns, which are then checked for not being too large. */ - __attribute__((nonnull(1,2), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2), warn_unused_result)); /*********************************************************************//** Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function @@ -432,7 +432,7 @@ row_table_add_foreign_constraints( ibool reject_fks) /*!< in: if TRUE, fail with error code DB_CANNOT_ADD_CONSTRAINT if any foreign keys are found. */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** The master thread in srv0srv.cc calls this regularly to drop tables which we must drop in background after queries to them have ended. Such lazy @@ -461,7 +461,7 @@ row_mysql_lock_table( dict_table_t* table, /*!< in: table to lock */ enum lock_mode mode, /*!< in: LOCK_X or LOCK_S */ const char* op_info) /*!< in: string for trx->op_info */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Truncates a table for MySQL. @@ -472,7 +472,7 @@ row_truncate_table_for_mysql( /*=========================*/ dict_table_t* table, /*!< in: table handle */ trx_t* trx) /*!< in: transaction handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Drops a table for MySQL. If the name of the dropped table ends in one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor", @@ -491,7 +491,7 @@ row_drop_table_for_mysql( bool nonatomic = true) /*!< in: whether it is permitted to release and reacquire dict_operation_lock */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Drop all temporary tables during crash recovery. */ UNIV_INTERN @@ -510,7 +510,7 @@ row_discard_tablespace_for_mysql( /*=============================*/ const char* name, /*!< in: table name */ trx_t* trx) /*!< in: transaction handle */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Imports a tablespace. The space id in the .ibd file must match the space id of the table in the data dictionary. @@ -521,7 +521,7 @@ row_import_tablespace_for_mysql( /*============================*/ dict_table_t* table, /*!< in/out: table */ row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Drops a database for MySQL. @return error code or DB_SUCCESS */ @@ -531,7 +531,7 @@ row_drop_database_for_mysql( /*========================*/ const char* name, /*!< in: database name which ends to '/' */ trx_t* trx) /*!< in: transaction handle */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Renames a table for MySQL. @return error code or DB_SUCCESS */ @@ -543,7 +543,7 @@ row_rename_table_for_mysql( const char* new_name, /*!< in: new table name */ trx_t* trx, /*!< in/out: transaction */ bool commit) /*!< in: whether to commit trx */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Checks that the index contains entries in an ascending order, unique constraint is not broken, and calculates the number of index entries @@ -558,7 +558,7 @@ row_check_index_for_mysql( const dict_index_t* index, /*!< in: index */ ulint* n_rows) /*!< out: number of entries seen in the consistent read */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Determines if a table is a magic monitor table. @return true if monitor table */ @@ -568,7 +568,7 @@ row_is_magic_monitor_table( /*=======================*/ const char* table_name) /*!< in: name of the table, in the form database/table_name */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Initialize this module */ UNIV_INTERN @@ -593,7 +593,7 @@ row_mysql_table_id_reassign( dict_table_t* table, /*!< in/out: table */ trx_t* trx, /*!< in/out: transaction */ table_id_t* new_id) /*!< out: new table id */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /* A struct describing a place for an individual column in the MySQL row format which is presented to the table handler in ha_innobase. diff --git a/storage/innobase/include/row0purge.h b/storage/innobase/include/row0purge.h index 888289a6c79bb..5df899bc39937 100644 --- a/storage/innobase/include/row0purge.h +++ b/storage/innobase/include/row0purge.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -47,7 +47,7 @@ row_purge_node_create( que_thr_t* parent, /*!< in: parent node, i.e., a thr node */ mem_heap_t* heap) /*!< in: memory heap where created */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************//** Determines if it is possible to remove a secondary index entry. Removal is possible if the secondary index entry does not refer to any @@ -70,7 +70,7 @@ row_purge_poss_sec( purge_node_t* node, /*!< in/out: row purge node */ dict_index_t* index, /*!< in: secondary index */ const dtuple_t* entry) /*!< in: secondary index entry */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*************************************************************** Does the purge operation for a single undo log record. This is a high-level function used in an SQL execution graph. @@ -80,7 +80,7 @@ que_thr_t* row_purge_step( /*===========*/ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /* Purge node structure */ diff --git a/storage/innobase/include/row0quiesce.h b/storage/innobase/include/row0quiesce.h index 1d6d11291b831..35d8184d33c1c 100644 --- a/storage/innobase/include/row0quiesce.h +++ b/storage/innobase/include/row0quiesce.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -43,7 +43,7 @@ row_quiesce_table_start( /*====================*/ dict_table_t* table, /*!< in: quiesce this table */ trx_t* trx) /*!< in/out: transaction/session */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*********************************************************************//** Set a table's quiesce state. @@ -55,7 +55,7 @@ row_quiesce_set_state( dict_table_t* table, /*!< in: quiesce this table */ ib_quiesce_t state, /*!< in: quiesce state to set */ trx_t* trx) /*!< in/out: transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Cleanup after table quiesce. */ @@ -65,7 +65,7 @@ row_quiesce_table_complete( /*=======================*/ dict_table_t* table, /*!< in: quiesce this table */ trx_t* trx) /*!< in/out: transaction/session */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_NONINL #include "row0quiesce.ic" diff --git a/storage/innobase/include/row0row.h b/storage/innobase/include/row0row.h index a4e5e0dd2fa2e..b04068c5a5d0b 100644 --- a/storage/innobase/include/row0row.h +++ b/storage/innobase/include/row0row.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -47,7 +47,7 @@ row_get_trx_id_offset( /*==================*/ const dict_index_t* index, /*!< in: clustered index */ const ulint* offsets)/*!< in: record offsets */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Reads the trx id field from a clustered index record. @return value of the field */ @@ -58,7 +58,7 @@ row_get_rec_trx_id( const rec_t* rec, /*!< in: record */ const dict_index_t* index, /*!< in: clustered index */ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Reads the roll pointer field from a clustered index record. @return value of the field */ @@ -69,7 +69,7 @@ row_get_rec_roll_ptr( const rec_t* rec, /*!< in: record */ const dict_index_t* index, /*!< in: clustered index */ const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** When an insert or purge to a table is performed, this function builds the entry to be inserted into or purged from an index on the table. @@ -88,7 +88,7 @@ row_build_index_entry_low( mem_heap_t* heap) /*!< in: memory heap from which the memory for the index entry is allocated */ - __attribute__((warn_unused_result, nonnull(1,3,4))); + MY_ATTRIBUTE((warn_unused_result, nonnull(1,3,4))); /*****************************************************************//** When an insert or purge to a table is performed, this function builds the entry to be inserted into or purged from an index on the table. @@ -107,7 +107,7 @@ row_build_index_entry( mem_heap_t* heap) /*!< in: memory heap from which the memory for the index entry is allocated */ - __attribute__((warn_unused_result, nonnull(1,3,4))); + MY_ATTRIBUTE((warn_unused_result, nonnull(1,3,4))); /*******************************************************************//** An inverse function to row_build_index_entry. Builds a row from a record in a clustered index. @@ -155,7 +155,7 @@ row_build( prefixes, or NULL */ mem_heap_t* heap) /*!< in: memory heap from which the memory needed is allocated */ - __attribute__((nonnull(2,3,9))); + MY_ATTRIBUTE((nonnull(2,3,9))); /*******************************************************************//** Converts an index record to a typed data tuple. @return index entry built; does not set info_bits, and the data fields @@ -171,7 +171,7 @@ row_rec_to_index_entry_low( stored columns */ mem_heap_t* heap) /*!< in: memory heap from which the memory needed is allocated */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Converts an index record to a typed data tuple. NOTE that externally stored (often big) fields are NOT copied to heap. @@ -187,7 +187,7 @@ row_rec_to_index_entry( stored columns */ mem_heap_t* heap) /*!< in: memory heap from which the memory needed is allocated */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Builds from a secondary index record a row reference with which we can search the clustered index record. @@ -210,7 +210,7 @@ row_build_row_ref( as long as the row reference is used! */ mem_heap_t* heap) /*!< in: memory heap from which the memory needed is allocated */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Builds from a secondary index record a row reference with which we can search the clustered index record. */ @@ -232,7 +232,7 @@ row_build_row_ref_in_tuple( ulint* offsets,/*!< in: rec_get_offsets(rec, index) or NULL */ trx_t* trx) /*!< in: transaction or NULL */ - __attribute__((nonnull(1,2,3))); + MY_ATTRIBUTE((nonnull(1,2,3))); /*******************************************************************//** Builds from a secondary index record a row reference with which we can search the clustered index record. */ @@ -263,7 +263,7 @@ row_search_on_row_ref( const dict_table_t* table, /*!< in: table */ const dtuple_t* ref, /*!< in: row reference */ mtr_t* mtr) /*!< in/out: mtr */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** Fetches the clustered index record for a secondary index record. The latches on the secondary index record are preserved. @@ -277,7 +277,7 @@ row_get_clust_rec( dict_index_t* index, /*!< in: secondary index */ dict_index_t** clust_index,/*!< out: clustered index */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Result of row_search_index_entry */ enum row_search_result { @@ -305,7 +305,7 @@ row_search_index_entry( btr_pcur_t* pcur, /*!< in/out: persistent cursor, which must be closed by the caller */ mtr_t* mtr) /*!< in: mtr */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #define ROW_COPY_DATA 1 #define ROW_COPY_POINTERS 2 @@ -334,7 +334,7 @@ row_raw_format( char* buf, /*!< out: output buffer */ ulint buf_size) /*!< in: output buffer size in bytes */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "row0row.ic" diff --git a/storage/innobase/include/row0sel.h b/storage/innobase/include/row0sel.h index c8be80f89d9cb..fd5bc755a22a1 100644 --- a/storage/innobase/include/row0sel.h +++ b/storage/innobase/include/row0sel.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -168,7 +168,7 @@ row_search_for_mysql( then prebuilt must have a pcur with stored position! In opening of a cursor 'direction' should be 0. */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Checks if MySQL at the moment is allowed for this table to retrieve a consistent read result, or store it to the query cache. @@ -190,7 +190,7 @@ row_search_max_autoinc( dict_index_t* index, /*!< in: index to search */ const char* col_name, /*!< in: autoinc column name */ ib_uint64_t* value) /*!< out: AUTOINC value read */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /** A structure for caching column values for prefetched rows */ struct sel_buf_t{ diff --git a/storage/innobase/include/row0uins.h b/storage/innobase/include/row0uins.h index ebf4881208a4e..89e334e5433df 100644 --- a/storage/innobase/include/row0uins.h +++ b/storage/innobase/include/row0uins.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -46,7 +46,7 @@ dberr_t row_undo_ins( /*=========*/ undo_node_t* node) /*!< in: row undo node */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "row0uins.ic" #endif diff --git a/storage/innobase/include/row0umod.h b/storage/innobase/include/row0umod.h index f89d5a334fc31..4f1d8e1f66c53 100644 --- a/storage/innobase/include/row0umod.h +++ b/storage/innobase/include/row0umod.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -43,7 +43,7 @@ row_undo_mod( /*=========*/ undo_node_t* node, /*!< in: row undo node */ que_thr_t* thr) /*!< in: query thread */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #ifndef UNIV_NONINL #include "row0umod.ic" diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index 27dedeb65a7f6..e59ec58b63c1b 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -91,7 +91,7 @@ upd_get_field_by_field_no( /*======================*/ const upd_t* update, /*!< in: update vector */ ulint no) /*!< in: field_no */ - __attribute__((nonnull, pure)); + MY_ATTRIBUTE((nonnull, pure)); /*********************************************************************//** Writes into the redo log the values of trx id and roll ptr and enough info to determine their positions within a clustered index record. @@ -174,7 +174,7 @@ bool row_upd_changes_disowned_external( /*==============================*/ const upd_t* update) /*!< in: update vector */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** Replaces the new column values stored in the update vector to the @@ -207,7 +207,7 @@ row_upd_build_sec_rec_difference_binary( const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const dtuple_t* entry, /*!< in: entry to insert */ mem_heap_t* heap) /*!< in: memory heap from which allocated */ - __attribute__((warn_unused_result, nonnull)); + MY_ATTRIBUTE((warn_unused_result, nonnull)); /***************************************************************//** Builds an update vector from those fields, excluding the roll ptr and trx id fields, which in an index entry differ from a record that has @@ -227,7 +227,7 @@ row_upd_build_difference_binary( trx_t* trx, /*!< in: transaction (for diagnostics), or NULL */ mem_heap_t* heap) /*!< in: memory heap from which allocated */ - __attribute__((nonnull(1,2,3,7), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2,3,7), warn_unused_result)); /***********************************************************//** Replaces the new column values stored in the update vector to the index entry given. */ @@ -250,7 +250,7 @@ row_upd_index_replace_new_col_vals_index_pos( does not work for non-clustered indexes. */ mem_heap_t* heap) /*!< in: memory heap for allocating and copying the new values */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***********************************************************//** Replaces the new column values stored in the update vector to the index entry given. */ @@ -269,7 +269,7 @@ row_upd_index_replace_new_col_vals( an upd_field is the clustered index position */ mem_heap_t* heap) /*!< in: memory heap for allocating and copying the new values */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /***********************************************************//** Replaces the new column values stored in the update vector. */ UNIV_INTERN @@ -311,7 +311,7 @@ row_upd_changes_ord_field_binary_func( compile time */ const row_ext_t*ext) /*!< NULL, or prefixes of the externally stored columns in the old row */ - __attribute__((nonnull(1,2), warn_unused_result)); + MY_ATTRIBUTE((nonnull(1,2), warn_unused_result)); #ifdef UNIV_DEBUG # define row_upd_changes_ord_field_binary(index,update,thr,row,ext) \ row_upd_changes_ord_field_binary_func(index,update,thr,row,ext) @@ -338,7 +338,7 @@ row_upd_changes_doc_id( /*===================*/ dict_table_t* table, /*!< in: table */ upd_field_t* upd_field) /*!< in: field to check */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************//** Checks if an update vector changes an ordering field of an index record. This function is fast if the update vector is short or the number of ordering diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h index 1df5b4d3e989b..7b850215701c3 100644 --- a/storage/innobase/include/row0vers.h +++ b/storage/innobase/include/row0vers.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -110,7 +110,7 @@ row_vers_build_for_consistent_read( if the history is missing or the record does not exist in the view, that is, it was freshly inserted afterwards */ - __attribute__((nonnull(1,2,3,4,5,6,7))); + MY_ATTRIBUTE((nonnull(1,2,3,4,5,6,7))); /*****************************************************************//** Constructs the last committed version of a clustered index record, @@ -136,7 +136,7 @@ row_vers_build_for_semi_consistent_read( const rec_t** old_vers)/*!< out: rec, old version, or NULL if the record does not exist in the view, that is, it was freshly inserted afterwards */ - __attribute__((nonnull(1,2,3,4,5))); + MY_ATTRIBUTE((nonnull(1,2,3,4,5))); #ifndef UNIV_NONINL diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 6e2f76af30d8b..aaea21b264b4a 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, 2009, Google Inc. Copyright (c) 2009, Percona Inc. @@ -734,7 +734,7 @@ UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_purge_coordinator_thread)( /*=========================================*/ - void* arg __attribute__((unused))); /*!< in: a dummy parameter + void* arg MY_ATTRIBUTE((unused))); /*!< in: a dummy parameter required by os_thread_create */ /*********************************************************************//** @@ -744,7 +744,7 @@ UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_worker_thread)( /*==============================*/ - void* arg __attribute__((unused))); /*!< in: a dummy parameter + void* arg MY_ATTRIBUTE((unused))); /*!< in: a dummy parameter required by os_thread_create */ } /* extern "C" */ diff --git a/storage/innobase/include/srv0start.h b/storage/innobase/include/srv0start.h index 40d502f4459ac..963b767f0fb5b 100644 --- a/storage/innobase/include/srv0start.h +++ b/storage/innobase/include/srv0start.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -105,7 +105,7 @@ srv_path_copy( ulint dest_len, /*!< in: max bytes to copy */ const char* basedir, /*!< in: base directory */ const char* table_name) /*!< in: source table name */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*****************************************************************//** Get the meta-data filename from the table name. */ @@ -116,7 +116,7 @@ srv_get_meta_data_filename( dict_table_t* table, /*!< in: table */ char* filename, /*!< out: filename */ ulint max_len) /*!< in: filename max length */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /** Log sequence number at shutdown */ extern lsn_t srv_shutdown_lsn; diff --git a/storage/innobase/include/sync0arr.h b/storage/innobase/include/sync0arr.h index 15dbdcb540d4f..a9e66f261c6b0 100644 --- a/storage/innobase/include/sync0arr.h +++ b/storage/innobase/include/sync0arr.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -110,7 +110,7 @@ sync_array_print_long_waits( /*========================*/ os_thread_id_t* waiter, /*!< out: longest waiting thread */ const void** sema) /*!< out: longest-waited-for semaphore */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /********************************************************************//** Validates the integrity of the wait array. Checks that the number of reserved cells equals the count variable. */ diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index fdcbb1b6fa54b..6b1e99bbbeec8 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -333,7 +333,7 @@ ibool rw_lock_s_lock_low( /*===============*/ rw_lock_t* lock, /*!< in: pointer to rw-lock */ - ulint pass __attribute__((unused)), + ulint pass MY_ATTRIBUTE((unused)), /*!< in: pass value; != 0, if the lock will be passed to another thread to unlock */ const char* file_name, /*!< in: file name where lock requested */ @@ -501,7 +501,7 @@ rw_lock_own( rw_lock_t* lock, /*!< in: rw-lock */ ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED, RW_LOCK_EX */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #endif /* UNIV_SYNC_DEBUG */ /******************************************************************//** Checks if somebody has locked the rw-lock in the specified mode. */ diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic index bb05ae7daf122..f2d4215a0511e 100644 --- a/storage/innobase/include/sync0rw.ic +++ b/storage/innobase/include/sync0rw.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -306,7 +306,7 @@ ibool rw_lock_s_lock_low( /*===============*/ rw_lock_t* lock, /*!< in: pointer to rw-lock */ - ulint pass __attribute__((unused)), + ulint pass MY_ATTRIBUTE((unused)), /*!< in: pass value; != 0, if the lock will be passed to another thread to unlock */ const char* file_name, /*!< in: file name where lock requested */ diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index d6f8d8f5e4ccb..95d9ef664987e 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2012, Facebook Inc. @@ -400,7 +400,7 @@ ibool mutex_own( /*======*/ const ib_mutex_t* mutex) /*!< in: mutex */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #endif /* UNIV_DEBUG */ #ifdef UNIV_SYNC_DEBUG /******************************************************************//** @@ -415,7 +415,7 @@ sync_thread_add_level( ulint level, /*!< in: level in the latching order; if SYNC_LEVEL_VARYING, nothing is done */ ibool relock) /*!< in: TRUE if re-entering an x-lock */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /******************************************************************//** Removes a latch from the thread level array if it is found there. @return TRUE if found in the array; it is no error if the latch is @@ -445,7 +445,7 @@ sync_thread_levels_nonempty_gen( /*============================*/ ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is allowed to be owned by the thread */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /******************************************************************//** Checks if the level array for the current thread is empty, except for data dictionary latches. */ @@ -462,7 +462,7 @@ sync_thread_levels_nonempty_trx( ibool has_search_latch) /*!< in: TRUE if and only if the thread is supposed to hold btr_search_latch */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); /******************************************************************//** Gets the debug information for a reserved mutex. */ diff --git a/storage/innobase/include/trx0rec.h b/storage/innobase/include/trx0rec.h index 50da55d2ea388..359937e358392 100644 --- a/storage/innobase/include/trx0rec.h +++ b/storage/innobase/include/trx0rec.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -86,7 +86,7 @@ ulint trx_undo_rec_get_offset( /*====================*/ undo_no_t undo_no) /*!< in: undo no read from node */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /**********************************************************************//** Returns the start of the undo record data area. */ @@ -109,7 +109,7 @@ trx_undo_rec_get_pars( externally stored fild */ undo_no_t* undo_no, /*!< out: undo log record number */ table_id_t* table_id) /*!< out: table id */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Builds a row reference from an undo log record. @return pointer to remaining part of undo record */ @@ -201,7 +201,7 @@ trx_undo_rec_get_partial_row( only in the assertion. */ mem_heap_t* heap) /*!< in: memory heap from which the memory needed is allocated */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /***********************************************************************//** Writes information to an undo log about an insert, update, or a delete marking of a clustered index record. This information is used in a rollback of the @@ -233,7 +233,7 @@ trx_undo_report_row_operation( inserted undo log record, 0 if BTR_NO_UNDO_LOG flag was specified */ - __attribute__((nonnull(3,4,10), warn_unused_result)); + MY_ATTRIBUTE((nonnull(3,4,10), warn_unused_result)); /******************************************************************//** Copies an undo record to heap. This function can be called if we know that the undo log record exists. @@ -244,7 +244,7 @@ trx_undo_get_undo_rec_low( /*======================*/ roll_ptr_t roll_ptr, /*!< in: roll pointer to record */ mem_heap_t* heap) /*!< in: memory heap where copied */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Build a previous version of a clustered index record. The caller must hold a latch on the index page of the clustered index record. @@ -268,7 +268,7 @@ trx_undo_prev_version_build( rec_t** old_vers)/*!< out, own: previous version, or NULL if rec is the first inserted version, or if history data has been deleted */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** Parses a redo log record of adding an undo log record. diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h index d5ab83d77671b..98a667b2ec104 100644 --- a/storage/innobase/include/trx0roll.h +++ b/storage/innobase/include/trx0roll.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -125,7 +125,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(trx_rollback_or_clean_all_recovered)( /*================================================*/ - void* arg __attribute__((unused))); + void* arg MY_ATTRIBUTE((unused))); /*!< in: a dummy parameter required by os_thread_create */ /*********************************************************************//** @@ -152,7 +152,7 @@ dberr_t trx_rollback_for_mysql( /*===================*/ trx_t* trx) /*!< in/out: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Rollback the latest SQL statement for MySQL. @return error code or DB_SUCCESS */ @@ -161,7 +161,7 @@ dberr_t trx_rollback_last_sql_stat_for_mysql( /*=================================*/ trx_t* trx) /*!< in/out: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Rollback a transaction to a given savepoint or do a complete rollback. @return error code or DB_SUCCESS */ @@ -173,7 +173,7 @@ trx_rollback_to_savepoint( trx_savept_t* savept) /*!< in: pointer to savepoint undo number, if partial rollback requested, or NULL for complete rollback */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /*******************************************************************//** Rolls back a transaction back to a named savepoint. Modifications after the savepoint are undone but InnoDB does NOT release the corresponding locks @@ -195,7 +195,7 @@ trx_rollback_to_savepoint_for_mysql( information to remove the binlog entries of the queries executed after the savepoint */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Creates a named savepoint. If the transaction is not yet started, starts it. If there is already a savepoint of the same name, this call erases that old @@ -212,7 +212,7 @@ trx_savepoint_for_mysql( position corresponding to this connection at the time of the savepoint */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /*******************************************************************//** Releases a named savepoint. Savepoints which were set after this savepoint are deleted. @@ -224,7 +224,7 @@ trx_release_savepoint_for_mysql( /*============================*/ trx_t* trx, /*!< in: transaction handle */ const char* savepoint_name) /*!< in: savepoint name */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /*******************************************************************//** Frees savepoint structs starting from savep. */ UNIV_INTERN diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 70f214d1ac7af..4a88ef241a141 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -267,7 +267,7 @@ ibool trx_in_trx_list( /*============*/ const trx_t* in_trx) /*!< in: transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ #if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG /***********************************************************//** @@ -278,7 +278,7 @@ ibool trx_assert_recovered( /*=================*/ trx_id_t trx_id) /*!< in: transaction identifier */ - __attribute__((warn_unused_result)); + MY_ATTRIBUTE((warn_unused_result)); #endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */ /*****************************************************************//** Updates the offset information about the end of the MySQL binlog entry diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index 144e1803975c0..e3a0e81bfc56f 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -103,7 +103,7 @@ void trx_free_prepared( /*==============*/ trx_t* trx) /*!< in, own: trx object */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); /********************************************************************//** Frees a transaction object for MySQL. */ UNIV_INTERN @@ -169,7 +169,7 @@ trx_start_for_ddl_low( /*==================*/ trx_t* trx, /*!< in/out: transaction */ trx_dict_op_t op) /*!< in: dictionary operation type */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG #define trx_start_for_ddl(t, o) \ @@ -191,7 +191,7 @@ void trx_commit( /*=======*/ trx_t* trx) /*!< in/out: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /****************************************************************//** Commits a transaction and a mini-transaction. */ UNIV_INTERN @@ -201,7 +201,7 @@ trx_commit_low( trx_t* trx, /*!< in/out: transaction */ mtr_t* mtr) /*!< in/out: mini-transaction (will be committed), or NULL if trx made no modifications */ - __attribute__((nonnull(1))); + MY_ATTRIBUTE((nonnull(1))); /****************************************************************//** Cleans up a transaction at database startup. The cleanup is needed if the transaction already got to the middle of a commit when the database @@ -255,7 +255,7 @@ void trx_commit_complete_for_mysql( /*==========================*/ trx_t* trx) /*!< in/out: transaction */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Marks the latest SQL statement ended. */ UNIV_INTERN @@ -317,7 +317,7 @@ trx_print_low( /*!< in: length of trx->lock.trx_locks */ ulint heap_size) /*!< in: mem_heap_get_size(trx->lock.lock_heap) */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Prints info about a transaction. @@ -331,7 +331,7 @@ trx_print_latched( const trx_t* trx, /*!< in: transaction */ ulint max_query_len) /*!< in: max query length to print, or 0 to use the default max length */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Prints info about a transaction. @@ -344,7 +344,7 @@ trx_print( const trx_t* trx, /*!< in: transaction */ ulint max_query_len) /*!< in: max query length to print, or 0 to use the default max length */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); /**********************************************************************//** Determine if a transaction is a dictionary operation. @@ -354,7 +354,7 @@ enum trx_dict_op_t trx_get_dict_operation( /*===================*/ const trx_t* trx) /*!< in: transaction */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /**********************************************************************//** Flag a transaction a dictionary operation. */ UNIV_INLINE @@ -383,7 +383,7 @@ trx_state_eq( if state != TRX_STATE_NOT_STARTED asserts that trx->state != TRX_STATE_NOT_STARTED */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); # ifdef UNIV_DEBUG /**********************************************************************//** Asserts that a transaction has been started. @@ -394,7 +394,7 @@ ibool trx_assert_started( /*===============*/ const trx_t* trx) /*!< in: transaction */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); # endif /* UNIV_DEBUG */ /**********************************************************************//** diff --git a/storage/innobase/include/trx0undo.h b/storage/innobase/include/trx0undo.h index 61b0dabb1e69b..0148cc6157936 100644 --- a/storage/innobase/include/trx0undo.h +++ b/storage/innobase/include/trx0undo.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -73,7 +73,7 @@ bool trx_undo_trx_id_is_insert( /*======================*/ const byte* trx_id) /*!< in: DB_TRX_ID, followed by DB_ROLL_PTR */ - __attribute__((nonnull, pure, warn_unused_result)); + MY_ATTRIBUTE((nonnull, pure, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /*****************************************************************//** Writes a roll ptr to an index page. In case that the size changes in @@ -214,7 +214,7 @@ trx_undo_add_page( mtr_t* mtr) /*!< in: mtr which does not have a latch to any undo log page; the caller must have reserved the rollback segment mutex */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /********************************************************************//** Frees the last undo log page. The caller must hold the rollback segment mutex. */ @@ -229,7 +229,7 @@ trx_undo_free_last_page_func( mtr_t* mtr) /*!< in/out: mini-transaction which does not have a latch to any undo log page or which has allocated the undo log page */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG # define trx_undo_free_last_page(trx,undo,mtr) \ trx_undo_free_last_page_func(trx,undo,mtr) @@ -251,7 +251,7 @@ trx_undo_truncate_end_func( trx_undo_t* undo, /*!< in/out: undo log */ undo_no_t limit) /*!< in: all undo records with undo number >= this value should be truncated */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG # define trx_undo_truncate_end(trx,undo,limit) \ trx_undo_truncate_end_func(trx,undo,limit) @@ -300,7 +300,7 @@ trx_undo_assign_undo( /*=================*/ trx_t* trx, /*!< in: transaction */ ulint type) /*!< in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); /******************************************************************//** Sets the state of the undo log segment at a transaction finish. @return undo log segment header page, x-latched */ @@ -350,7 +350,7 @@ void trx_undo_free_prepared( /*===================*/ trx_t* trx) /*!< in/out: PREPARED transaction */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); #endif /* !UNIV_HOTBACKUP */ /***********************************************************//** Parses the redo log entry of an undo log page initialization. diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 8c325ecc88cd0..dfb59673f0be2 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -249,7 +249,7 @@ that are only referenced from within InnoDB, not from MySQL. We disable the GCC visibility directive on all Sun operating systems because there is no easy way to get it to work. See http://bugs.mysql.com/bug.php?id=52263. */ #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(sun) || defined(__INTEL_COMPILER) -# define UNIV_INTERN __attribute__((visibility ("hidden"))) +# define UNIV_INTERN MY_ATTRIBUTE((visibility ("hidden"))) #else # define UNIV_INTERN #endif @@ -264,7 +264,7 @@ appears close together improving code locality of non-cold parts of program. The paths leading to call of cold functions within code are marked as unlikely by the branch prediction mechanism. optimize a rarely invoked function for size instead for speed. */ -# define UNIV_COLD __attribute__((cold)) +# define UNIV_COLD MY_ATTRIBUTE((cold)) #else # define UNIV_COLD /* empty */ #endif @@ -528,7 +528,7 @@ contains the sum of the following flag and the locally stored len. */ #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER) #define HAVE_GCC_GT_2 /* Tell the compiler that variable/function is unused. */ -# define UNIV_UNUSED __attribute__ ((unused)) +# define UNIV_UNUSED MY_ATTRIBUTE ((unused)) #else # define UNIV_UNUSED #endif /* CHECK FOR GCC VER_GT_2 */ diff --git a/storage/innobase/include/ut0byte.h b/storage/innobase/include/ut0byte.h index 5bdd553ca802c..4893ab9f9af20 100644 --- a/storage/innobase/include/ut0byte.h +++ b/storage/innobase/include/ut0byte.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -39,7 +39,7 @@ ut_ull_create( /*==========*/ ulint high, /*!< in: high-order 32 bits */ ulint low) /*!< in: low-order 32 bits */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /********************************************************//** Rounds a 64-bit integer downward to a multiple of a power of 2. @@ -80,7 +80,7 @@ ut_align_down( /*==========*/ const void* ptr, /*!< in: pointer */ ulint align_no) /*!< in: align by this number */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*********************************************************//** The following function computes the offset of a pointer from the nearest aligned address. @@ -91,7 +91,7 @@ ut_align_offset( /*============*/ const void* ptr, /*!< in: pointer */ ulint align_no) /*!< in: align by this number */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*****************************************************************//** Gets the nth bit of a ulint. @return TRUE if nth bit is 1; 0th bit is defined to be the least significant */ diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h index 6a4afe9959769..3f5baef0a3c98 100644 --- a/storage/innobase/include/ut0dbg.h +++ b/storage/innobase/include/ut0dbg.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -59,7 +59,7 @@ ut_dbg_assertion_failed( const char* expr, /*!< in: the failed assertion */ const char* file, /*!< in: source file containing the assertion */ ulint line) /*!< in: line number of the assertion */ - UNIV_COLD __attribute__((nonnull(2))); + UNIV_COLD MY_ATTRIBUTE((nonnull(2))); /** Abort the execution. */ # define UT_DBG_PANIC abort() diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h index af7eb4e9b1d30..81470358f2fc9 100644 --- a/storage/innobase/include/ut0mem.h +++ b/storage/innobase/include/ut0mem.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -87,7 +87,7 @@ ut_malloc_low( ulint n, /*!< in: number of bytes to allocate */ ibool assert_on_error) /*!< in: if TRUE, we crash mysqld if the memory cannot be allocated */ - __attribute__((malloc)); + MY_ATTRIBUTE((malloc)); /**********************************************************************//** Allocates memory. */ #define ut_malloc(n) ut_malloc_low(n, TRUE) diff --git a/storage/innobase/include/ut0rnd.h b/storage/innobase/include/ut0rnd.h index 53b769849a5c1..6ed3ee3b2e5dc 100644 --- a/storage/innobase/include/ut0rnd.h +++ b/storage/innobase/include/ut0rnd.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2009, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -96,7 +96,7 @@ ulint ut_fold_ull( /*========*/ ib_uint64_t d) /*!< in: 64-bit integer */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*************************************************************//** Folds a character string ending in the null character. @return folded value */ @@ -105,7 +105,7 @@ ulint ut_fold_string( /*===========*/ const char* str) /*!< in: null-terminated string */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); /***********************************************************//** Looks for a prime number slightly greater than the given argument. The prime is chosen so that it is not near any power of 2. @@ -115,7 +115,7 @@ ulint ut_find_prime( /*==========*/ ulint n) /*!< in: positive number > 100 */ - __attribute__((const)); + MY_ATTRIBUTE((const)); #endif /* !UNIV_INNOCHECKSUM */ @@ -128,7 +128,7 @@ ut_fold_ulint_pair( /*===============*/ ulint n1, /*!< in: ulint */ ulint n2) /*!< in: ulint */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /*************************************************************//** Folds a binary string. @return folded value */ @@ -138,7 +138,7 @@ ut_fold_binary( /*===========*/ const byte* str, /*!< in: string of bytes */ ulint len) /*!< in: length */ - __attribute__((pure)); + MY_ATTRIBUTE((pure)); #ifndef UNIV_NONINL diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 0caf379d8fac1..ef887ed5e5845 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -217,7 +217,7 @@ ulint ut_2_power_up( /*==========*/ ulint n) /*!< in: number != 0 */ - __attribute__((const)); + MY_ATTRIBUTE((const)); /** Determine how many bytes (groups of 8 bits) are needed to store the given number of bits. @@ -297,7 +297,7 @@ void ut_print_timestamp( /*===============*/ FILE* file) /*!< in: file where to print */ - UNIV_COLD __attribute__((nonnull)); + UNIV_COLD MY_ATTRIBUTE((nonnull)); #ifndef UNIV_INNOCHECKSUM @@ -485,7 +485,7 @@ ut_ulint_sort( ulint* aux_arr, /*!< in/out: aux array to use in sort */ ulint low, /*!< in: lower bound */ ulint high) /*!< in: upper bound */ - __attribute__((nonnull)); + MY_ATTRIBUTE((nonnull)); #ifndef UNIV_NONINL #include "ut0ut.ic" diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 8ad84846224ec..bf4cff28bef56 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -409,7 +409,7 @@ ibool lock_rec_validate_page( /*===================*/ const buf_block_t* block) /*!< in: buffer block */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ /* The lock system */ @@ -493,7 +493,7 @@ Checks that a transaction id is sensible, i.e., not in the future. #ifdef UNIV_DEBUG UNIV_INTERN #else -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) #endif bool lock_check_trx_id_sanity( @@ -3616,7 +3616,7 @@ lock_get_next_lock( ut_ad(heap_no == ULINT_UNDEFINED); ut_ad(lock_get_type_low(lock) == LOCK_TABLE); - lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); + lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock); } } while (lock != NULL && lock->trx->lock.deadlock_mark > ctx->mark_start); @@ -3666,7 +3666,8 @@ lock_get_first_lock( } else { *heap_no = ULINT_UNDEFINED; ut_ad(lock_get_type_low(lock) == LOCK_TABLE); - lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); + dict_table_t* table = lock->un_member.tab_lock.table; + lock = UT_LIST_GET_FIRST(table->locks); } ut_a(lock != NULL); @@ -4392,7 +4393,8 @@ lock_table( dberr_t err; const lock_t* wait_for; - ut_ad(table && thr); + ut_ad(table != NULL); + ut_ad(thr != NULL); if (flags & BTR_NO_LOCKING_FLAG) { @@ -5779,7 +5781,7 @@ lock_validate_table_locks( /*********************************************************************//** Validate record locks up to a limit. @return lock at limit or NULL if no more locks in the hash bucket */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const lock_t* lock_rec_validate( /*==============*/ diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index a1c35e20ead74..e2e7c4207a10a 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -479,7 +479,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(lock_wait_timeout_thread)( /*=====================================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /* in: a dummy parameter required by os_thread_create */ { diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 3ff4a9d7d1ed4..8ff8e39d352bb 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -975,7 +975,7 @@ log_group_init( ulint space_id, /*!< in: space id of the file space which contains the log files of this group */ - ulint archive_space_id __attribute__((unused))) + ulint archive_space_id MY_ATTRIBUTE((unused))) /*!< in: space id of the file space which contains some archived log files for this group; currently, only @@ -2352,7 +2352,7 @@ void log_archived_file_name_gen( /*=======================*/ char* buf, /*!< in: buffer where to write */ - ulint id __attribute__((unused)), + ulint id MY_ATTRIBUTE((unused)), /*!< in: group id; currently we only archive the first group */ ulint file_no)/*!< in: file number */ diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index ca07f89890f9d..85f4f6ea6715d 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -328,7 +328,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(recv_writer_thread)( /*===============================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { @@ -742,7 +742,7 @@ recv_check_cp_is_consistent( /********************************************************//** Looks for the maximum consistent checkpoint from the log groups. @return error code or DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t recv_find_max_checkpoint( /*=====================*/ diff --git a/storage/innobase/mem/mem0dbg.cc b/storage/innobase/mem/mem0dbg.cc index 308c297955155..a77785a369ade 100644 --- a/storage/innobase/mem/mem0dbg.cc +++ b/storage/innobase/mem/mem0dbg.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -248,7 +248,7 @@ void mem_field_erase( /*============*/ byte* buf, /*!< in: memory field */ - ulint n __attribute__((unused))) + ulint n MY_ATTRIBUTE((unused))) /*!< in: how many bytes the user requested */ { byte* usr_buf; @@ -450,7 +450,7 @@ void mem_heap_validate_or_print( /*=======================*/ mem_heap_t* heap, /*!< in: memory heap */ - byte* top __attribute__((unused)), + byte* top MY_ATTRIBUTE((unused)), /*!< in: calculate and validate only until this top pointer in the heap is reached, if this pointer is NULL, ignored */ diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 869586bcd90fe..f60ec648ba129 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -58,7 +58,7 @@ mtr_block_dirtied( /*****************************************************************//** Releases the item in the slot given. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void mtr_memo_slot_release_func( /*=======================*/ @@ -105,7 +105,7 @@ mtr_memo_slot_release_func( Releases the mlocks and other objects stored in an mtr memo. They are released in the order opposite to which they were pushed to the memo. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void mtr_memo_pop_all( /*=============*/ @@ -395,7 +395,7 @@ mtr_read_ulint( /*===========*/ const byte* ptr, /*!< in: pointer from where to read */ ulint type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */ - mtr_t* mtr __attribute__((unused))) + mtr_t* mtr MY_ATTRIBUTE((unused))) /*!< in: mini-transaction handle */ { ut_ad(mtr->state == MTR_ACTIVE); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 2a3a095848174..46a7b8015217f 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1,6 +1,6 @@ /*********************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. Portions of this file contain modifications contributed and copyrighted @@ -1469,11 +1469,11 @@ void os_file_set_nocache( /*================*/ int fd /*!< in: file descriptor to alter */ - __attribute__((unused)), + MY_ATTRIBUTE((unused)), const char* file_name /*!< in: used in the diagnostic message */ - __attribute__((unused)), - const char* operation_name __attribute__((unused))) + MY_ATTRIBUTE((unused)), + const char* operation_name MY_ATTRIBUTE((unused))) /*!< in: "open" or "create"; used in the diagnostic message */ { @@ -2353,7 +2353,7 @@ os_file_flush_func( /*******************************************************************//** Does a synchronous read operation in Posix. @return number of bytes read, -1 if error */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ssize_t os_file_pread( /*==========*/ @@ -2464,7 +2464,7 @@ os_file_pread( /*******************************************************************//** Does a synchronous write operation in Posix. @return number of bytes written, -1 if error */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ssize_t os_file_pwrite( /*===========*/ diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index cb2381df48c3a..95b8db0ccc86b 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -304,7 +304,7 @@ byte* page_parse_create( /*==============*/ byte* ptr, /*!< in: buffer */ - byte* end_ptr __attribute__((unused)), /*!< in: buffer end */ + byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */ ulint comp, /*!< in: nonzero=compact page format */ buf_block_t* block, /*!< in: block or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index e5176148edd7a..4da11e5d68811 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2005, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. This program is free software; you can redistribute it and/or modify it under @@ -119,7 +119,7 @@ Compare at most sizeof(field_ref_zero) bytes. independently of any UNIV_ debugging conditions. */ #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG # include -__attribute__((format (printf, 1, 2))) +MY_ATTRIBUTE((format (printf, 1, 2))) /**********************************************************************//** Report a failure to decompress or compress. @return number of characters printed */ @@ -738,8 +738,8 @@ static void page_zip_free( /*==========*/ - void* opaque __attribute__((unused)), /*!< in: memory heap */ - void* address __attribute__((unused)))/*!< in: object to free */ + void* opaque MY_ATTRIBUTE((unused)), /*!< in: memory heap */ + void* address MY_ATTRIBUTE((unused)))/*!< in: object to free */ { } @@ -4769,7 +4769,8 @@ page_zip_parse_compress( ulint size; ulint trailer_size; - ut_ad(ptr && end_ptr); + ut_ad(ptr != NULL); + ut_ad(end_ptr != NULL); ut_ad(!page == !page_zip); if (UNIV_UNLIKELY(ptr + (2 + 2) > end_ptr)) { diff --git a/storage/innobase/pars/lexyy.cc b/storage/innobase/pars/lexyy.cc index 1c01becd9edf8..bfa8e2ea9506e 100644 --- a/storage/innobase/pars/lexyy.cc +++ b/storage/innobase/pars/lexyy.cc @@ -295,7 +295,7 @@ static int yy_start = 0; /* start state number */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); -__attribute__((unused)) static void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +MY_ATTRIBUTE((unused)) static void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); static YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); @@ -916,7 +916,7 @@ char *yytext; #line 1 "pars0lex.l" /***************************************************************************** -Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1027,7 +1027,7 @@ static int yy_init_globals (void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ -__attribute__((unused)) static int yylex_destroy (void ); +MY_ATTRIBUTE((unused)) static int yylex_destroy (void ); int yyget_debug (void ); @@ -2664,7 +2664,7 @@ static int yy_get_next_buffer (void) * @param new_buffer The new input buffer. * */ - __attribute__((unused)) static void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) + MY_ATTRIBUTE((unused)) static void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body @@ -3042,7 +3042,7 @@ static int yy_init_globals (void) } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ -__attribute__((unused)) static int yylex_destroy (void) +MY_ATTRIBUTE((unused)) static int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ diff --git a/storage/innobase/pars/make_flex.sh b/storage/innobase/pars/make_flex.sh index 581fc2342aa77..c3db8aea29838 100755 --- a/storage/innobase/pars/make_flex.sh +++ b/storage/innobase/pars/make_flex.sh @@ -1,6 +1,6 @@ #!/bin/bash # -# Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved. +# Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. # # 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 @@ -33,15 +33,15 @@ sed -e ' s/'"$TMPFILE"'/'"$OUTFILE"'/; s/\(int offset = \)\((yy_c_buf_p) - (yytext_ptr)\);/\1(int)(\2);/; s/\(void yy\(restart\|_\(delete\|flush\)_buffer\)\)/static \1/; -s/\(void yy_switch_to_buffer\)/__attribute__((unused)) static \1/; -s/\(void yy\(push\|pop\)_buffer_state\)/__attribute__((unused)) static \1/; +s/\(void yy_switch_to_buffer\)/MY_ATTRIBUTE((unused)) static \1/; +s/\(void yy\(push\|pop\)_buffer_state\)/MY_ATTRIBUTE((unused)) static \1/; s/\(YY_BUFFER_STATE yy_create_buffer\)/static \1/; -s/\(\(int\|void\) yy[gs]et_\)/__attribute__((unused)) static \1/; +s/\(\(int\|void\) yy[gs]et_\)/MY_ATTRIBUTE((unused)) static \1/; s/\(void \*\?yy\(\(re\)\?alloc\|free\)\)/static \1/; s/\(extern \)\?\(int yy\(leng\|lineno\|_flex_debug\)\)/static \2/; -s/\(int yylex_destroy\)/__attribute__((unused)) static \1/; +s/\(int yylex_destroy\)/MY_ATTRIBUTE((unused)) static \1/; s/\(extern \)\?\(int yylex \)/UNIV_INTERN \2/; -s/^\(\(FILE\|char\) *\* *yyget\)/__attribute__((unused)) static \1/; +s/^\(\(FILE\|char\) *\* *yyget\)/MY_ATTRIBUTE((unused)) static \1/; s/^\(extern \)\?\(\(FILE\|char\) *\* *yy\)/static \2/; ' < $TMPFILE >> $OUTFILE diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index 655e5ba1324cf..b116357c5b989 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1925,7 +1925,7 @@ pars_create_table( sym_node_t* column_defs, /*!< in: list of column names */ sym_node_t* compact, /* in: non-NULL if COMPACT table. */ sym_node_t* block_size, /* in: block size (can be NULL) */ - void* not_fit_in_memory __attribute__((unused))) + void* not_fit_in_memory MY_ATTRIBUTE((unused))) /*!< in: a non-NULL pointer means that this is a table which in simulations should be simulated as not fitting @@ -2141,7 +2141,7 @@ UNIV_INTERN que_fork_t* pars_stored_procedure_call( /*=======================*/ - sym_node_t* sym_node __attribute__((unused))) + sym_node_t* sym_node MY_ATTRIBUTE((unused))) /*!< in: stored procedure name */ { ut_error; @@ -2201,7 +2201,7 @@ UNIV_INTERN void yyerror( /*====*/ - const char* s __attribute__((unused))) + const char* s MY_ATTRIBUTE((unused))) /*!< in: error message string */ { ut_ad(s); diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc index 426cf9e3ac553..616ef322fb52b 100644 --- a/storage/innobase/rem/rem0cmp.cc +++ b/storage/innobase/rem/rem0cmp.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -75,7 +75,7 @@ cmp_debug_dtuple_rec_with_match( completely matched fields; when function returns, contains the value for current comparison */ - __attribute__((nonnull, warn_unused_result)); + MY_ATTRIBUTE((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ /*************************************************************//** This function is used to compare two data fields for which the data type @@ -659,7 +659,10 @@ cmp_dtuple_rec_with_match_low( in current field */ int ret; /* return value */ - ut_ad(dtuple && rec && matched_fields && matched_bytes); + ut_ad(dtuple != NULL); + ut_ad(rec != NULL); + ut_ad(matched_fields != NULL); + ut_ad(matched_bytes != NULL); ut_ad(dtuple_check_typed(dtuple)); ut_ad(rec_offs_validate(rec, NULL, offsets)); @@ -920,7 +923,7 @@ Compare two physical record fields. @retval 1 if rec1 field is greater than rec2 @retval -1 if rec1 field is less than rec2 @retval 0 if rec1 field equals to rec2 */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) int cmp_rec_rec_simple_field( /*=====================*/ @@ -1139,7 +1142,9 @@ cmp_rec_rec_with_match( int ret = 0; /* return value */ ulint comp; - ut_ad(rec1 && rec2 && index); + ut_ad(rec1 != NULL); + ut_ad(rec2 != NULL); + ut_ad(index != NULL); ut_ad(rec_offs_validate(rec1, index, offsets1)); ut_ad(rec_offs_validate(rec2, index, offsets2)); ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2)); @@ -1375,7 +1380,9 @@ cmp_debug_dtuple_rec_with_match( int ret; /* return value */ ulint cur_field; /* current field number */ - ut_ad(dtuple && rec && matched_fields); + ut_ad(dtuple != NULL); + ut_ad(rec != NULL); + ut_ad(matched_fields != NULL); ut_ad(dtuple_check_typed(dtuple)); ut_ad(rec_offs_validate(rec, NULL, offsets)); diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 0d7b7c16785dd..a95e9c236139e 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -241,7 +241,7 @@ rec_get_n_extern_new( Determine the offset to each field in a leaf-page record in ROW_FORMAT=COMPACT. This is a special case of rec_init_offsets() and rec_get_offsets_func(). */ -UNIV_INLINE __attribute__((nonnull)) +UNIV_INLINE MY_ATTRIBUTE((nonnull)) void rec_init_offsets_comp_ordinary( /*===========================*/ @@ -785,7 +785,7 @@ rec_get_nth_field_offs_old( /**********************************************************//** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. @return total size */ -UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2))) +UNIV_INLINE MY_ATTRIBUTE((warn_unused_result, nonnull(1,2))) ulint rec_get_converted_size_comp_prefix_low( /*===================================*/ @@ -1130,7 +1130,7 @@ rec_convert_dtuple_to_rec_old( /*********************************************************//** Builds a ROW_FORMAT=COMPACT record out of a data tuple. */ -UNIV_INLINE __attribute__((nonnull)) +UNIV_INLINE MY_ATTRIBUTE((nonnull)) void rec_convert_dtuple_to_rec_comp( /*===========================*/ @@ -1338,7 +1338,9 @@ rec_convert_dtuple_to_rec( { rec_t* rec; - ut_ad(buf && index && dtuple); + ut_ad(buf != NULL); + ut_ad(index != NULL); + ut_ad(dtuple != NULL); ut_ad(dtuple_validate(dtuple)); ut_ad(dtuple_check_typed(dtuple)); diff --git a/storage/innobase/row/row0ftsort.cc b/storage/innobase/row/row0ftsort.cc index 1fc72bdeade9b..4fd3a51040a0b 100644 --- a/storage/innobase/row/row0ftsort.cc +++ b/storage/innobase/row/row0ftsort.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2010, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -512,8 +512,18 @@ row_merge_fts_doc_tokenize( dfield_dup(field, buf->heap); /* One variable length column, word with its lenght less than - fts_max_token_size, add one extra size and one extra byte */ - cur_len += 2; + fts_max_token_size, add one extra size and one extra byte. + + Since the max length for FTS token now is larger than 255, + so we will need to signify length byte itself, so only 1 to 128 + bytes can be used for 1 bytes, larger than that 2 bytes. */ + if (t_str.f_len < 128) { + /* Extra size is one byte. */ + cur_len += 2; + } else { + /* Extra size is two bytes. */ + cur_len += 3; + } /* Reserve one byte for the end marker of row_merge_block_t. */ if (buf->total_size + data_size[idx] + cur_len @@ -976,7 +986,7 @@ row_fts_start_parallel_merge( /********************************************************************//** Insert processed FTS data to auxillary index tables. @return DB_SUCCESS if insertion runs fine */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t row_merge_write_fts_word( /*=====================*/ diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 89496b4176b11..eda89951c3f28 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -2179,7 +2179,7 @@ PageConverter::operator() ( Clean up after import tablespace failure, this function will acquire the dictionary latches on behalf of the transaction if the transaction hasn't already acquired them. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_import_discard_changes( /*=======================*/ @@ -2230,7 +2230,7 @@ row_import_discard_changes( /*****************************************************************//** Clean up after import tablespace. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_cleanup( /*===============*/ @@ -2265,7 +2265,7 @@ row_import_cleanup( /*****************************************************************//** Report error during tablespace import. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_error( /*=============*/ @@ -2293,7 +2293,7 @@ row_import_error( Adjust the root page index node and leaf node segment headers, update with the new space id. For all the table's secondary indexes. @return error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_adjust_root_pages_of_secondary_indexes( /*==============================================*/ @@ -2409,7 +2409,7 @@ row_import_adjust_root_pages_of_secondary_indexes( /*****************************************************************//** Ensure that dict_sys->row_id exceeds SELECT MAX(DB_ROW_ID). @return error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_set_sys_max_row_id( /*==========================*/ @@ -2559,7 +2559,7 @@ row_import_cfg_read_string( /*********************************************************************//** Write the meta data (index user fields) config file. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_cfg_read_index_fields( /*=============================*/ @@ -2642,7 +2642,7 @@ row_import_cfg_read_index_fields( Read the index names and root page numbers of the indexes and set the values. Row format [root_page_no, len of str, str ... ] @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_read_index_data( /*=======================*/ @@ -2837,7 +2837,7 @@ row_import_read_indexes( /*********************************************************************//** Read the meta data (table columns) config file. Deserialise the contents of dict_col_t structure, along with the column name. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_read_columns( /*====================*/ @@ -2962,7 +2962,7 @@ row_import_read_columns( /*****************************************************************//** Read the contents of the .cfg file. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_read_v1( /*===============*/ @@ -3128,7 +3128,7 @@ row_import_read_v1( /** Read the contents of the .cfg file. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_read_meta_data( /*======================*/ @@ -3171,7 +3171,7 @@ row_import_read_meta_data( /** Read the contents of the .cfg file. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_import_read_cfg( /*================*/ diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index f0f7e5fcdf0fe..3041d93a09a40 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -224,7 +224,7 @@ Does an insert operation by updating a delete-marked existing record in the index. This situation can occur if the delete-marked record is kept in the index for consistent reads. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_sec_index_entry_by_modify( /*==============================*/ @@ -319,7 +319,7 @@ Does an insert operation by delete unmarking and updating a delete marked existing record in the index. This situation can occur if the delete marked record is kept in the index for consistent reads. @return DB_SUCCESS, DB_FAIL, or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_clust_index_entry_by_modify( /*================================*/ @@ -427,7 +427,7 @@ row_ins_cascade_ancestor_updates_table( Returns the number of ancestor UPDATE or DELETE nodes of a cascaded update/delete node. @return number of ancestors */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ulint row_ins_cascade_n_ancestors( /*========================*/ @@ -453,7 +453,7 @@ a cascaded update. can also be 0 if no foreign key fields changed; the returned value is ULINT_UNDEFINED if the column type in the child table is too short to fit the new value in the parent table: that means the update fails */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ulint row_ins_cascade_calc_update_vec( /*============================*/ @@ -926,7 +926,7 @@ Perform referential actions or checks when a parent row is deleted or updated and the constraint had an ON DELETE or ON UPDATE condition which was not RESTRICT. @return DB_SUCCESS, DB_LOCK_WAIT, or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_foreign_check_on_constraint( /*================================*/ @@ -1747,7 +1747,7 @@ Otherwise does searches to the indexes of referenced tables and sets shared locks which lock either the success or the failure of a constraint. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_check_foreign_constraints( /*==============================*/ @@ -1888,7 +1888,7 @@ Scans a unique non-clustered index at a given index entry to determine whether a uniqueness violation has occurred for the key value of the entry. Set shared locks on possible duplicate records. @return DB_SUCCESS, DB_DUPLICATE_KEY, or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_scan_sec_index_for_duplicate( /*=================================*/ @@ -2030,7 +2030,7 @@ row_ins_scan_sec_index_for_duplicate( @retval DB_SUCCESS_LOCKED_REC when rec is an exact match of entry or a newer version of entry (the entry should not be inserted) @retval DB_DUPLICATE_KEY when entry is a duplicate of rec */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_duplicate_online( /*=====================*/ @@ -2071,7 +2071,7 @@ row_ins_duplicate_online( @retval DB_SUCCESS_LOCKED_REC when rec is an exact match of entry or a newer version of entry (the entry should not be inserted) @retval DB_DUPLICATE_KEY when entry is a duplicate of rec */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_duplicate_error_in_clust_online( /*====================================*/ @@ -2114,7 +2114,7 @@ for a clustered index! record @retval DB_SUCCESS_LOCKED_REC if an exact match of the record was found in online table rebuild (flags & (BTR_KEEP_SYS_FLAG | BTR_NO_LOCKING_FLAG)) */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_duplicate_error_in_clust( /*=============================*/ @@ -2532,7 +2532,7 @@ row_ins_clust_index_entry_low( /***************************************************************//** Starts a mini-transaction and checks if the index will be dropped. @return true if the index is to be dropped */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_ins_sec_mtr_start_and_check_if_aborted( /*=======================================*/ @@ -2973,7 +2973,7 @@ row_ins_index_entry( /***********************************************************//** Sets the values of the dtuple fields in entry from the values of appropriate columns in row. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_ins_index_entry_set_vals( /*=========================*/ @@ -3026,7 +3026,7 @@ row_ins_index_entry_set_vals( Inserts a single index entry to the table. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins_index_entry_step( /*=====================*/ @@ -3149,7 +3149,7 @@ row_ins_get_row_from_select( Inserts a row to a table. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_ins( /*====*/ diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index bb473ca92cf3b..a6751b208f74c 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2011, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2011, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -201,7 +201,7 @@ struct row_log_t { /** Create the file or online log if it does not exist. @param[in,out] log online rebuild log @return file descriptor. */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) int row_log_tmpfile( row_log_t* log) @@ -217,7 +217,7 @@ row_log_tmpfile( /** Allocate the memory for the log buffer. @param[in,out] log_buf Buffer used for log operation @return TRUE if success, false if not */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) bool row_log_block_allocate( row_log_buf_t& log_buf) @@ -407,7 +407,7 @@ row_log_table_get_error( /******************************************************//** Starts logging an operation to a table that is being rebuilt. @return pointer to log, or NULL if no logging is necessary */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) byte* row_log_table_open( /*===============*/ @@ -442,7 +442,7 @@ row_log_table_open( /******************************************************//** Stops logging an operation to a table that is being rebuilt. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_log_table_close_func( /*=====================*/ @@ -812,7 +812,7 @@ row_log_table_low_redundant( /******************************************************//** Logs an insert or update to a table that is being rebuilt. */ -static __attribute__((nonnull(1,2,3))) +static MY_ATTRIBUTE((nonnull(1,2,3))) void row_log_table_low( /*==============*/ @@ -1312,7 +1312,7 @@ row_log_table_blob_alloc( /******************************************************//** Converts a log record to a table row. @return converted row, or NULL if the conversion fails */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const dtuple_t* row_log_table_apply_convert_mrec( /*=============================*/ @@ -1466,7 +1466,7 @@ row_log_table_apply_convert_mrec( /******************************************************//** Replays an insert operation on a table that was rebuilt. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_insert_low( /*===========================*/ @@ -1548,7 +1548,7 @@ row_log_table_apply_insert_low( /******************************************************//** Replays an insert operation on a table that was rebuilt. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_insert( /*=======================*/ @@ -1600,7 +1600,7 @@ row_log_table_apply_insert( /******************************************************//** Deletes a record from a table that is being rebuilt. @return DB_SUCCESS or error code */ -static __attribute__((nonnull(1, 2, 4, 5), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1, 2, 4, 5), warn_unused_result)) dberr_t row_log_table_apply_delete_low( /*===========================*/ @@ -1698,7 +1698,7 @@ row_log_table_apply_delete_low( /******************************************************//** Replays a delete operation on a table that was rebuilt. @return DB_SUCCESS or error code */ -static __attribute__((nonnull(1, 3, 4, 5, 6, 7), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1, 3, 4, 5, 6, 7), warn_unused_result)) dberr_t row_log_table_apply_delete( /*=======================*/ @@ -1820,7 +1820,7 @@ row_log_table_apply_delete( /******************************************************//** Replays an update operation on a table that was rebuilt. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_update( /*=======================*/ @@ -2183,7 +2183,7 @@ row_log_table_apply_update( Applies an operation to a table that was rebuilt. @return NULL on failure (mrec corruption) or when out of data; pointer to next record on success */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const mrec_t* row_log_table_apply_op( /*===================*/ @@ -2474,7 +2474,7 @@ row_log_table_apply_op( /******************************************************//** Applies operations to a table was rebuilt. @return DB_SUCCESS, or error code on failure */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_log_table_apply_ops( /*====================*/ @@ -2971,7 +2971,7 @@ row_log_get_max_trx( /******************************************************//** Applies an operation to a secondary index that was being created. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_log_apply_op_low( /*=================*/ @@ -3198,7 +3198,7 @@ row_log_apply_op_low( Applies an operation to a secondary index that was being created. @return NULL on failure (mrec corruption) or when out of data; pointer to next record on success */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) const mrec_t* row_log_apply_op( /*=============*/ @@ -3323,7 +3323,7 @@ row_log_apply_op( /******************************************************//** Applies operations to a secondary index that was being created. @return DB_SUCCESS, or error code on failure */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t row_log_apply_ops( /*==============*/ diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 20a73a9ba33d6..dbb7a79cf589d 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -70,7 +70,7 @@ UNIV_INTERN char srv_disable_sort_file_cache; #ifdef UNIV_DEBUG /******************************************************//** Display a merge tuple. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_merge_tuple_print( /*==================*/ @@ -105,7 +105,7 @@ row_merge_tuple_print( /******************************************************//** Encode an index record. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_merge_buf_encode( /*=================*/ @@ -142,7 +142,7 @@ row_merge_buf_encode( /******************************************************//** Allocate a sort buffer. @return own: sort buffer */ -static __attribute__((malloc, nonnull)) +static MY_ATTRIBUTE((malloc, nonnull)) row_merge_buf_t* row_merge_buf_create_low( /*=====================*/ @@ -642,7 +642,7 @@ row_merge_dup_report( /*************************************************************//** Compare two tuples. @return 1, 0, -1 if a is greater, equal, less, respectively, than b */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) int row_merge_tuple_cmp( /*================*/ @@ -721,7 +721,7 @@ UT_SORT_FUNCTION_BODY(). /**********************************************************************//** Merge sort the tuple buffer in main memory. */ -static __attribute__((nonnull(4,5))) +static MY_ATTRIBUTE((nonnull(4,5))) void row_merge_tuple_sort( /*=================*/ @@ -1245,7 +1245,7 @@ row_merge_write_eof( @param[in,out] tmpfd temporary file handle @param[in] path path to create temporary file @return file descriptor, or -1 on failure */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) int row_merge_tmpfile_if_needed( int* tmpfd, @@ -1264,7 +1264,7 @@ row_merge_tmpfile_if_needed( @param[in] nrec number of records in the file @param[in] path path to create temporary files @return file descriptor, or -1 on failure */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) int row_merge_file_create_if_needed( merge_file_t* file, @@ -1310,7 +1310,7 @@ containing the index entries for the indexes to be built. @param[in,out] block file buffer @param[in,out] tmpfd temporary file handle return DB_SUCCESS or error */ -static __attribute__((nonnull(1,2,3,4,6,9,10,16), warn_unused_result)) +static MY_ATTRIBUTE((nonnull(1,2,3,4,6,9,10,16), warn_unused_result)) dberr_t row_merge_read_clustered_index( trx_t* trx, @@ -2028,7 +2028,7 @@ row_merge_read_clustered_index( /*************************************************************//** Merge two blocks of records on disk and write a bigger block. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_merge_blocks( /*=============*/ @@ -2139,7 +2139,7 @@ row_merge_blocks( /*************************************************************//** Copy a block of index entries. @return TRUE on success, FALSE on failure */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ibool row_merge_blocks_copy( /*==================*/ @@ -2212,7 +2212,7 @@ row_merge_blocks_copy( /*************************************************************//** Merge disk files. @return DB_SUCCESS or error code */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) dberr_t row_merge( /*======*/ @@ -2398,7 +2398,7 @@ row_merge_sort( /*************************************************************//** Copy externally stored columns to the data tuple. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_merge_copy_blobs( /*=================*/ @@ -2443,7 +2443,7 @@ row_merge_copy_blobs( Read sorted file containing index data tuples and insert these data tuples to the index @return DB_SUCCESS or error number */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_merge_insert_index_tuples( /*==========================*/ @@ -3456,7 +3456,7 @@ row_merge_rename_tables_dict( /*********************************************************************//** Create and execute a query graph for creating an index. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_merge_create_index_graph( /*=========================*/ diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 3140e18a0b1a7..c3a7e2c280706 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1419,9 +1419,12 @@ row_insert_for_mysql( } /* Difference between Doc IDs are restricted within - 4 bytes integer. See fts_get_encoded_len() */ + 4 bytes integer. See fts_get_encoded_len(). Consecutive + doc_ids difference should not exceed + FTS_DOC_ID_MAX_STEP value. */ - if (doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) { + if (next_doc_id > 1 + && doc_id - next_doc_id >= FTS_DOC_ID_MAX_STEP) { fprintf(stderr, "InnoDB: Doc ID " UINT64PF " is too" " big. Its difference with largest" @@ -1678,7 +1681,8 @@ row_update_for_mysql( trx_t* trx = prebuilt->trx; ulint fk_depth = 0; - ut_ad(prebuilt && trx); + ut_ad(prebuilt != NULL); + ut_ad(trx != NULL); UT_NOT_USED(mysql_rec); if (prebuilt->table->ibd_file_missing) { @@ -1871,7 +1875,8 @@ row_unlock_for_mysql( btr_pcur_t* clust_pcur = &prebuilt->clust_pcur; trx_t* trx = prebuilt->trx; - ut_ad(prebuilt && trx); + ut_ad(prebuilt != NULL); + ut_ad(trx != NULL); if (UNIV_UNLIKELY (!srv_locks_unsafe_for_binlog @@ -4473,7 +4478,7 @@ row_mysql_drop_temp_tables(void) Drop all foreign keys in a database, see Bug#18942. Called at the end of row_drop_database_for_mysql(). @return error code or DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t drop_all_foreign_keys_in_db( /*========================*/ @@ -4665,7 +4670,7 @@ row_drop_database_for_mysql( Checks if a table name contains the string "/#sql" which denotes temporary tables in MySQL. @return true if temporary table */ -UNIV_INTERN __attribute__((warn_unused_result)) +UNIV_INTERN MY_ATTRIBUTE((warn_unused_result)) bool row_is_mysql_tmp_table_name( /*========================*/ @@ -4679,7 +4684,7 @@ row_is_mysql_tmp_table_name( /****************************************************************//** Delete a single constraint. @return error code or DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_delete_constraint_low( /*======================*/ @@ -4702,7 +4707,7 @@ row_delete_constraint_low( /****************************************************************//** Delete a single constraint. @return error code or DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_delete_constraint( /*==================*/ diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc index b26ba971a9538..bc2e0b0e1cb1f 100644 --- a/storage/innobase/row/row0purge.cc +++ b/storage/innobase/row/row0purge.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -69,7 +69,8 @@ row_purge_node_create( { purge_node_t* node; - ut_ad(parent && heap); + ut_ad(parent != NULL); + ut_ad(heap != NULL); node = static_cast( mem_heap_zalloc(heap, sizeof(*node))); @@ -120,7 +121,7 @@ row_purge_reposition_pcur( Removes a delete marked clustered index record if possible. @retval true if the row was not found, or it was successfully removed @retval false if the row was modified after the delete marking */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_purge_remove_clust_if_poss_low( /*===============================*/ @@ -202,7 +203,7 @@ marking. @retval true if the row was not found, or it was successfully removed @retval false the purge needs to be suspended because of running out of file space. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_purge_remove_clust_if_poss( /*===========================*/ @@ -274,7 +275,7 @@ row_purge_poss_sec( Removes a secondary index entry if possible, by modifying the index tree. Does not try to buffer the delete. @return TRUE if success or if not found */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) ibool row_purge_remove_sec_if_poss_tree( /*==============================*/ @@ -396,7 +397,7 @@ Removes a secondary index entry without modifying the index tree, if possible. @retval true if success or if not found @retval false if row_purge_remove_sec_if_poss_tree() should be invoked */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_purge_remove_sec_if_poss_leaf( /*==============================*/ @@ -507,7 +508,7 @@ row_purge_remove_sec_if_poss_leaf( /***********************************************************//** Removes a secondary index entry if possible. */ -UNIV_INLINE __attribute__((nonnull(1,2))) +UNIV_INLINE MY_ATTRIBUTE((nonnull(1,2))) void row_purge_remove_sec_if_poss( /*=========================*/ @@ -554,7 +555,7 @@ Purges a delete marking of a record. @retval true if the row was not found, or it was successfully removed @retval false the purge needs to be suspended because of running out of file space */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_purge_del_mark( /*===============*/ @@ -745,7 +746,8 @@ row_purge_parse_undo_rec( ulint info_bits; ulint type; - ut_ad(node && thr); + ut_ad(node != NULL); + ut_ad(thr != NULL); ptr = trx_undo_rec_get_pars( undo_rec, &type, &node->cmpl_info, @@ -830,7 +832,7 @@ row_purge_parse_undo_rec( /***********************************************************//** Purges the parsed record. @return true if purged, false if skipped */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool row_purge_record_func( /*==================*/ @@ -895,7 +897,7 @@ row_purge_record_func( Fetches an undo log record and does the purge for the recorded operation. If none left, or the current purge completed, returns the control to the parent node, which is always a query thread node. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_purge( /*======*/ diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index ecd6f47947b23..583fbe60fb34b 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2012, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -37,7 +37,7 @@ Created 2012-02-08 by Sunny Bains. /*********************************************************************//** Write the meta data (index user fields) config file. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_quiesce_write_index_fields( /*===========================*/ @@ -97,7 +97,7 @@ row_quiesce_write_index_fields( /*********************************************************************//** Write the meta data config file index information. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_quiesce_write_indexes( /*======================*/ @@ -210,7 +210,7 @@ Write the meta data (table columns) config file. Serialise the contents of dict_col_t structure, along with the column name. All fields are serialized as ib_uint32_t. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_quiesce_write_table( /*====================*/ @@ -293,7 +293,7 @@ row_quiesce_write_table( /*********************************************************************//** Write the meta data config file header. @return DB_SUCCESS or error code. */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_quiesce_write_header( /*=====================*/ @@ -415,7 +415,7 @@ row_quiesce_write_header( /*********************************************************************//** Write the table meta data after quiesce. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_quiesce_write_cfg( /*==================*/ @@ -530,10 +530,8 @@ row_quiesce_table_start( trx_purge_stop(); } - ut_a(table->id > 0); - for (ulint count = 0; - ibuf_contract_in_background(table->id, TRUE) != 0 + ibuf_merge_space(table->space) != 0 && !trx_is_interrupted(trx); ++count) { if (!(count % 20)) { diff --git a/storage/innobase/row/row0row.cc b/storage/innobase/row/row0row.cc index be786f954fb9f..96d25e15777db 100644 --- a/storage/innobase/row/row0row.cc +++ b/storage/innobase/row/row0row.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -240,7 +240,9 @@ row_build( ulint offsets_[REC_OFFS_NORMAL_SIZE]; rec_offs_init(offsets_); - ut_ad(index && rec && heap); + ut_ad(index != NULL); + ut_ad(rec != NULL); + ut_ad(heap != NULL); ut_ad(dict_index_is_clust(index)); ut_ad(!mutex_own(&trx_sys->mutex)); ut_ad(!col_map || col_table); @@ -409,7 +411,9 @@ row_rec_to_index_entry_low( ulint len; ulint rec_len; - ut_ad(rec && heap && index); + ut_ad(rec != NULL); + ut_ad(heap != NULL); + ut_ad(index != NULL); /* Because this function may be invoked by row0merge.cc on a record whose header is in different format, the check rec_offs_validate(rec, index, offsets) must be avoided here. */ @@ -464,7 +468,9 @@ row_rec_to_index_entry( byte* buf; const rec_t* copy_rec; - ut_ad(rec && heap && index); + ut_ad(rec != NULL); + ut_ad(heap != NULL); + ut_ad(index != NULL); ut_ad(rec_offs_validate(rec, index, offsets)); /* Take a copy of rec to heap */ @@ -523,7 +529,9 @@ row_build_row_ref( ulint* offsets = offsets_; rec_offs_init(offsets_); - ut_ad(index && rec && heap); + ut_ad(index != NULL); + ut_ad(rec != NULL); + ut_ad(heap != NULL); ut_ad(!dict_index_is_clust(index)); offsets = rec_get_offsets(rec, index, offsets, diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index b7bc3cff64535..42b1ab5763012 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -675,7 +675,7 @@ sel_enqueue_prefetched_row( /*********************************************************************//** Builds a previous version of a clustered index record for a consistent read @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_sel_build_prev_vers( /*====================*/ @@ -710,7 +710,7 @@ row_sel_build_prev_vers( /*********************************************************************//** Builds the last committed version of a clustered index record for a semi-consistent read. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_sel_build_committed_vers_for_mysql( /*===================================*/ @@ -808,7 +808,7 @@ row_sel_test_other_conds( Retrieves the clustered index record corresponding to a record in a non-clustered index. Does the necessary locking. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_sel_get_clust_rec( /*==================*/ @@ -1312,7 +1312,7 @@ row_sel_try_search_shortcut( /*********************************************************************//** Performs a select step. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_sel( /*====*/ @@ -2563,7 +2563,7 @@ row_sel_store_row_id_to_prebuilt( /**************************************************************//** Stores a non-SQL-NULL field in the MySQL format. The counterpart of this function is row_mysql_store_col_in_innobase_format() in row0mysql.cc. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_sel_field_store_in_mysql_format_func( /*=====================================*/ @@ -2752,7 +2752,7 @@ row_sel_field_store_in_mysql_format_func( #endif /* UNIV_DEBUG */ /**************************************************************//** Convert a field in the Innobase format to a field in the MySQL format. */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) ibool row_sel_store_mysql_field_func( /*===========================*/ @@ -2902,7 +2902,7 @@ Note that the template in prebuilt may advise us to copy only a few columns to mysql_rec, other columns are left blank. All columns may not be needed in the query. @return TRUE on success, FALSE if not all columns could be retrieved */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) ibool row_sel_store_mysql_rec( /*====================*/ @@ -2964,7 +2964,7 @@ row_sel_store_mysql_rec( /*********************************************************************//** Builds a previous version of a clustered index record for a consistent read @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_sel_build_prev_vers_for_mysql( /*==============================*/ @@ -3001,7 +3001,7 @@ Retrieves the clustered index record corresponding to a record in a non-clustered index. Does the necessary locking. Used in the MySQL interface. @return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_sel_get_clust_rec_for_mysql( /*============================*/ diff --git a/storage/innobase/row/row0uins.cc b/storage/innobase/row/row0uins.cc index 849bf09649259..651042fb820df 100644 --- a/storage/innobase/row/row0uins.cc +++ b/storage/innobase/row/row0uins.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -61,7 +61,7 @@ introduced where a call to log_free_check() is bypassed. */ Removes a clustered index record. The pcur in node was positioned on the record, now it is detached. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_ins_remove_clust_rec( /*==========================*/ @@ -176,7 +176,7 @@ row_undo_ins_remove_clust_rec( /***************************************************************//** Removes a secondary index entry if found. @return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_ins_remove_sec_low( /*========================*/ @@ -251,7 +251,7 @@ row_undo_ins_remove_sec_low( Removes a secondary index entry from the index if found. Tries first optimistic, then pessimistic descent down the tree. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_ins_remove_sec( /*====================*/ @@ -350,7 +350,7 @@ row_undo_ins_parse_undo_rec( /***************************************************************//** Removes secondary index records. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_ins_remove_sec_rec( /*========================*/ diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc index 29252c7834a87..4b44245bd96d6 100644 --- a/storage/innobase/row/row0umod.cc +++ b/storage/innobase/row/row0umod.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -72,7 +72,7 @@ introduced where a call to log_free_check() is bypassed. */ /***********************************************************//** Undoes a modify in a clustered index record. @return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_clust_low( /*===================*/ @@ -154,7 +154,7 @@ This is attempted when the record was inserted by updating a delete-marked record and there no longer exist transactions that would see the delete-marked record. @return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_remove_clust_low( /*==========================*/ @@ -243,7 +243,7 @@ row_undo_mod_remove_clust_low( Undoes a modify in a clustered index record. Sets also the node state for the next round of undo. @return DB_SUCCESS or error code: we may run out of file space */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_clust( /*===============*/ @@ -380,7 +380,7 @@ row_undo_mod_clust( /***********************************************************//** Delete marks or removes a secondary index entry if found. @return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_del_mark_or_remove_sec_low( /*====================================*/ @@ -516,7 +516,7 @@ not cause problems because in row0sel.cc, in queries we always retrieve the clustered index record or an earlier version of it, if the secondary index record through which we do the search is delete-marked. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_del_mark_or_remove_sec( /*================================*/ @@ -549,7 +549,7 @@ fields but alphabetically they stayed the same, e.g., 'abc' -> 'aBc'. @retval DB_OUT_OF_FILE_SPACE when running out of tablespace @retval DB_DUPLICATE_KEY if the value was missing and an insert would lead to a duplicate exists */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_del_unmark_sec_and_undo_update( /*========================================*/ @@ -745,7 +745,7 @@ row_undo_mod_del_unmark_sec_and_undo_update( /***********************************************************//** Flags a secondary index corrupted. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_undo_mod_sec_flag_corrupted( /*============================*/ @@ -777,7 +777,7 @@ row_undo_mod_sec_flag_corrupted( /***********************************************************//** Undoes a modify in secondary indexes when undo record type is UPD_DEL. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_upd_del_sec( /*=====================*/ @@ -844,7 +844,7 @@ row_undo_mod_upd_del_sec( /***********************************************************//** Undoes a modify in secondary indexes when undo record type is DEL_MARK. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_del_mark_sec( /*======================*/ @@ -912,7 +912,7 @@ row_undo_mod_del_mark_sec( /***********************************************************//** Undoes a modify in secondary indexes when undo record type is UPD_EXIST. @return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo_mod_upd_exist_sec( /*=======================*/ @@ -1028,7 +1028,7 @@ row_undo_mod_upd_exist_sec( /***********************************************************//** Parses the row reference and other info in a modify undo log record. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void row_undo_mod_parse_undo_rec( /*========================*/ @@ -1105,7 +1105,8 @@ row_undo_mod( dberr_t err; ibool dict_locked; - ut_ad(node && thr); + ut_ad(node != NULL); + ut_ad(thr != NULL); ut_ad(node->state == UNDO_NODE_MODIFY); dict_locked = thr_get_trx(thr)->dict_operation_lock_mode == RW_X_LATCH; diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc index 9977a1e8f0424..149dc6719301e 100644 --- a/storage/innobase/row/row0undo.cc +++ b/storage/innobase/row/row0undo.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -245,7 +245,7 @@ Fetches an undo log record and does the undo for the recorded operation. If none left, or a partial rollback completed, returns control to the parent node, which is always a query thread node. @return DB_SUCCESS if operation successfully completed, else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_undo( /*=====*/ @@ -257,7 +257,8 @@ row_undo( roll_ptr_t roll_ptr; ibool locked_data_dict; - ut_ad(node && thr); + ut_ad(node != NULL); + ut_ad(thr != NULL); trx = node->trx; diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index fcd54332a47ae..1cdfe9f5774f6 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -170,7 +170,7 @@ NOTE that this function will temporarily commit mtr and lose the pcur position! @return DB_SUCCESS or an error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_check_references_constraints( /*=================================*/ @@ -607,7 +607,7 @@ row_upd_write_sys_vals_to_log( roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */ byte* log_ptr,/*!< pointer to a buffer of size > 20 opened in mlog */ - mtr_t* mtr __attribute__((unused))) /*!< in: mtr */ + mtr_t* mtr MY_ATTRIBUTE((unused))) /*!< in: mtr */ { ut_ad(dict_index_is_clust(index)); ut_ad(mtr); @@ -1642,7 +1642,7 @@ row_upd_store_row( Updates a secondary index entry of a row. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_sec_index_entry( /*====================*/ @@ -1844,7 +1844,7 @@ Updates the secondary index record if it is changed in the row update or deletes it if this is a delete. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_sec_step( /*=============*/ @@ -1877,7 +1877,7 @@ updated. We must mark them as inherited in entry, so that they are not freed in a rollback. A limited version of this function used to be called btr_cur_mark_dtuple_inherited_extern(). @return TRUE if any columns were inherited */ -static __attribute__((warn_unused_result)) +static MY_ATTRIBUTE((warn_unused_result)) ibool row_upd_clust_rec_by_insert_inherit_func( /*=====================================*/ @@ -1956,7 +1956,7 @@ fields of the clustered index record change. This should be quite rare in database applications. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_clust_rec_by_insert( /*========================*/ @@ -2081,7 +2081,7 @@ Updates a clustered index record of a row when the ordering fields do not change. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_clust_rec( /*==============*/ @@ -2240,7 +2240,7 @@ row_upd_clust_rec( /***********************************************************//** Delete marks a clustered index record. @return DB_SUCCESS if operation successfully completed, else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_del_mark_clust_rec( /*=======================*/ @@ -2292,7 +2292,7 @@ row_upd_del_mark_clust_rec( Updates the clustered index record. @return DB_SUCCESS if operation successfully completed, DB_LOCK_WAIT in case of a lock wait, else error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd_clust_step( /*===============*/ @@ -2488,7 +2488,7 @@ to this node, we assume that we have a persistent cursor which was on a record, and the position of the cursor is stored in the cursor. @return DB_SUCCESS if operation successfully completed, else error code or DB_LOCK_WAIT */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t row_upd( /*====*/ @@ -2497,7 +2497,8 @@ row_upd( { dberr_t err = DB_SUCCESS; - ut_ad(node && thr); + ut_ad(node != NULL); + ut_ad(thr != NULL); if (UNIV_LIKELY(node->in_mysql_interface)) { diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 858555ee55cb2..7a7783b962ca5 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1497,7 +1497,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_monitor_thread)( /*===============================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { @@ -1674,7 +1674,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_error_monitor_thread)( /*=====================================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { @@ -2102,7 +2102,7 @@ srv_master_do_active_tasks(void) /* Do an ibuf merge */ srv_main_thread_op_info = "doing insert buffer merge"; counter_time = ut_time_us(NULL); - ibuf_contract_in_background(0, FALSE); + ibuf_merge_in_background(false); MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time); @@ -2194,7 +2194,7 @@ srv_master_do_idle_tasks(void) /* Do an ibuf merge */ counter_time = ut_time_us(NULL); srv_main_thread_op_info = "doing insert buffer merge"; - ibuf_contract_in_background(0, TRUE); + ibuf_merge_in_background(true); MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time); @@ -2270,7 +2270,7 @@ srv_master_do_shutdown_tasks( /* Do an ibuf merge */ srv_main_thread_op_info = "doing insert buffer merge"; - n_bytes_merged = ibuf_contract_in_background(0, TRUE); + n_bytes_merged = ibuf_merge_in_background(true); /* Flush logs if needed */ srv_sync_log_buffer_in_background(); @@ -2310,7 +2310,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_master_thread)( /*==============================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { @@ -2454,7 +2454,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_worker_thread)( /*==============================*/ - void* arg __attribute__((unused))) /*!< in: a dummy parameter + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { srv_slot_t* slot; @@ -2712,7 +2712,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(srv_purge_coordinator_thread)( /*=========================================*/ - void* arg __attribute__((unused))) /*!< in: a dummy parameter + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { srv_slot_t* slot; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 5a9aeb75e8571..697107a1e0d39 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. @@ -509,7 +509,7 @@ UNIV_INTERN void srv_normalize_path_for_win( /*=======================*/ - char* str __attribute__((unused))) /*!< in/out: null-terminated + char* str MY_ATTRIBUTE((unused))) /*!< in/out: null-terminated character string */ { #ifdef __WIN__ @@ -526,7 +526,7 @@ srv_normalize_path_for_win( /*********************************************************************//** Creates a log file. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t create_log_file( /*============*/ @@ -733,7 +733,7 @@ create_log_files_rename( /*********************************************************************//** Opens a log file. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t open_log_file( /*==========*/ @@ -761,7 +761,7 @@ open_log_file( /*********************************************************************//** Creates or opens database data files and closes them. @return DB_SUCCESS or error code */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t open_or_create_data_files( /*======================*/ diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc index 3ca495aaa8c72..4df35053d0d53 100644 --- a/storage/innobase/sync/sync0sync.cc +++ b/storage/innobase/sync/sync0sync.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -387,10 +387,10 @@ ulint mutex_enter_nowait_func( /*====================*/ ib_mutex_t* mutex, /*!< in: pointer to mutex */ - const char* file_name __attribute__((unused)), + const char* file_name MY_ATTRIBUTE((unused)), /*!< in: file name where mutex requested */ - ulint line __attribute__((unused))) + ulint line MY_ATTRIBUTE((unused))) /*!< in: line where requested */ { ut_ad(mutex_validate(mutex)); diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 56d46311f62d9..efc600d16b1cc 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -913,7 +913,7 @@ Fetches the next undo log record from the history list to purge. It must be released with the corresponding release function. @return copy of an undo log record or pointer to trx_purge_dummy_rec, if the whole undo log can skipped in purge; NULL if none left */ -static __attribute__((warn_unused_result, nonnull)) +static MY_ATTRIBUTE((warn_unused_result, nonnull)) trx_undo_rec_t* trx_purge_fetch_next_rec( /*=====================*/ diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index a698b37c2a6f7..868a8a6c0b687 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -1132,7 +1132,7 @@ trx_undo_rec_get_partial_row( /***********************************************************************//** Erases the unused undo log page end. @return TRUE if the page contained something, FALSE if it was empty */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) ibool trx_undo_erase_page_end( /*====================*/ @@ -1158,7 +1158,7 @@ byte* trx_undo_parse_erase_page_end( /*==========================*/ byte* ptr, /*!< in: buffer */ - byte* end_ptr __attribute__((unused)), /*!< in: buffer end */ + byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */ page_t* page, /*!< in: page or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ { @@ -1441,7 +1441,7 @@ NOTE: the caller must have latches on the clustered index page. @retval true if the undo log has been truncated and we cannot fetch the old version @retval false if the undo log record is available */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) bool trx_undo_get_undo_rec( /*==================*/ @@ -1469,7 +1469,7 @@ trx_undo_get_undo_rec( #ifdef UNIV_DEBUG #define ATTRIB_USED_ONLY_IN_DEBUG #else /* UNIV_DEBUG */ -#define ATTRIB_USED_ONLY_IN_DEBUG __attribute__((unused)) +#define ATTRIB_USED_ONLY_IN_DEBUG MY_ATTRIBUTE((unused)) #endif /* UNIV_DEBUG */ /*******************************************************************//** diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index bc11f1d76bd45..e1e253cbb764d 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -336,7 +336,7 @@ the row, these locks are naturally released in the rollback. Savepoints which were set after this savepoint are deleted. @return if no savepoint of the name found then DB_NO_SAVEPOINT, otherwise DB_SUCCESS */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t trx_rollback_to_savepoint_for_mysql_low( /*====================================*/ @@ -796,7 +796,7 @@ extern "C" UNIV_INTERN os_thread_ret_t DECLARE_THREAD(trx_rollback_or_clean_all_recovered)( /*================================================*/ - void* arg __attribute__((unused))) + void* arg MY_ATTRIBUTE((unused))) /*!< in: a dummy parameter required by os_thread_create */ { diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 937a64a0e46be..9d6196333d7d9 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -959,7 +959,7 @@ trx_serialisation_number_get( /****************************************************************//** Assign the transaction its history serialisation number and write the update UNDO log record to the assigned rollback segment. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void trx_write_serialisation_history( /*============================*/ @@ -1030,7 +1030,7 @@ trx_write_serialisation_history( /******************************************************************** Finalize a transaction containing updates for a FTS table. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void trx_finalize_for_fts_table( /*=======================*/ @@ -1063,7 +1063,7 @@ trx_finalize_for_fts_table( /******************************************************************//** Finalize a transaction containing updates to FTS tables. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void trx_finalize_for_fts( /*=================*/ @@ -1130,7 +1130,7 @@ trx_flush_log_if_needed_low( /**********************************************************************//** If required, flushes the log to disk based on the value of innodb_flush_log_at_trx_commit. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void trx_flush_log_if_needed( /*====================*/ @@ -1145,7 +1145,7 @@ trx_flush_log_if_needed( /****************************************************************//** Commits a transaction in memory. */ -static __attribute__((nonnull)) +static MY_ATTRIBUTE((nonnull)) void trx_commit_in_memory( /*=================*/ @@ -2136,7 +2136,7 @@ which is in the prepared state @return trx on match, the trx->xid will be invalidated; note that the trx may have been committed, unless the caller is holding lock_sys->mutex */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) trx_t* trx_get_trx_by_xid_low( /*===================*/ diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 290271c6cab2e..2ddb35d5ad08e 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -419,11 +419,11 @@ trx_undo_page_init( Creates a new undo log segment in file. @return DB_SUCCESS if page creation OK possible error codes are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t trx_undo_seg_create( /*================*/ - trx_rseg_t* rseg __attribute__((unused)),/*!< in: rollback segment */ + trx_rseg_t* rseg MY_ATTRIBUTE((unused)),/*!< in: rollback segment */ trx_rsegf_t* rseg_hdr,/*!< in: rollback segment header, page x-latched */ ulint type, /*!< in: type of the segment: TRX_UNDO_INSERT or @@ -443,7 +443,9 @@ trx_undo_seg_create( ibool success; dberr_t err = DB_SUCCESS; - ut_ad(mtr && id && rseg_hdr); + ut_ad(mtr != NULL); + ut_ad(id != NULL); + ut_ad(rseg_hdr != NULL); ut_ad(mutex_own(&(rseg->mutex))); /* fputs(type == TRX_UNDO_INSERT @@ -827,7 +829,7 @@ byte* trx_undo_parse_discard_latest( /*==========================*/ byte* ptr, /*!< in: buffer */ - byte* end_ptr __attribute__((unused)), /*!< in: buffer end */ + byte* end_ptr MY_ATTRIBUTE((unused)), /*!< in: buffer end */ page_t* page, /*!< in: page or NULL */ mtr_t* mtr) /*!< in: mtr or NULL */ { @@ -1557,7 +1559,7 @@ Creates a new undo log. @return DB_SUCCESS if successful in creating the new undo lob object, possible error codes are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY */ -static __attribute__((nonnull, warn_unused_result)) +static MY_ATTRIBUTE((nonnull, warn_unused_result)) dberr_t trx_undo_create( /*============*/ From 51ed64a520dfbec24b73bffc40494d738713df22 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 21 Jun 2016 14:22:52 +0200 Subject: [PATCH 088/112] 5.6.31 --- include/mysql/psi/mysql_file.h | 8 ++++---- include/mysql/psi/mysql_socket.h | 10 +++++----- include/mysql/psi/mysql_thread.h | 26 +++++++++++++------------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h index c839b2b019bbb..a83e2ef8a1df5 100644 --- a/include/mysql/psi/mysql_file.h +++ b/include/mysql/psi/mysql_file.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -511,9 +511,9 @@ static inline void inline_mysql_file_register( PSI_file_info *info, int count #else - const char *category __attribute__ ((unused)), - void *info __attribute__ ((unused)), - int count __attribute__ ((unused)) + const char *category MY_ATTRIBUTE ((unused)), + void *info MY_ATTRIBUTE ((unused)), + int count MY_ATTRIBUTE ((unused)) #endif ) { diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h index e1d56539f853c..209f113ffe272 100644 --- a/include/mysql/psi/mysql_socket.h +++ b/include/mysql/psi/mysql_socket.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -114,9 +114,9 @@ mysql_socket_set_address( const struct sockaddr *addr, socklen_t addr_len #else - MYSQL_SOCKET socket __attribute__ ((unused)), - const struct sockaddr *addr __attribute__ ((unused)), - socklen_t addr_len __attribute__ ((unused)) + MYSQL_SOCKET socket MY_ATTRIBUTE ((unused)), + const struct sockaddr *addr MY_ATTRIBUTE ((unused)), + socklen_t addr_len MY_ATTRIBUTE ((unused)) #endif ) { @@ -136,7 +136,7 @@ mysql_socket_set_thread_owner( #ifdef HAVE_PSI_SOCKET_INTERFACE MYSQL_SOCKET socket #else -MYSQL_SOCKET socket __attribute__ ((unused)) +MYSQL_SOCKET socket MY_ATTRIBUTE ((unused)) #endif ) { diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h index 99fcd348e87fb..ee2693d2863ba 100644 --- a/include/mysql/psi/mysql_thread.h +++ b/include/mysql/psi/mysql_thread.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. 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 @@ -587,9 +587,9 @@ static inline void inline_mysql_mutex_register( PSI_mutex_info *info, int count #else - const char *category __attribute__ ((unused)), - void *info __attribute__ ((unused)), - int count __attribute__ ((unused)) + const char *category MY_ATTRIBUTE ((unused)), + void *info MY_ATTRIBUTE ((unused)), + int count MY_ATTRIBUTE ((unused)) #endif ) { @@ -771,9 +771,9 @@ static inline void inline_mysql_rwlock_register( PSI_rwlock_info *info, int count #else - const char *category __attribute__ ((unused)), - void *info __attribute__ ((unused)), - int count __attribute__ ((unused)) + const char *category MY_ATTRIBUTE ((unused)), + void *info MY_ATTRIBUTE ((unused)), + int count MY_ATTRIBUTE ((unused)) #endif ) { @@ -1089,9 +1089,9 @@ static inline void inline_mysql_cond_register( PSI_cond_info *info, int count #else - const char *category __attribute__ ((unused)), - void *info __attribute__ ((unused)), - int count __attribute__ ((unused)) + const char *category MY_ATTRIBUTE ((unused)), + void *info MY_ATTRIBUTE ((unused)), + int count MY_ATTRIBUTE ((unused)) #endif ) { @@ -1231,9 +1231,9 @@ static inline void inline_mysql_thread_register( PSI_thread_info *info, int count #else - const char *category __attribute__ ((unused)), - void *info __attribute__ ((unused)), - int count __attribute__ ((unused)) + const char *category MY_ATTRIBUTE ((unused)), + void *info MY_ATTRIBUTE ((unused)), + int count MY_ATTRIBUTE ((unused)) #endif ) { From 15313216bfeee4882fb1362d2fe2aec508551917 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 26 Apr 2016 13:42:10 +0400 Subject: [PATCH 089/112] MDEV-9993 - connect.json_udf_bin valgrind warnings "result" may be uninitialized when json_set_item() is called directly. --- storage/connect/jsonudf.cpp | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 7b82ba2d62784..2b73d1d759509 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -3568,11 +3568,11 @@ my_bool json_set_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) return JsonInit(initid, args, message, true, reslen, memlen); } // end of json_set_item_init -char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, - unsigned long *res_length, char *is_null, char *error) +static char *json_set_item_core(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *error, int w) { char *p, *path, *str = NULL; - int w, rc; + int rc; my_bool b = true; PJSON jsp; PJSNX jsx; @@ -3586,13 +3586,6 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, } else if (initid->const_item) g->N = 1; - if (!strcmp(result, "$insert")) - w = 1; - else if (!strcmp(result, "$update")) - w = 2; - else - w = 0; - // Save stack and allocation environment and prepare error return if (g->jump_level == MAX_JUMP) { PUSH_WARNING(MSG(TOO_MANY_JUMPS)); @@ -3671,7 +3664,13 @@ char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, *res_length = strlen(str); return str; -} // end of json_set_item +} // end of json_set_item_core + +char *json_set_item(UDF_INIT *initid, UDF_ARGS *args, char *result, + unsigned long *res_length, char *is_null, char *error) +{ + return json_set_item_core(initid, args, result, res_length, is_null, error, 0); +} void json_set_item_deinit(UDF_INIT* initid) { @@ -3689,8 +3688,7 @@ my_bool json_insert_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) char *json_insert_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { - strcpy(result, "$insert"); - return json_set_item(initid, args, result, res_length, is_null, p); + return json_set_item_core(initid, args, result, res_length, is_null, p, 1); } // end of json_insert_item void json_insert_item_deinit(UDF_INIT* initid) @@ -3709,8 +3707,7 @@ my_bool json_update_item_init(UDF_INIT *initid, UDF_ARGS *args, char *message) char *json_update_item(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *res_length, char *is_null, char *p) { - strcpy(result, "$update"); - return json_set_item(initid, args, result, res_length, is_null, p); + return json_set_item_core(initid, args, result, res_length, is_null, p, 2); } // end of json_update_item void json_update_item_deinit(UDF_INIT* initid) From 82a96926a77b38a36a031e34b2c4ff3e36406f3d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 15 Jun 2016 13:57:44 +0400 Subject: [PATCH 090/112] MDEV-9728 - Hard crash in metadata_lock_info metadata_lock_info plugin called MDL_context::find_ticket() to obtain lock duration, which in turn iterates foreign thread private lists. These lists can be updated by owner thread without protection. Fixed by iterating threads (instead of MDL locks and tickets) and obtaining data through APC. Also fixed mdl_iterate_lock() to initialize iterator under prlock protection. --- mysql-test/r/create_or_replace.result | 12 +- mysql-test/t/create_or_replace.test | 10 ++ .../metadata_lock_info/metadata_lock_info.cc | 154 ++++++++++++------ .../r/global_read_lock.result | 2 +- .../t/global_read_lock.test | 2 +- sql/mdl.cc | 4 +- sql/mdl.h | 2 +- 7 files changed, 123 insertions(+), 63 deletions(-) diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result index ff8170b730982..a8348b8a5d07f 100644 --- a/mysql-test/r/create_or_replace.result +++ b/mysql-test/r/create_or_replace.result @@ -265,10 +265,10 @@ lock table test.t1 write, mysqltest2.t2 write; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock mysqltest2 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test # MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock mysqltest2 t2 +# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 create or replace table test.t1; ERROR 42000: A table must have at least 1 column show tables; @@ -292,10 +292,10 @@ lock table test.t1 write, mysqltest2.t2 write; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock mysqltest2 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test # MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock mysqltest2 t2 +# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a'; ERROR 42S21: Duplicate column name 'a' show tables; @@ -401,29 +401,29 @@ lock table t1 write, t2 read; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 create or replace table t1 (i int); select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 create or replace table t1 like t2; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 create or replace table t1 select 1 as f1; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 # MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 drop table t1; unlock tables; diff --git a/mysql-test/t/create_or_replace.test b/mysql-test/t/create_or_replace.test index 9e37950dbeff3..7bba2b341c043 100644 --- a/mysql-test/t/create_or_replace.test +++ b/mysql-test/t/create_or_replace.test @@ -216,15 +216,18 @@ create table test.t1 (i int); create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; --error ER_TABLE_MUST_HAVE_COLUMNS create or replace table test.t1; show tables; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; --error ER_TABLE_MUST_HAVE_COLUMNS create or replace table mysqltest2.t2; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; create table t1 (i int); drop table t1; @@ -233,15 +236,18 @@ create table test.t1 (i int); create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; --error ER_DUP_FIELDNAME create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a'; show tables; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; --error ER_DUP_FIELDNAME create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a'; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; create table t1 (i int); drop table t1; @@ -319,15 +325,19 @@ drop view t1; create table t1 (a int); lock table t1 write, t2 read; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; create or replace table t1 (i int); --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; create or replace table t1 like t2; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; create or replace table t1 select 1 as f1; --replace_column 1 # +--sorted_result select * from information_schema.metadata_lock_info; drop table t1; unlock tables; diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index fcfdb59da3056..19c0ee351031b 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -67,65 +67,115 @@ static ST_FIELD_INFO i_s_metadata_lock_info_fields_info[] = {NULL, 0, MYSQL_TYPE_STRING, 0, 0, NULL, 0} }; -struct st_i_s_metadata_param + +class Ticket_info: public Apc_target::Apc_call { - THD *thd; +public: + bool timed_out; + THD *request_thd; + THD *target_thd; TABLE *table; + int error; + + Ticket_info(THD *request_thd_arg, TABLE *table_arg): + request_thd(request_thd_arg), table(table_arg), error(0) + { } + + void call_in_target_thread() + { + MDL_ticket *ticket; + int i; + + for (i= 0; i < MDL_DURATION_END; i++) + { + MDL_context::Ticket_iterator it(request_thd->mdl_context.m_tickets[i]); + while ((ticket= it++)) + { + MDL_key *key= ticket->get_key(); + + table->field[0]->store((longlong) target_thd->thread_id, TRUE); + + table->field[1]->set_notnull(); + table->field[1]->store( + metadata_lock_info_lock_mode[(int) ticket->get_type()].str, + metadata_lock_info_lock_mode[(int) ticket->get_type()].length, + system_charset_info); + + table->field[2]->set_notnull(); + table->field[2]->store( + metadata_lock_info_duration[i].str, + metadata_lock_info_duration[i].length, + system_charset_info); + + table->field[3]->set_notnull(); + table->field[3]->store( + metadata_lock_info_lock_name[(int) key->mdl_namespace()].str, + metadata_lock_info_lock_name[(int) key->mdl_namespace()].length, + system_charset_info); + + table->field[4]->set_notnull(); + table->field[4]->store(key->db_name(), key->db_name_length(), + system_charset_info); + + table->field[5]->set_notnull(); + table->field[5]->store(key->name(), key->name_length(), + system_charset_info); + + if ((error= schema_table_store_record(request_thd, table))) + return; + } + } + } }; -int i_s_metadata_lock_info_fill_row( - MDL_ticket *mdl_ticket, - void *arg -) { - st_i_s_metadata_param *param = (st_i_s_metadata_param *) arg; - THD *thd = param->thd; - TABLE *table = param->table; - DBUG_ENTER("i_s_metadata_lock_info_fill_row"); - MDL_request mdl_request; - enum_mdl_duration mdl_duration; - MDL_context *mdl_ctx = mdl_ticket->get_ctx(); - enum_mdl_type mdl_ticket_type = mdl_ticket->get_type(); - MDL_key *mdl_key = mdl_ticket->get_key(); - MDL_key::enum_mdl_namespace mdl_namespace = mdl_key->mdl_namespace(); - mdl_request.init(mdl_key, mdl_ticket_type, MDL_STATEMENT); - mdl_ctx->find_ticket(&mdl_request, &mdl_duration); - table->field[0]->store((longlong) mdl_ctx->get_thread_id(), TRUE); - table->field[1]->set_notnull(); - table->field[1]->store( - metadata_lock_info_lock_mode[(int) mdl_ticket_type].str, - metadata_lock_info_lock_mode[(int) mdl_ticket_type].length, - system_charset_info); - table->field[2]->set_notnull(); - table->field[2]->store( - metadata_lock_info_duration[(int) mdl_duration].str, - metadata_lock_info_duration[(int) mdl_duration].length, - system_charset_info); - table->field[3]->set_notnull(); - table->field[3]->store( - metadata_lock_info_lock_name[(int) mdl_namespace].str, - metadata_lock_info_lock_name[(int) mdl_namespace].length, - system_charset_info); - table->field[4]->set_notnull(); - table->field[4]->store(mdl_key->db_name(), - mdl_key->db_name_length(), system_charset_info); - table->field[5]->set_notnull(); - table->field[5]->store(mdl_key->name(), - mdl_key->name_length(), system_charset_info); - if (schema_table_store_record(thd, table)) - DBUG_RETURN(1); - DBUG_RETURN(0); + +static THD *find_thread(my_thread_id id) +{ + THD *tmp; + + mysql_mutex_lock(&LOCK_thread_count); + I_List_iterator it(threads); + while ((tmp= it++)) + { + if (id == tmp->thread_id) + { + mysql_mutex_lock(&tmp->LOCK_thd_data); + break; + } + } + mysql_mutex_unlock(&LOCK_thread_count); + return tmp; } -int i_s_metadata_lock_info_fill_table( - THD *thd, - TABLE_LIST *tables, - COND *cond -) { - st_i_s_metadata_param param; + +static int i_s_metadata_lock_info_fill_table(THD *thd, TABLE_LIST *tables, + COND *cond) +{ + Ticket_info info(thd, tables->table); + DYNAMIC_ARRAY ids; + THD *tmp; + uint i; DBUG_ENTER("i_s_metadata_lock_info_fill_table"); - param.table = tables->table; - param.thd = thd; - DBUG_RETURN(mdl_iterate(i_s_metadata_lock_info_fill_row, ¶m)); + + /* Gather thread identifiers */ + my_init_dynamic_array(&ids, sizeof(my_thread_id), 512, 1, MYF(0)); + mysql_mutex_lock(&LOCK_thread_count); + I_List_iterator it(threads); + while ((tmp= it++)) + if (tmp != thd && (info.error= insert_dynamic(&ids, &tmp->thread_id))) + break; + mysql_mutex_unlock(&LOCK_thread_count); + + /* Let foreign threads fill info */ + for (i= 0; i < ids.elements && info.error == 0; i++) + if ((info.target_thd= find_thread(*dynamic_element(&ids, i, my_thread_id*)))) + info.target_thd->apc_target.make_apc_call(thd, &info, INT_MAX, + &info.timed_out); + + delete_dynamic(&ids); + if (info.error == 0) + info.call_in_target_thread(); + DBUG_RETURN(info.error); } static int i_s_metadata_lock_info_init( diff --git a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result index 9840aeecf973c..61b0a913ca497 100644 --- a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result +++ b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result @@ -1,7 +1,7 @@ SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name FLUSH TABLES WITH READ LOCK; -SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; +SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info ORDER BY lock_type DESC; lock_mode lock_duration lock_type table_schema table_name MDL_SHARED MDL_EXPLICIT Global read lock MDL_SHARED MDL_EXPLICIT Commit lock diff --git a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test index f221191255e40..74fa5e3e1fd3a 100644 --- a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test +++ b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test @@ -1,5 +1,5 @@ SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; FLUSH TABLES WITH READ LOCK; -SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; +SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info ORDER BY lock_type DESC; UNLOCK TABLES; SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; diff --git a/sql/mdl.cc b/sql/mdl.cc index b94a3710fd110..28d2006b023a7 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -706,10 +706,10 @@ static inline int mdl_iterate_lock(MDL_lock *lock, int (*callback)(MDL_ticket *ticket, void *arg), void *arg) { - MDL_lock::Ticket_iterator ticket_it(lock->m_granted); - MDL_ticket *ticket; int res= 0; mysql_prlock_rdlock(&lock->m_rwlock); + MDL_lock::Ticket_iterator ticket_it(lock->m_granted); + MDL_ticket *ticket; while ((ticket= ticket_it++) && !(res= callback(ticket, arg))) /* no-op */; mysql_prlock_unlock(&lock->m_rwlock); return res; diff --git a/sql/mdl.h b/sql/mdl.h index c4d792acd290e..ec7b633a67d9e 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -953,7 +953,7 @@ class MDL_context MDL_context &operator=(MDL_context &rhs); /* not implemented */ /* metadata_lock_info plugin */ - friend int i_s_metadata_lock_info_fill_row(MDL_ticket*, void*); + friend class Ticket_info; }; From 8255781d9b4fa81f330ec5e021de60d6f552447d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 20 Jun 2016 13:54:19 +0400 Subject: [PATCH 091/112] MDEV-10258 - Valgrind warnings in buildbot after a set of mroonga tests Fixed memory leak when mroonga fails to open index files. Memory leak was detected by valgrind when running mroonga/storage.repair_table_no_index_file. --- storage/mroonga/ha_mroonga.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index fb63b3cd1273d..08942deed8dac 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -4184,9 +4184,12 @@ int ha_mroonga::storage_open(const char *name, int mode, uint test_if_locked) if (!(ha_thd()->open_options & HA_OPEN_FOR_REPAIR)) { error = storage_open_indexes(name); if (error) { - // TODO: free grn_columns and set NULL; grn_obj_unlink(ctx, grn_table); grn_table = NULL; + // TODO: unlink elements + free(grn_columns); + // TODO: unlink elements + free(grn_column_ranges); DBUG_RETURN(error); } From 1592fbd332373a110edcc28468cd8dc2b99271ef Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 21 Jun 2016 16:02:35 +0200 Subject: [PATCH 092/112] 8.39 --- pcre/AUTHORS | 6 +- pcre/CMakeLists.txt | 19 +- pcre/ChangeLog | 94 +- pcre/LICENCE | 6 +- pcre/Makefile.am | 1 + pcre/Makefile.in | 6 +- pcre/NEWS | 9 + pcre/RunGrepTest | 9 + pcre/RunTest | 32 +- pcre/aclocal.m4 | 4 +- pcre/config.h.generic | 6 +- pcre/configure | 32 +- pcre/configure.ac | 12 +- pcre/doc/html/pcreapi.html | 9 +- pcre/doc/pcre.txt | 1935 ++++++++-------- pcre/doc/pcreapi.3 | 11 +- pcre/pcre.h.generic | 4 +- pcre/pcre_compile.c | 183 +- pcre/pcre_get.c | 23 +- pcre/pcre_internal.h | 8 +- pcre/pcre_jit_compile.c | 3077 +++++++++++++++++--------- pcre/pcre_jit_test.c | 36 +- pcre/pcre_study.c | 2 +- pcre/pcrecpp.cc | 130 +- pcre/pcregrep.c | 2 +- pcre/pcreposix.c | 6 +- pcre/pcretest.c | 20 +- pcre/sljit/sljitConfigInternal.h | 67 +- pcre/sljit/sljitExecAllocator.c | 8 +- pcre/sljit/sljitLir.c | 422 ++-- pcre/sljit/sljitLir.h | 430 ++-- pcre/sljit/sljitNativeARM_32.c | 398 ++-- pcre/sljit/sljitNativeARM_64.c | 358 +-- pcre/sljit/sljitNativeARM_T2_32.c | 370 ++-- pcre/sljit/sljitNativeMIPS_32.c | 24 +- pcre/sljit/sljitNativeMIPS_64.c | 44 +- pcre/sljit/sljitNativeMIPS_common.c | 380 ++-- pcre/sljit/sljitNativePPC_32.c | 26 +- pcre/sljit/sljitNativePPC_64.c | 28 +- pcre/sljit/sljitNativePPC_common.c | 388 ++-- pcre/sljit/sljitNativeSPARC_32.c | 24 +- pcre/sljit/sljitNativeSPARC_common.c | 288 +-- pcre/sljit/sljitNativeTILEGX_64.c | 212 +- pcre/sljit/sljitNativeX86_32.c | 80 +- pcre/sljit/sljitNativeX86_64.c | 170 +- pcre/sljit/sljitNativeX86_common.c | 706 +++--- pcre/sljit/sljitUtils.c | 11 +- pcre/testdata/testinput11 | 2 + pcre/testdata/testinput2 | 26 + pcre/testdata/testinput6 | 9 + pcre/testdata/testinput7 | 4 + pcre/testdata/testoutput11-16 | 5 +- pcre/testdata/testoutput11-32 | 5 +- pcre/testdata/testoutput11-8 | 5 +- pcre/testdata/testoutput2 | 132 +- pcre/testdata/testoutput6 | 16 + pcre/testdata/testoutput7 | 20 + pcre/testdata/valgrind-jit.supp | 15 + 58 files changed, 5887 insertions(+), 4468 deletions(-) create mode 100644 pcre/testdata/valgrind-jit.supp diff --git a/pcre/AUTHORS b/pcre/AUTHORS index d33723f198a83..342417a8a19b3 100644 --- a/pcre/AUTHORS +++ b/pcre/AUTHORS @@ -8,7 +8,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2015 University of Cambridge +Copyright (c) 1997-2016 University of Cambridge All rights reserved @@ -19,7 +19,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2015 Zoltan Herczeg +Copyright(c) 2010-2016 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2015 Zoltan Herczeg +Copyright(c) 2009-2016 Zoltan Herczeg All rights reserved. diff --git a/pcre/CMakeLists.txt b/pcre/CMakeLists.txt index 846241d64f7ee..ce6b167368823 100644 --- a/pcre/CMakeLists.txt +++ b/pcre/CMakeLists.txt @@ -65,12 +65,15 @@ # so it has been removed. # 2013-10-08 PH got rid of the "source" command, which is a bash-ism (use ".") # 2013-11-05 PH added support for PARENS_NEST_LIMIT +# 2016-03-01 PH applied Chris Wilson's patch for MSVC static build PROJECT(PCRE C CXX) -# Increased minimum to 2.8.0 to support newer add_test features +# Increased minimum to 2.8.0 to support newer add_test features. Set policy +# CMP0026 to avoid warnings for the use of LOCATION in GET_TARGET_PROPERTY. CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0) +CMAKE_POLICY(SET CMP0026 OLD) SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) # for FindReadline.cmake @@ -567,6 +570,20 @@ SET(PCREPOSIX_SOURCES ENDIF (EXISTS ${PROJECT_SOURCE_DIR}/pcreposix.rc) ENDIF(MSVC AND NOT PCRE_STATIC) +# Fix static compilation with MSVC: https://bugs.exim.org/show_bug.cgi?id=1681 +# This code was taken from the CMake wiki, not from WebM. + +IF(MSVC AND PCRE_STATIC) + MESSAGE(STATUS "** MSVC and PCRE_STATIC: modifying compiler flags to use static runtime library") + foreach(flag_var + CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endforeach() +ENDIF(MSVC AND PCRE_STATIC) + SET(PCRECPP_HEADERS pcrecpp.h pcre_scanner.h diff --git a/pcre/ChangeLog b/pcre/ChangeLog index 5e5bf188cea00..a34f845f8a19d 100644 --- a/pcre/ChangeLog +++ b/pcre/ChangeLog @@ -4,12 +4,104 @@ ChangeLog for PCRE Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All development is happening in the PCRE2 10.xx series. +Version 8.39 14-June-2016 +------------------------- + +1. If PCRE_AUTO_CALLOUT was set on a pattern that had a (?# comment between + an item and its qualifier (for example, A(?#comment)?B) pcre_compile() + misbehaved. This bug was found by the LLVM fuzzer. + +2. Similar to the above, if an isolated \E was present between an item and its + qualifier when PCRE_AUTO_CALLOUT was set, pcre_compile() misbehaved. This + bug was found by the LLVM fuzzer. + +3. Further to 8.38/46, negated classes such as [^[:^ascii:]\d] were also not + working correctly in UCP mode. + +4. The POSIX wrapper function regexec() crashed if the option REG_STARTEND + was set when the pmatch argument was NULL. It now returns REG_INVARG. + +5. Allow for up to 32-bit numbers in the ordin() function in pcregrep. + +6. An empty \Q\E sequence between an item and its qualifier caused + pcre_compile() to misbehave when auto callouts were enabled. This bug was + found by the LLVM fuzzer. + +7. If a pattern that was compiled with PCRE_EXTENDED started with white + space or a #-type comment that was followed by (?-x), which turns off + PCRE_EXTENDED, and there was no subsequent (?x) to turn it on again, + pcre_compile() assumed that (?-x) applied to the whole pattern and + consequently mis-compiled it. This bug was found by the LLVM fuzzer. + +8. A call of pcre_copy_named_substring() for a named substring whose number + was greater than the space in the ovector could cause a crash. + +9. Yet another buffer overflow bug involved duplicate named groups with a + group that reset capture numbers (compare 8.38/7 below). Once again, I have + just allowed for more memory, even if not needed. (A proper fix is + implemented in PCRE2, but it involves a lot of refactoring.) + +10. pcre_get_substring_list() crashed if the use of \K in a match caused the + start of the match to be earlier than the end. + +11. Migrating appropriate PCRE2 JIT improvements to PCRE. + +12. A pattern such as /(?<=((?C)0))/, which has a callout inside a lookbehind + assertion, caused pcretest to generate incorrect output, and also to read + uninitialized memory (detected by ASAN or valgrind). + +13. A pattern that included (*ACCEPT) in the middle of a sufficiently deeply + nested set of parentheses of sufficient size caused an overflow of the + compiling workspace (which was diagnosed, but of course is not desirable). + +14. And yet another buffer overflow bug involving duplicate named groups, this + time nested, with a nested back reference. Yet again, I have just allowed + for more memory, because anything more needs all the refactoring that has + been done for PCRE2. An example pattern that provoked this bug is: + /((?J)(?'R'(?'R'(?'R'(?'R'(?'R'(?|(\k'R'))))))))/ and the bug was + registered as CVE-2016-1283. + +15. pcretest went into a loop if global matching was requested with an ovector + size less than 2. It now gives an error message. This bug was found by + afl-fuzz. + +16. An invalid pattern fragment such as (?(?C)0 was not diagnosing an error + ("assertion expected") when (?(?C) was not followed by an opening + parenthesis. + +17. Fixed typo ("&&" for "&") in pcre_study(). Fortunately, this could not + actually affect anything, by sheer luck. + +18. Applied Chris Wilson's patch (Bugzilla #1681) to CMakeLists.txt for MSVC + static compilation. + +19. Modified the RunTest script to incorporate a valgrind suppressions file so + that certain errors, provoked by the SSE2 instruction set when JIT is used, + are ignored. + +20. A racing condition is fixed in JIT reported by Mozilla. + +21. Minor code refactor to avoid "array subscript is below array bounds" + compiler warning. + +22. Minor code refactor to avoid "left shift of negative number" warning. + +23. Fix typo causing compile error when 16- or 32-bit JIT is compiled without + UCP support. + +24. Refactor to avoid compiler warnings in pcrecpp.cc. + +25. Refactor to fix a typo in pcre_jit_test.c + +26. Patch to support compiling pcrecpp.cc with Intel compiler. + + Version 8.38 23-November-2015 ----------------------------- 1. If a group that contained a recursive back reference also contained a forward reference subroutine call followed by a non-forward-reference - subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to + subroutine call, for example /.((?2)(?R)\1)()/, pcre_compile() failed to compile correct code, leading to undefined behaviour or an internally detected error. This bug was discovered by the LLVM fuzzer. diff --git a/pcre/LICENCE b/pcre/LICENCE index 9f6f98e477f47..dd977af971b7c 100644 --- a/pcre/LICENCE +++ b/pcre/LICENCE @@ -25,7 +25,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2015 University of Cambridge +Copyright (c) 1997-2016 University of Cambridge All rights reserved. @@ -36,7 +36,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2015 Zoltan Herczeg +Copyright(c) 2010-2016 Zoltan Herczeg All rights reserved. @@ -47,7 +47,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2015 Zoltan Herczeg +Copyright(c) 2009-2016 Zoltan Herczeg All rights reserved. diff --git a/pcre/Makefile.am b/pcre/Makefile.am index 5f640b003a2cc..22b69471b3c22 100644 --- a/pcre/Makefile.am +++ b/pcre/Makefile.am @@ -613,6 +613,7 @@ EXTRA_DIST += \ testdata/testoutput25 \ testdata/testoutput26 \ testdata/testoutputEBC \ + testdata/valgrind-jit.supp \ testdata/wintestinput3 \ testdata/wintestoutput3 \ perltest.pl diff --git a/pcre/Makefile.in b/pcre/Makefile.in index c2a4530df3dfe..6d039125a979f 100644 --- a/pcre/Makefile.in +++ b/pcre/Makefile.in @@ -1070,9 +1070,9 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre_visibility.m4 doc/perltest.txt \ testdata/testoutput22-16 testdata/testoutput22-32 \ testdata/testoutput23 testdata/testoutput24 \ testdata/testoutput25 testdata/testoutput26 \ - testdata/testoutputEBC testdata/wintestinput3 \ - testdata/wintestoutput3 perltest.pl pcredemo.c $(pcrecpp_man) \ - cmake/COPYING-CMAKE-SCRIPTS \ + testdata/testoutputEBC testdata/valgrind-jit.supp \ + testdata/wintestinput3 testdata/wintestoutput3 perltest.pl \ + pcredemo.c $(pcrecpp_man) cmake/COPYING-CMAKE-SCRIPTS \ cmake/FindPackageHandleStandardArgs.cmake \ cmake/FindReadline.cmake cmake/FindEditline.cmake \ CMakeLists.txt config-cmake.h.in diff --git a/pcre/NEWS b/pcre/NEWS index 7e42dcb3603fa..0ca1bab2a4ce1 100644 --- a/pcre/NEWS +++ b/pcre/NEWS @@ -1,6 +1,15 @@ News about PCRE releases ------------------------ +Release 8.39 14-June-2016 +------------------------- + +Some appropriate PCRE2 JIT improvements have been retro-fitted to PCRE1. Apart +from that, this is another bug-fix release. Note that this library (now called +PCRE1) is now being maintained for bug fixes only. New projects are advised to +use the new PCRE2 libraries. + + Release 8.38 23-November-2015 ----------------------------- diff --git a/pcre/RunGrepTest b/pcre/RunGrepTest index a6e93d3489243..721ec5184ab4d 100755 --- a/pcre/RunGrepTest +++ b/pcre/RunGrepTest @@ -67,6 +67,15 @@ fi ./pcretest -C utf >/dev/null utf8=$? +# We need valgrind suppressions when JIT is in use. (This isn't perfect because +# some tests are run with -no-jit, but as PCRE1 is in maintenance only, I have +# not bothered about that.) + +./pcretest -C jit >/dev/null +if [ $? -eq 1 -a "$valgrind" != "" ] ; then + valgrind="$valgrind --suppressions=./testdata/valgrind-jit.supp" +fi + echo "Testing pcregrep main features" echo "---------------------------- Test 1 ------------------------------" >testtrygrep diff --git a/pcre/RunTest b/pcre/RunTest index 67cfbf07cf9de..357a739b75f82 100755 --- a/pcre/RunTest +++ b/pcre/RunTest @@ -178,6 +178,7 @@ nojit= sim= skip= valgrind= +vjs= # This is in case the caller has set aliases (as I do - PH) unset cp ls mv rm @@ -357,6 +358,9 @@ $sim ./pcretest -C jit >/dev/null jit=$? if [ $jit -ne 0 -a "$nojit" != "yes" ] ; then jitopt=-s+ + if [ "$valgrind" != "" ] ; then + vjs="--suppressions=$testdata/valgrind-jit.supp" + fi fi # If no specific tests were requested, select all. Those that are not @@ -423,7 +427,7 @@ for bmode in "$test8" "$test16" "$test32"; do if [ $do1 = yes ] ; then echo $title1 for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput1 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput1 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput1 testtry if [ $? != 0 ] ; then exit 1; fi @@ -441,7 +445,7 @@ fi if [ $do2 = yes ] ; then echo $title2 "(not UTF-$bits)" for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput2 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput2 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput2 testtry if [ $? != 0 ] ; then exit 1; fi @@ -504,7 +508,7 @@ if [ $do3 = yes ] ; then if [ "$locale" != "" ] ; then echo $title3 "(using '$locale' locale)" for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $infile testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $infile testtry if [ $? = 0 ] ; then if $cf $outfile testtry >teststdout || \ $cf $outfile2 testtry >teststdout || \ @@ -540,7 +544,7 @@ if [ $do4 = yes ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput4 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput4 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput4 testtry if [ $? != 0 ] ; then exit 1; fi @@ -560,7 +564,7 @@ if [ $do5 = yes ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput5 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput5 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput5 testtry if [ $? != 0 ] ; then exit 1; fi @@ -580,7 +584,7 @@ if [ $do6 = yes ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput6 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput6 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput6 testtry if [ $? != 0 ] ; then exit 1; fi @@ -602,7 +606,7 @@ if [ $do7 = yes ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput7 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput7 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput7 testtry if [ $? != 0 ] ; then exit 1; fi @@ -698,7 +702,7 @@ if [ $do12 = yes ] ; then if [ $jit -eq 0 -o "$nojit" = "yes" ] ; then echo " Skipped because JIT is not available or not usable" else - $sim $valgrind ./pcretest -q $bmode $testdata/testinput12 testtry + $sim $valgrind $vjs ./pcretest -q $bmode $testdata/testinput12 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput12 testtry if [ $? != 0 ] ; then exit 1; fi @@ -735,7 +739,7 @@ if [ "$do14" = yes ] ; then cp -f $testdata/saved16 testsaved16 cp -f $testdata/saved32 testsaved32 for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput14 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput14 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput14 testtry if [ $? != 0 ] ; then exit 1; fi @@ -759,7 +763,7 @@ if [ "$do15" = yes ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput15 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput15 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput15 testtry if [ $? != 0 ] ; then exit 1; fi @@ -783,7 +787,7 @@ if [ $do16 = yes ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput16 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput16 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput16 testtry if [ $? != 0 ] ; then exit 1; fi @@ -805,7 +809,7 @@ if [ $do17 = yes ] ; then echo " Skipped when running 8-bit tests" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput17 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput17 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput17 testtry if [ $? != 0 ] ; then exit 1; fi @@ -829,7 +833,7 @@ if [ $do18 = yes ] ; then echo " Skipped because UTF-$bits support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput18 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput18 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput18-$bits testtry if [ $? != 0 ] ; then exit 1; fi @@ -853,7 +857,7 @@ if [ $do19 = yes ] ; then echo " Skipped because Unicode property support is not available" else for opt in "" "-s" $jitopt; do - $sim $valgrind ./pcretest -q $bmode $opt $testdata/testinput19 testtry + $sim $valgrind ${opt:+$vjs} ./pcretest -q $bmode $opt $testdata/testinput19 testtry if [ $? = 0 ] ; then $cf $testdata/testoutput19 testtry if [ $? != 0 ] ; then exit 1; fi diff --git a/pcre/aclocal.m4 b/pcre/aclocal.m4 index 0241dd2342bb9..f118a7ea19c55 100644 --- a/pcre/aclocal.m4 +++ b/pcre/aclocal.m4 @@ -21,7 +21,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29) +dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -63,7 +63,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29]) +[m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ diff --git a/pcre/config.h.generic b/pcre/config.h.generic index 07c12b2677e22..ccc26dbbba238 100644 --- a/pcre/config.h.generic +++ b/pcre/config.h.generic @@ -235,7 +235,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE 8.38" +#define PACKAGE_STRING "PCRE 8.39" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" @@ -244,7 +244,7 @@ sure both macros are undefined; an emulation function will then be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "8.38" +#define PACKAGE_VERSION "8.39" /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested parentheses (of any kind) in a pattern. This limits the amount of system @@ -336,7 +336,7 @@ sure both macros are undefined; an emulation function will then be used. */ /* #undef SUPPORT_VALGRIND */ /* Version number of package */ -#define VERSION "8.38" +#define VERSION "8.39" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/pcre/configure b/pcre/configure index 5ca9342b7915b..54678cf7d163c 100755 --- a/pcre/configure +++ b/pcre/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for PCRE 8.38. +# Generated by GNU Autoconf 2.69 for PCRE 8.39. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='PCRE' PACKAGE_TARNAME='pcre' -PACKAGE_VERSION='8.38' -PACKAGE_STRING='PCRE 8.38' +PACKAGE_VERSION='8.39' +PACKAGE_STRING='PCRE 8.39' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1418,7 +1418,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures PCRE 8.38 to adapt to many kinds of systems. +\`configure' configures PCRE 8.39 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1488,7 +1488,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of PCRE 8.38:";; + short | recursive ) echo "Configuration of PCRE 8.39:";; esac cat <<\_ACEOF @@ -1662,7 +1662,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -PCRE configure 8.38 +PCRE configure 8.39 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2419,7 +2419,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by PCRE $as_me 8.38, which was +It was created by PCRE $as_me 8.39, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3283,7 +3283,7 @@ fi # Define the identity of the package. PACKAGE='pcre' - VERSION='8.38' + VERSION='8.39' cat >>confdefs.h <<_ACEOF @@ -17634,9 +17634,9 @@ _ACEOF # Versioning PCRE_MAJOR="8" -PCRE_MINOR="38" +PCRE_MINOR="39" PCRE_PRERELEASE="" -PCRE_DATE="2015-11-23" +PCRE_DATE="2016-06-14" if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09" then @@ -19658,16 +19658,16 @@ esac # (Note: The libpcre*_version bits are m4 variables, assigned above) EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \ - $NO_UNDEFINED -version-info 3:6:2" + $NO_UNDEFINED -version-info 3:7:2" EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \ - $NO_UNDEFINED -version-info 2:6:2" + $NO_UNDEFINED -version-info 2:7:2" EXTRA_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \ - $NO_UNDEFINED -version-info 0:6:0" + $NO_UNDEFINED -version-info 0:7:0" EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \ - $NO_UNDEFINED -version-info 0:3:0" + $NO_UNDEFINED -version-info 0:4:0" EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \ $NO_UNDEFINED -version-info 0:1:0 \ @@ -20719,7 +20719,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by PCRE $as_me 8.38, which was +This file was extended by PCRE $as_me 8.39, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20785,7 +20785,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -PCRE config.status 8.38 +PCRE config.status 8.39 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/pcre/configure.ac b/pcre/configure.ac index 9ebe598746c3d..3cefaf100f98a 100644 --- a/pcre/configure.ac +++ b/pcre/configure.ac @@ -9,18 +9,18 @@ dnl The PCRE_PRERELEASE feature is for identifying release candidates. It might dnl be defined as -RC2, for example. For real releases, it should be empty. m4_define(pcre_major, [8]) -m4_define(pcre_minor, [38]) +m4_define(pcre_minor, [39]) m4_define(pcre_prerelease, []) -m4_define(pcre_date, [2015-11-23]) +m4_define(pcre_date, [2016-06-14]) # NOTE: The CMakeLists.txt file searches for the above variables in the first # 50 lines of this file. Please update that if the variables above are moved. # Libtool shared library interface versions (current:revision:age) -m4_define(libpcre_version, [3:6:2]) -m4_define(libpcre16_version, [2:6:2]) -m4_define(libpcre32_version, [0:6:0]) -m4_define(libpcreposix_version, [0:3:0]) +m4_define(libpcre_version, [3:7:2]) +m4_define(libpcre16_version, [2:7:2]) +m4_define(libpcre32_version, [0:7:0]) +m4_define(libpcreposix_version, [0:4:0]) m4_define(libpcrecpp_version, [0:1:0]) AC_PREREQ(2.57) diff --git a/pcre/doc/html/pcreapi.html b/pcre/doc/html/pcreapi.html index b401ecc76df6d..2d7adf185a6df 100644 --- a/pcre/doc/html/pcreapi.html +++ b/pcre/doc/html/pcreapi.html @@ -315,9 +315,8 @@

pcreapi man page

building PCRE, for use in environments that have limited stacks. Because of the greater use of memory management, it runs more slowly. Separate functions are provided so that special-purpose external code can be used for this case. When -used, these functions are always called in a stack-like manner (last obtained, -first freed), and always for memory blocks of the same size. There is a -discussion about PCRE's stack usage in the +used, these functions always allocate memory blocks of the same size. There is +a discussion about PCRE's stack usage in the pcrestack documentation.

@@ -2913,9 +2912,9 @@

pcreapi man page


REVISION

-Last updated: 09 February 2014 +Last updated: 18 December 2015
-Copyright © 1997-2014 University of Cambridge. +Copyright © 1997-2015 University of Cambridge.

Return to the PCRE index page. diff --git a/pcre/doc/pcre.txt b/pcre/doc/pcre.txt index 76a47c79eff8d..f5eb347e18aef 100644 --- a/pcre/doc/pcre.txt +++ b/pcre/doc/pcre.txt @@ -1814,84 +1814,83 @@ PCRE API OVERVIEW ments that have limited stacks. Because of the greater use of memory management, it runs more slowly. Separate functions are provided so that special-purpose external code can be used for this case. When - used, these functions are always called in a stack-like manner (last - obtained, first freed), and always for memory blocks of the same size. - There is a discussion about PCRE's stack usage in the pcrestack docu- + used, these functions always allocate memory blocks of the same size. + There is a discussion about PCRE's stack usage in the pcrestack docu- mentation. The global variable pcre_callout initially contains NULL. It can be set - by the caller to a "callout" function, which PCRE will then call at - specified points during a matching operation. Details are given in the + by the caller to a "callout" function, which PCRE will then call at + specified points during a matching operation. Details are given in the pcrecallout documentation. The global variable pcre_stack_guard initially contains NULL. It can be - set by the caller to a function that is called by PCRE whenever it - starts to compile a parenthesized part of a pattern. When parentheses + set by the caller to a function that is called by PCRE whenever it + starts to compile a parenthesized part of a pattern. When parentheses are nested, PCRE uses recursive function calls, which use up the system - stack. This function is provided so that applications with restricted - stacks can force a compilation error if the stack runs out. The func- + stack. This function is provided so that applications with restricted + stacks can force a compilation error if the stack runs out. The func- tion should return zero if all is well, or non-zero to force an error. NEWLINES - PCRE supports five different conventions for indicating line breaks in - strings: a single CR (carriage return) character, a single LF (line- + PCRE supports five different conventions for indicating line breaks in + strings: a single CR (carriage return) character, a single LF (line- feed) character, the two-character sequence CRLF, any of the three pre- - ceding, or any Unicode newline sequence. The Unicode newline sequences - are the three just mentioned, plus the single characters VT (vertical + ceding, or any Unicode newline sequence. The Unicode newline sequences + are the three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line separator, U+2028), and PS (paragraph separator, U+2029). - Each of the first three conventions is used by at least one operating - system as its standard newline sequence. When PCRE is built, a default - can be specified. The default default is LF, which is the Unix stan- - dard. When PCRE is run, the default can be overridden, either when a + Each of the first three conventions is used by at least one operating + system as its standard newline sequence. When PCRE is built, a default + can be specified. The default default is LF, which is the Unix stan- + dard. When PCRE is run, the default can be overridden, either when a pattern is compiled, or when it is matched. At compile time, the newline convention can be specified by the options - argument of pcre_compile(), or it can be specified by special text at + argument of pcre_compile(), or it can be specified by special text at the start of the pattern itself; this overrides any other settings. See the pcrepattern page for details of the special character sequences. In the PCRE documentation the word "newline" is used to mean "the char- - acter or pair of characters that indicate a line break". The choice of - newline convention affects the handling of the dot, circumflex, and + acter or pair of characters that indicate a line break". The choice of + newline convention affects the handling of the dot, circumflex, and dollar metacharacters, the handling of #-comments in /x mode, and, when - CRLF is a recognized line ending sequence, the match position advance- + CRLF is a recognized line ending sequence, the match position advance- ment for a non-anchored pattern. There is more detail about this in the section on pcre_exec() options below. - The choice of newline convention does not affect the interpretation of - the \n or \r escape sequences, nor does it affect what \R matches, + The choice of newline convention does not affect the interpretation of + the \n or \r escape sequences, nor does it affect what \R matches, which is controlled in a similar way, but by separate options. MULTITHREADING - The PCRE functions can be used in multi-threading applications, with + The PCRE functions can be used in multi-threading applications, with the proviso that the memory management functions pointed to by pcre_malloc, pcre_free, pcre_stack_malloc, and pcre_stack_free, and the - callout and stack-checking functions pointed to by pcre_callout and + callout and stack-checking functions pointed to by pcre_callout and pcre_stack_guard, are shared by all threads. - The compiled form of a regular expression is not altered during match- + The compiled form of a regular expression is not altered during match- ing, so the same compiled pattern can safely be used by several threads at once. - If the just-in-time optimization feature is being used, it needs sepa- - rate memory stack areas for each thread. See the pcrejit documentation + If the just-in-time optimization feature is being used, it needs sepa- + rate memory stack areas for each thread. See the pcrejit documentation for more details. SAVING PRECOMPILED PATTERNS FOR LATER USE The compiled form of a regular expression can be saved and re-used at a - later time, possibly by a different program, and even on a host other - than the one on which it was compiled. Details are given in the - pcreprecompile documentation, which includes a description of the - pcre_pattern_to_host_byte_order() function. However, compiling a regu- - lar expression with one version of PCRE for use with a different ver- + later time, possibly by a different program, and even on a host other + than the one on which it was compiled. Details are given in the + pcreprecompile documentation, which includes a description of the + pcre_pattern_to_host_byte_order() function. However, compiling a regu- + lar expression with one version of PCRE for use with a different ver- sion is not guaranteed to work and may cause crashes. @@ -1899,45 +1898,45 @@ CHECKING BUILD-TIME OPTIONS int pcre_config(int what, void *where); - The function pcre_config() makes it possible for a PCRE client to dis- + The function pcre_config() makes it possible for a PCRE client to dis- cover which optional features have been compiled into the PCRE library. - The pcrebuild documentation has more details about these optional fea- + The pcrebuild documentation has more details about these optional fea- tures. - The first argument for pcre_config() is an integer, specifying which + The first argument for pcre_config() is an integer, specifying which information is required; the second argument is a pointer to a variable - into which the information is placed. The returned value is zero on - success, or the negative error code PCRE_ERROR_BADOPTION if the value - in the first argument is not recognized. The following information is + into which the information is placed. The returned value is zero on + success, or the negative error code PCRE_ERROR_BADOPTION if the value + in the first argument is not recognized. The following information is available: PCRE_CONFIG_UTF8 - The output is an integer that is set to one if UTF-8 support is avail- - able; otherwise it is set to zero. This value should normally be given + The output is an integer that is set to one if UTF-8 support is avail- + able; otherwise it is set to zero. This value should normally be given to the 8-bit version of this function, pcre_config(). If it is given to - the 16-bit or 32-bit version of this function, the result is + the 16-bit or 32-bit version of this function, the result is PCRE_ERROR_BADOPTION. PCRE_CONFIG_UTF16 The output is an integer that is set to one if UTF-16 support is avail- - able; otherwise it is set to zero. This value should normally be given + able; otherwise it is set to zero. This value should normally be given to the 16-bit version of this function, pcre16_config(). If it is given - to the 8-bit or 32-bit version of this function, the result is + to the 8-bit or 32-bit version of this function, the result is PCRE_ERROR_BADOPTION. PCRE_CONFIG_UTF32 The output is an integer that is set to one if UTF-32 support is avail- - able; otherwise it is set to zero. This value should normally be given + able; otherwise it is set to zero. This value should normally be given to the 32-bit version of this function, pcre32_config(). If it is given - to the 8-bit or 16-bit version of this function, the result is + to the 8-bit or 16-bit version of this function, the result is PCRE_ERROR_BADOPTION. PCRE_CONFIG_UNICODE_PROPERTIES - The output is an integer that is set to one if support for Unicode + The output is an integer that is set to one if support for Unicode character properties is available; otherwise it is set to zero. PCRE_CONFIG_JIT @@ -1947,80 +1946,80 @@ CHECKING BUILD-TIME OPTIONS PCRE_CONFIG_JITTARGET - The output is a pointer to a zero-terminated "const char *" string. If + The output is a pointer to a zero-terminated "const char *" string. If JIT support is available, the string contains the name of the architec- - ture for which the JIT compiler is configured, for example "x86 32bit - (little endian + unaligned)". If JIT support is not available, the + ture for which the JIT compiler is configured, for example "x86 32bit + (little endian + unaligned)". If JIT support is not available, the result is NULL. PCRE_CONFIG_NEWLINE - The output is an integer whose value specifies the default character - sequence that is recognized as meaning "newline". The values that are + The output is an integer whose value specifies the default character + sequence that is recognized as meaning "newline". The values that are supported in ASCII/Unicode environments are: 10 for LF, 13 for CR, 3338 - for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR, - ANYCRLF, and ANY yield the same values. However, the value for LF is - normally 21, though some EBCDIC environments use 37. The corresponding - values for CRLF are 3349 and 3365. The default should normally corre- + for CRLF, -2 for ANYCRLF, and -1 for ANY. In EBCDIC environments, CR, + ANYCRLF, and ANY yield the same values. However, the value for LF is + normally 21, though some EBCDIC environments use 37. The corresponding + values for CRLF are 3349 and 3365. The default should normally corre- spond to the standard sequence for your operating system. PCRE_CONFIG_BSR The output is an integer whose value indicates what character sequences - the \R escape sequence matches by default. A value of 0 means that \R - matches any Unicode line ending sequence; a value of 1 means that \R + the \R escape sequence matches by default. A value of 0 means that \R + matches any Unicode line ending sequence; a value of 1 means that \R matches only CR, LF, or CRLF. The default can be overridden when a pat- tern is compiled or matched. PCRE_CONFIG_LINK_SIZE - The output is an integer that contains the number of bytes used for + The output is an integer that contains the number of bytes used for internal linkage in compiled regular expressions. For the 8-bit library, the value can be 2, 3, or 4. For the 16-bit library, the value - is either 2 or 4 and is still a number of bytes. For the 32-bit + is either 2 or 4 and is still a number of bytes. For the 32-bit library, the value is either 2 or 4 and is still a number of bytes. The default value of 2 is sufficient for all but the most massive patterns, - since it allows the compiled pattern to be up to 64K in size. Larger - values allow larger regular expressions to be compiled, at the expense + since it allows the compiled pattern to be up to 64K in size. Larger + values allow larger regular expressions to be compiled, at the expense of slower matching. PCRE_CONFIG_POSIX_MALLOC_THRESHOLD - The output is an integer that contains the threshold above which the - POSIX interface uses malloc() for output vectors. Further details are + The output is an integer that contains the threshold above which the + POSIX interface uses malloc() for output vectors. Further details are given in the pcreposix documentation. PCRE_CONFIG_PARENS_LIMIT The output is a long integer that gives the maximum depth of nesting of - parentheses (of any kind) in a pattern. This limit is imposed to cap + parentheses (of any kind) in a pattern. This limit is imposed to cap the amount of system stack used when a pattern is compiled. It is spec- - ified when PCRE is built; the default is 250. This limit does not take + ified when PCRE is built; the default is 250. This limit does not take into account the stack that may already be used by the calling applica- - tion. For finer control over compilation stack usage, you can set a + tion. For finer control over compilation stack usage, you can set a pointer to an external checking function in pcre_stack_guard. PCRE_CONFIG_MATCH_LIMIT - The output is a long integer that gives the default limit for the num- - ber of internal matching function calls in a pcre_exec() execution. + The output is a long integer that gives the default limit for the num- + ber of internal matching function calls in a pcre_exec() execution. Further details are given with pcre_exec() below. PCRE_CONFIG_MATCH_LIMIT_RECURSION The output is a long integer that gives the default limit for the depth - of recursion when calling the internal matching function in a - pcre_exec() execution. Further details are given with pcre_exec() + of recursion when calling the internal matching function in a + pcre_exec() execution. Further details are given with pcre_exec() below. PCRE_CONFIG_STACKRECURSE - The output is an integer that is set to one if internal recursion when + The output is an integer that is set to one if internal recursion when running pcre_exec() is implemented by recursive function calls that use - the stack to remember their state. This is the usual way that PCRE is + the stack to remember their state. This is the usual way that PCRE is compiled. The output is zero if PCRE was compiled to use blocks of data - on the heap instead of recursive function calls. In this case, - pcre_stack_malloc and pcre_stack_free are called to manage memory + on the heap instead of recursive function calls. In this case, + pcre_stack_malloc and pcre_stack_free are called to manage memory blocks on the heap, thus avoiding the use of the stack. @@ -2037,67 +2036,67 @@ COMPILING A PATTERN Either of the functions pcre_compile() or pcre_compile2() can be called to compile a pattern into an internal form. The only difference between - the two interfaces is that pcre_compile2() has an additional argument, - errorcodeptr, via which a numerical error code can be returned. To - avoid too much repetition, we refer just to pcre_compile() below, but + the two interfaces is that pcre_compile2() has an additional argument, + errorcodeptr, via which a numerical error code can be returned. To + avoid too much repetition, we refer just to pcre_compile() below, but the information applies equally to pcre_compile2(). The pattern is a C string terminated by a binary zero, and is passed in - the pattern argument. A pointer to a single block of memory that is - obtained via pcre_malloc is returned. This contains the compiled code + the pattern argument. A pointer to a single block of memory that is + obtained via pcre_malloc is returned. This contains the compiled code and related data. The pcre type is defined for the returned block; this is a typedef for a structure whose contents are not externally defined. It is up to the caller to free the memory (via pcre_free) when it is no longer required. - Although the compiled code of a PCRE regex is relocatable, that is, it + Although the compiled code of a PCRE regex is relocatable, that is, it does not depend on memory location, the complete pcre data block is not - fully relocatable, because it may contain a copy of the tableptr argu- + fully relocatable, because it may contain a copy of the tableptr argu- ment, which is an address (see below). The options argument contains various bit settings that affect the com- - pilation. It should be zero if no options are required. The available - options are described below. Some of them (in particular, those that - are compatible with Perl, but some others as well) can also be set and - unset from within the pattern (see the detailed description in the - pcrepattern documentation). For those options that can be different in - different parts of the pattern, the contents of the options argument + pilation. It should be zero if no options are required. The available + options are described below. Some of them (in particular, those that + are compatible with Perl, but some others as well) can also be set and + unset from within the pattern (see the detailed description in the + pcrepattern documentation). For those options that can be different in + different parts of the pattern, the contents of the options argument specifies their settings at the start of compilation and execution. The - PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and - PCRE_NO_START_OPTIMIZE options can be set at the time of matching as + PCRE_ANCHORED, PCRE_BSR_xxx, PCRE_NEWLINE_xxx, PCRE_NO_UTF8_CHECK, and + PCRE_NO_START_OPTIMIZE options can be set at the time of matching as well as at compile time. If errptr is NULL, pcre_compile() returns NULL immediately. Otherwise, - if compilation of a pattern fails, pcre_compile() returns NULL, and + if compilation of a pattern fails, pcre_compile() returns NULL, and sets the variable pointed to by errptr to point to a textual error mes- sage. This is a static string that is part of the library. You must not - try to free it. Normally, the offset from the start of the pattern to + try to free it. Normally, the offset from the start of the pattern to the data unit that was being processed when the error was discovered is - placed in the variable pointed to by erroffset, which must not be NULL - (if it is, an immediate error is given). However, for an invalid UTF-8 - or UTF-16 string, the offset is that of the first data unit of the + placed in the variable pointed to by erroffset, which must not be NULL + (if it is, an immediate error is given). However, for an invalid UTF-8 + or UTF-16 string, the offset is that of the first data unit of the failing character. - Some errors are not detected until the whole pattern has been scanned; - in these cases, the offset passed back is the length of the pattern. - Note that the offset is in data units, not characters, even in a UTF + Some errors are not detected until the whole pattern has been scanned; + in these cases, the offset passed back is the length of the pattern. + Note that the offset is in data units, not characters, even in a UTF mode. It may sometimes point into the middle of a UTF-8 or UTF-16 char- acter. - If pcre_compile2() is used instead of pcre_compile(), and the error- - codeptr argument is not NULL, a non-zero error code number is returned - via this argument in the event of an error. This is in addition to the + If pcre_compile2() is used instead of pcre_compile(), and the error- + codeptr argument is not NULL, a non-zero error code number is returned + via this argument in the event of an error. This is in addition to the textual error message. Error codes and messages are listed below. - If the final argument, tableptr, is NULL, PCRE uses a default set of - character tables that are built when PCRE is compiled, using the - default C locale. Otherwise, tableptr must be an address that is the - result of a call to pcre_maketables(). This value is stored with the - compiled pattern, and used again by pcre_exec() and pcre_dfa_exec() - when the pattern is matched. For more discussion, see the section on + If the final argument, tableptr, is NULL, PCRE uses a default set of + character tables that are built when PCRE is compiled, using the + default C locale. Otherwise, tableptr must be an address that is the + result of a call to pcre_maketables(). This value is stored with the + compiled pattern, and used again by pcre_exec() and pcre_dfa_exec() + when the pattern is matched. For more discussion, see the section on locale support below. - This code fragment shows a typical straightforward call to pcre_com- + This code fragment shows a typical straightforward call to pcre_com- pile(): pcre *re; @@ -2110,181 +2109,181 @@ COMPILING A PATTERN &erroffset, /* for error offset */ NULL); /* use default character tables */ - The following names for option bits are defined in the pcre.h header + The following names for option bits are defined in the pcre.h header file: PCRE_ANCHORED If this bit is set, the pattern is forced to be "anchored", that is, it - is constrained to match only at the first matching point in the string - that is being searched (the "subject string"). This effect can also be - achieved by appropriate constructs in the pattern itself, which is the + is constrained to match only at the first matching point in the string + that is being searched (the "subject string"). This effect can also be + achieved by appropriate constructs in the pattern itself, which is the only way to do it in Perl. PCRE_AUTO_CALLOUT If this bit is set, pcre_compile() automatically inserts callout items, - all with number 255, before each pattern item. For discussion of the + all with number 255, before each pattern item. For discussion of the callout facility, see the pcrecallout documentation. PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE These options (which are mutually exclusive) control what the \R escape - sequence matches. The choice is either to match only CR, LF, or CRLF, + sequence matches. The choice is either to match only CR, LF, or CRLF, or to match any Unicode newline sequence. The default is specified when PCRE is built. It can be overridden from within the pattern, or by set- ting an option when a compiled pattern is matched. PCRE_CASELESS - If this bit is set, letters in the pattern match both upper and lower - case letters. It is equivalent to Perl's /i option, and it can be - changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE - always understands the concept of case for characters whose values are - less than 128, so caseless matching is always possible. For characters - with higher values, the concept of case is supported if PCRE is com- - piled with Unicode property support, but not otherwise. If you want to - use caseless matching for characters 128 and above, you must ensure - that PCRE is compiled with Unicode property support as well as with + If this bit is set, letters in the pattern match both upper and lower + case letters. It is equivalent to Perl's /i option, and it can be + changed within a pattern by a (?i) option setting. In UTF-8 mode, PCRE + always understands the concept of case for characters whose values are + less than 128, so caseless matching is always possible. For characters + with higher values, the concept of case is supported if PCRE is com- + piled with Unicode property support, but not otherwise. If you want to + use caseless matching for characters 128 and above, you must ensure + that PCRE is compiled with Unicode property support as well as with UTF-8 support. PCRE_DOLLAR_ENDONLY - If this bit is set, a dollar metacharacter in the pattern matches only - at the end of the subject string. Without this option, a dollar also - matches immediately before a newline at the end of the string (but not - before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored - if PCRE_MULTILINE is set. There is no equivalent to this option in + If this bit is set, a dollar metacharacter in the pattern matches only + at the end of the subject string. Without this option, a dollar also + matches immediately before a newline at the end of the string (but not + before any other newlines). The PCRE_DOLLAR_ENDONLY option is ignored + if PCRE_MULTILINE is set. There is no equivalent to this option in Perl, and no way to set it within a pattern. PCRE_DOTALL - If this bit is set, a dot metacharacter in the pattern matches a char- + If this bit is set, a dot metacharacter in the pattern matches a char- acter of any value, including one that indicates a newline. However, it - only ever matches one character, even if newlines are coded as CRLF. - Without this option, a dot does not match when the current position is + only ever matches one character, even if newlines are coded as CRLF. + Without this option, a dot does not match when the current position is at a newline. This option is equivalent to Perl's /s option, and it can - be changed within a pattern by a (?s) option setting. A negative class + be changed within a pattern by a (?s) option setting. A negative class such as [^a] always matches newline characters, independent of the set- ting of this option. PCRE_DUPNAMES - If this bit is set, names used to identify capturing subpatterns need + If this bit is set, names used to identify capturing subpatterns need not be unique. This can be helpful for certain types of pattern when it - is known that only one instance of the named subpattern can ever be - matched. There are more details of named subpatterns below; see also + is known that only one instance of the named subpattern can ever be + matched. There are more details of named subpatterns below; see also the pcrepattern documentation. PCRE_EXTENDED - If this bit is set, most white space characters in the pattern are - totally ignored except when escaped or inside a character class. How- - ever, white space is not allowed within sequences such as (?> that - introduce various parenthesized subpatterns, nor within a numerical - quantifier such as {1,3}. However, ignorable white space is permitted + If this bit is set, most white space characters in the pattern are + totally ignored except when escaped or inside a character class. How- + ever, white space is not allowed within sequences such as (?> that + introduce various parenthesized subpatterns, nor within a numerical + quantifier such as {1,3}. However, ignorable white space is permitted between an item and a following quantifier and between a quantifier and a following + that indicates possessiveness. White space did not used to include the VT character (code 11), because Perl did not treat this character as white space. However, Perl changed - at release 5.18, so PCRE followed at release 8.34, and VT is now + at release 5.18, so PCRE followed at release 8.34, and VT is now treated as white space. - PCRE_EXTENDED also causes characters between an unescaped # outside a - character class and the next newline, inclusive, to be ignored. - PCRE_EXTENDED is equivalent to Perl's /x option, and it can be changed + PCRE_EXTENDED also causes characters between an unescaped # outside a + character class and the next newline, inclusive, to be ignored. + PCRE_EXTENDED is equivalent to Perl's /x option, and it can be changed within a pattern by a (?x) option setting. - Which characters are interpreted as newlines is controlled by the - options passed to pcre_compile() or by a special sequence at the start - of the pattern, as described in the section entitled "Newline conven- + Which characters are interpreted as newlines is controlled by the + options passed to pcre_compile() or by a special sequence at the start + of the pattern, as described in the section entitled "Newline conven- tions" in the pcrepattern documentation. Note that the end of this type - of comment is a literal newline sequence in the pattern; escape + of comment is a literal newline sequence in the pattern; escape sequences that happen to represent a newline do not count. - This option makes it possible to include comments inside complicated - patterns. Note, however, that this applies only to data characters. - White space characters may never appear within special character + This option makes it possible to include comments inside complicated + patterns. Note, however, that this applies only to data characters. + White space characters may never appear within special character sequences in a pattern, for example within the sequence (?( that intro- duces a conditional subpattern. PCRE_EXTRA - This option was invented in order to turn on additional functionality - of PCRE that is incompatible with Perl, but it is currently of very - little use. When set, any backslash in a pattern that is followed by a - letter that has no special meaning causes an error, thus reserving - these combinations for future expansion. By default, as in Perl, a - backslash followed by a letter with no special meaning is treated as a + This option was invented in order to turn on additional functionality + of PCRE that is incompatible with Perl, but it is currently of very + little use. When set, any backslash in a pattern that is followed by a + letter that has no special meaning causes an error, thus reserving + these combinations for future expansion. By default, as in Perl, a + backslash followed by a letter with no special meaning is treated as a literal. (Perl can, however, be persuaded to give an error for this, by - running it with the -w option.) There are at present no other features - controlled by this option. It can also be set by a (?X) option setting + running it with the -w option.) There are at present no other features + controlled by this option. It can also be set by a (?X) option setting within a pattern. PCRE_FIRSTLINE - If this option is set, an unanchored pattern is required to match - before or at the first newline in the subject string, though the + If this option is set, an unanchored pattern is required to match + before or at the first newline in the subject string, though the matched text may continue over the newline. PCRE_JAVASCRIPT_COMPAT If this option is set, PCRE's behaviour is changed in some ways so that - it is compatible with JavaScript rather than Perl. The changes are as + it is compatible with JavaScript rather than Perl. The changes are as follows: - (1) A lone closing square bracket in a pattern causes a compile-time - error, because this is illegal in JavaScript (by default it is treated + (1) A lone closing square bracket in a pattern causes a compile-time + error, because this is illegal in JavaScript (by default it is treated as a data character). Thus, the pattern AB]CD becomes illegal when this option is set. - (2) At run time, a back reference to an unset subpattern group matches - an empty string (by default this causes the current matching alterna- - tive to fail). A pattern such as (\1)(a) succeeds when this option is - set (assuming it can find an "a" in the subject), whereas it fails by + (2) At run time, a back reference to an unset subpattern group matches + an empty string (by default this causes the current matching alterna- + tive to fail). A pattern such as (\1)(a) succeeds when this option is + set (assuming it can find an "a" in the subject), whereas it fails by default, for Perl compatibility. (3) \U matches an upper case "U" character; by default \U causes a com- pile time error (Perl uses \U to upper case subsequent characters). (4) \u matches a lower case "u" character unless it is followed by four - hexadecimal digits, in which case the hexadecimal number defines the - code point to match. By default, \u causes a compile time error (Perl + hexadecimal digits, in which case the hexadecimal number defines the + code point to match. By default, \u causes a compile time error (Perl uses it to upper case the following character). - (5) \x matches a lower case "x" character unless it is followed by two - hexadecimal digits, in which case the hexadecimal number defines the - code point to match. By default, as in Perl, a hexadecimal number is + (5) \x matches a lower case "x" character unless it is followed by two + hexadecimal digits, in which case the hexadecimal number defines the + code point to match. By default, as in Perl, a hexadecimal number is always expected after \x, but it may have zero, one, or two digits (so, for example, \xz matches a binary zero character followed by z). PCRE_MULTILINE - By default, for the purposes of matching "start of line" and "end of + By default, for the purposes of matching "start of line" and "end of line", PCRE treats the subject string as consisting of a single line of - characters, even if it actually contains newlines. The "start of line" + characters, even if it actually contains newlines. The "start of line" metacharacter (^) matches only at the start of the string, and the "end - of line" metacharacter ($) matches only at the end of the string, or - before a terminating newline (except when PCRE_DOLLAR_ENDONLY is set). - Note, however, that unless PCRE_DOTALL is set, the "any character" - metacharacter (.) does not match at a newline. This behaviour (for ^, + of line" metacharacter ($) matches only at the end of the string, or + before a terminating newline (except when PCRE_DOLLAR_ENDONLY is set). + Note, however, that unless PCRE_DOTALL is set, the "any character" + metacharacter (.) does not match at a newline. This behaviour (for ^, $, and dot) is the same as Perl. - When PCRE_MULTILINE it is set, the "start of line" and "end of line" - constructs match immediately following or immediately before internal - newlines in the subject string, respectively, as well as at the very - start and end. This is equivalent to Perl's /m option, and it can be + When PCRE_MULTILINE it is set, the "start of line" and "end of line" + constructs match immediately following or immediately before internal + newlines in the subject string, respectively, as well as at the very + start and end. This is equivalent to Perl's /m option, and it can be changed within a pattern by a (?m) option setting. If there are no new- - lines in a subject string, or no occurrences of ^ or $ in a pattern, + lines in a subject string, or no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no effect. PCRE_NEVER_UTF This option locks out interpretation of the pattern as UTF-8 (or UTF-16 - or UTF-32 in the 16-bit and 32-bit libraries). In particular, it pre- - vents the creator of the pattern from switching to UTF interpretation + or UTF-32 in the 16-bit and 32-bit libraries). In particular, it pre- + vents the creator of the pattern from switching to UTF interpretation by starting the pattern with (*UTF). This may be useful in applications that process patterns from external sources. The combination of PCRE_UTF8 and PCRE_NEVER_UTF also causes an error. @@ -2295,41 +2294,41 @@ COMPILING A PATTERN PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY - These options override the default newline definition that was chosen - when PCRE was built. Setting the first or the second specifies that a - newline is indicated by a single character (CR or LF, respectively). - Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the - two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies + These options override the default newline definition that was chosen + when PCRE was built. Setting the first or the second specifies that a + newline is indicated by a single character (CR or LF, respectively). + Setting PCRE_NEWLINE_CRLF specifies that a newline is indicated by the + two-character CRLF sequence. Setting PCRE_NEWLINE_ANYCRLF specifies that any of the three preceding sequences should be recognized. Setting - PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be + PCRE_NEWLINE_ANY specifies that any Unicode newline sequence should be recognized. - In an ASCII/Unicode environment, the Unicode newline sequences are the - three just mentioned, plus the single characters VT (vertical tab, + In an ASCII/Unicode environment, the Unicode newline sequences are the + three just mentioned, plus the single characters VT (vertical tab, U+000B), FF (form feed, U+000C), NEL (next line, U+0085), LS (line sep- - arator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit + arator, U+2028), and PS (paragraph separator, U+2029). For the 8-bit library, the last two are recognized only in UTF-8 mode. - When PCRE is compiled to run in an EBCDIC (mainframe) environment, the + When PCRE is compiled to run in an EBCDIC (mainframe) environment, the code for CR is 0x0d, the same as ASCII. However, the character code for - LF is normally 0x15, though in some EBCDIC environments 0x25 is used. - Whichever of these is not LF is made to correspond to Unicode's NEL - character. EBCDIC codes are all less than 256. For more details, see + LF is normally 0x15, though in some EBCDIC environments 0x25 is used. + Whichever of these is not LF is made to correspond to Unicode's NEL + character. EBCDIC codes are all less than 256. For more details, see the pcrebuild documentation. - The newline setting in the options word uses three bits that are + The newline setting in the options word uses three bits that are treated as a number, giving eight possibilities. Currently only six are - used (default plus the five values above). This means that if you set - more than one newline option, the combination may or may not be sensi- + used (default plus the five values above). This means that if you set + more than one newline option, the combination may or may not be sensi- ble. For example, PCRE_NEWLINE_CR with PCRE_NEWLINE_LF is equivalent to - PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and + PCRE_NEWLINE_CRLF, but other combinations may yield unused numbers and cause an error. - The only time that a line break in a pattern is specially recognized - when compiling is when PCRE_EXTENDED is set. CR and LF are white space - characters, and so are ignored in this mode. Also, an unescaped # out- - side a character class indicates a comment that lasts until after the - next line break sequence. In other circumstances, line break sequences + The only time that a line break in a pattern is specially recognized + when compiling is when PCRE_EXTENDED is set. CR and LF are white space + characters, and so are ignored in this mode. Also, an unescaped # out- + side a character class indicates a comment that lasts until after the + next line break sequence. In other circumstances, line break sequences in patterns are treated as literal data. The newline option that is set at compile time becomes the default that @@ -2338,79 +2337,79 @@ COMPILING A PATTERN PCRE_NO_AUTO_CAPTURE If this option is set, it disables the use of numbered capturing paren- - theses in the pattern. Any opening parenthesis that is not followed by - ? behaves as if it were followed by ?: but named parentheses can still - be used for capturing (and they acquire numbers in the usual way). + theses in the pattern. Any opening parenthesis that is not followed by + ? behaves as if it were followed by ?: but named parentheses can still + be used for capturing (and they acquire numbers in the usual way). There is no equivalent of this option in Perl. PCRE_NO_AUTO_POSSESS - If this option is set, it disables "auto-possessification". This is an - optimization that, for example, turns a+b into a++b in order to avoid - backtracks into a+ that can never be successful. However, if callouts - are in use, auto-possessification means that some of them are never + If this option is set, it disables "auto-possessification". This is an + optimization that, for example, turns a+b into a++b in order to avoid + backtracks into a+ that can never be successful. However, if callouts + are in use, auto-possessification means that some of them are never taken. You can set this option if you want the matching functions to do - a full unoptimized search and run all the callouts, but it is mainly + a full unoptimized search and run all the callouts, but it is mainly provided for testing purposes. PCRE_NO_START_OPTIMIZE - This is an option that acts at matching time; that is, it is really an - option for pcre_exec() or pcre_dfa_exec(). If it is set at compile - time, it is remembered with the compiled pattern and assumed at match- - ing time. This is necessary if you want to use JIT execution, because - the JIT compiler needs to know whether or not this option is set. For + This is an option that acts at matching time; that is, it is really an + option for pcre_exec() or pcre_dfa_exec(). If it is set at compile + time, it is remembered with the compiled pattern and assumed at match- + ing time. This is necessary if you want to use JIT execution, because + the JIT compiler needs to know whether or not this option is set. For details see the discussion of PCRE_NO_START_OPTIMIZE below. PCRE_UCP - This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, - \w, and some of the POSIX character classes. By default, only ASCII - characters are recognized, but if PCRE_UCP is set, Unicode properties - are used instead to classify characters. More details are given in the - section on generic character types in the pcrepattern page. If you set - PCRE_UCP, matching one of the items it affects takes much longer. The - option is available only if PCRE has been compiled with Unicode prop- + This option changes the way PCRE processes \B, \b, \D, \d, \S, \s, \W, + \w, and some of the POSIX character classes. By default, only ASCII + characters are recognized, but if PCRE_UCP is set, Unicode properties + are used instead to classify characters. More details are given in the + section on generic character types in the pcrepattern page. If you set + PCRE_UCP, matching one of the items it affects takes much longer. The + option is available only if PCRE has been compiled with Unicode prop- erty support. PCRE_UNGREEDY - This option inverts the "greediness" of the quantifiers so that they - are not greedy by default, but become greedy if followed by "?". It is - not compatible with Perl. It can also be set by a (?U) option setting + This option inverts the "greediness" of the quantifiers so that they + are not greedy by default, but become greedy if followed by "?". It is + not compatible with Perl. It can also be set by a (?U) option setting within the pattern. PCRE_UTF8 - This option causes PCRE to regard both the pattern and the subject as + This option causes PCRE to regard both the pattern and the subject as strings of UTF-8 characters instead of single-byte strings. However, it - is available only when PCRE is built to include UTF support. If not, - the use of this option provokes an error. Details of how this option + is available only when PCRE is built to include UTF support. If not, + the use of this option provokes an error. Details of how this option changes the behaviour of PCRE are given in the pcreunicode page. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set, the validity of the pattern as a UTF-8 string is - automatically checked. There is a discussion about the validity of - UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is - found, pcre_compile() returns an error. If you already know that your - pattern is valid, and you want to skip this check for performance rea- - sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the + automatically checked. There is a discussion about the validity of + UTF-8 strings in the pcreunicode page. If an invalid UTF-8 sequence is + found, pcre_compile() returns an error. If you already know that your + pattern is valid, and you want to skip this check for performance rea- + sons, you can set the PCRE_NO_UTF8_CHECK option. When it is set, the effect of passing an invalid UTF-8 string as a pattern is undefined. It may cause your program to crash or loop. Note that this option can also - be passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity - checking of subject strings only. If the same string is being matched - many times, the option can be safely set for the second and subsequent + be passed to pcre_exec() and pcre_dfa_exec(), to suppress the validity + checking of subject strings only. If the same string is being matched + many times, the option can be safely set for the second and subsequent matchings to improve performance. COMPILATION ERROR CODES - The following table lists the error codes than may be returned by - pcre_compile2(), along with the error messages that may be returned by - both compiling functions. Note that error messages are always 8-bit - ASCII strings, even in 16-bit or 32-bit mode. As PCRE has developed, - some error codes have fallen out of use. To avoid confusion, they have + The following table lists the error codes than may be returned by + pcre_compile2(), along with the error messages that may be returned by + both compiling functions. Note that error messages are always 8-bit + ASCII strings, even in 16-bit or 32-bit mode. As PCRE has developed, + some error codes have fallen out of use. To avoid confusion, they have not been re-used. 0 no error @@ -2504,7 +2503,7 @@ COMPILATION ERROR CODES 84 group name must start with a non-digit 85 parentheses are too deeply nested (stack check) - The numbers 32 and 10000 in errors 48 and 49 are defaults; different + The numbers 32 and 10000 in errors 48 and 49 are defaults; different values may be used if the limits were changed when PCRE was built. @@ -2513,64 +2512,64 @@ STUDYING A PATTERN pcre_extra *pcre_study(const pcre *code, int options, const char **errptr); - If a compiled pattern is going to be used several times, it is worth + If a compiled pattern is going to be used several times, it is worth spending more time analyzing it in order to speed up the time taken for - matching. The function pcre_study() takes a pointer to a compiled pat- + matching. The function pcre_study() takes a pointer to a compiled pat- tern as its first argument. If studying the pattern produces additional - information that will help speed up matching, pcre_study() returns a - pointer to a pcre_extra block, in which the study_data field points to + information that will help speed up matching, pcre_study() returns a + pointer to a pcre_extra block, in which the study_data field points to the results of the study. The returned value from pcre_study() can be passed directly to - pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con- - tains other fields that can be set by the caller before the block is + pcre_exec() or pcre_dfa_exec(). However, a pcre_extra block also con- + tains other fields that can be set by the caller before the block is passed; these are described below in the section on matching a pattern. - If studying the pattern does not produce any useful information, - pcre_study() returns NULL by default. In that circumstance, if the + If studying the pattern does not produce any useful information, + pcre_study() returns NULL by default. In that circumstance, if the calling program wants to pass any of the other fields to pcre_exec() or - pcre_dfa_exec(), it must set up its own pcre_extra block. However, if - pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it + pcre_dfa_exec(), it must set up its own pcre_extra block. However, if + pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it returns a pcre_extra block even if studying did not find any additional - information. It may still return NULL, however, if an error occurs in + information. It may still return NULL, however, if an error occurs in pcre_study(). - The second argument of pcre_study() contains option bits. There are + The second argument of pcre_study() contains option bits. There are three further options in addition to PCRE_STUDY_EXTRA_NEEDED: PCRE_STUDY_JIT_COMPILE PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE - If any of these are set, and the just-in-time compiler is available, - the pattern is further compiled into machine code that executes much - faster than the pcre_exec() interpretive matching function. If the - just-in-time compiler is not available, these options are ignored. All + If any of these are set, and the just-in-time compiler is available, + the pattern is further compiled into machine code that executes much + faster than the pcre_exec() interpretive matching function. If the + just-in-time compiler is not available, these options are ignored. All undefined bits in the options argument must be zero. - JIT compilation is a heavyweight optimization. It can take some time - for patterns to be analyzed, and for one-off matches and simple pat- - terns the benefit of faster execution might be offset by a much slower + JIT compilation is a heavyweight optimization. It can take some time + for patterns to be analyzed, and for one-off matches and simple pat- + terns the benefit of faster execution might be offset by a much slower study time. Not all patterns can be optimized by the JIT compiler. For - those that cannot be handled, matching automatically falls back to the - pcre_exec() interpreter. For more details, see the pcrejit documenta- + those that cannot be handled, matching automatically falls back to the + pcre_exec() interpreter. For more details, see the pcrejit documenta- tion. - The third argument for pcre_study() is a pointer for an error message. - If studying succeeds (even if no data is returned), the variable it - points to is set to NULL. Otherwise it is set to point to a textual + The third argument for pcre_study() is a pointer for an error message. + If studying succeeds (even if no data is returned), the variable it + points to is set to NULL. Otherwise it is set to point to a textual error message. This is a static string that is part of the library. You - must not try to free it. You should test the error pointer for NULL + must not try to free it. You should test the error pointer for NULL after calling pcre_study(), to be sure that it has run successfully. - When you are finished with a pattern, you can free the memory used for + When you are finished with a pattern, you can free the memory used for the study data by calling pcre_free_study(). This function was added to - the API for release 8.20. For earlier versions, the memory could be - freed with pcre_free(), just like the pattern itself. This will still - work in cases where JIT optimization is not used, but it is advisable + the API for release 8.20. For earlier versions, the memory could be + freed with pcre_free(), just like the pattern itself. This will still + work in cases where JIT optimization is not used, but it is advisable to change to the new function when convenient. - This is a typical way in which pcre_study() is used (except that in a + This is a typical way in which pcre_study() is used (except that in a real application there should be tests for errors): int rc; @@ -2590,29 +2589,29 @@ STUDYING A PATTERN Studying a pattern does two things: first, a lower bound for the length of subject string that is needed to match the pattern is computed. This does not mean that there are any strings of that length that match, but - it does guarantee that no shorter strings match. The value is used to + it does guarantee that no shorter strings match. The value is used to avoid wasting time by trying to match strings that are shorter than the - lower bound. You can find out the value in a calling program via the + lower bound. You can find out the value in a calling program via the pcre_fullinfo() function. Studying a pattern is also useful for non-anchored patterns that do not - have a single fixed starting character. A bitmap of possible starting - bytes is created. This speeds up finding a position in the subject at + have a single fixed starting character. A bitmap of possible starting + bytes is created. This speeds up finding a position in the subject at which to start matching. (In 16-bit mode, the bitmap is used for 16-bit - values less than 256. In 32-bit mode, the bitmap is used for 32-bit + values less than 256. In 32-bit mode, the bitmap is used for 32-bit values less than 256.) - These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), - and the information is also used by the JIT compiler. The optimiza- - tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option. - You might want to do this if your pattern contains callouts or (*MARK) - and you want to make use of these facilities in cases where matching + These two optimizations apply to both pcre_exec() and pcre_dfa_exec(), + and the information is also used by the JIT compiler. The optimiza- + tions can be disabled by setting the PCRE_NO_START_OPTIMIZE option. + You might want to do this if your pattern contains callouts or (*MARK) + and you want to make use of these facilities in cases where matching fails. - PCRE_NO_START_OPTIMIZE can be specified at either compile time or exe- - cution time. However, if PCRE_NO_START_OPTIMIZE is passed to + PCRE_NO_START_OPTIMIZE can be specified at either compile time or exe- + cution time. However, if PCRE_NO_START_OPTIMIZE is passed to pcre_exec(), (that is, after any JIT compilation has happened) JIT exe- - cution is disabled. For JIT execution to work with PCRE_NO_START_OPTI- + cution is disabled. For JIT execution to work with PCRE_NO_START_OPTI- MIZE, the option must be set at compile time. There is a longer discussion of PCRE_NO_START_OPTIMIZE below. @@ -2620,65 +2619,65 @@ STUDYING A PATTERN LOCALE SUPPORT - PCRE handles caseless matching, and determines whether characters are - letters, digits, or whatever, by reference to a set of tables, indexed - by character code point. When running in UTF-8 mode, or in the 16- or + PCRE handles caseless matching, and determines whether characters are + letters, digits, or whatever, by reference to a set of tables, indexed + by character code point. When running in UTF-8 mode, or in the 16- or 32-bit libraries, this applies only to characters with code points less - than 256. By default, higher-valued code points never match escapes - such as \w or \d. However, if PCRE is built with Unicode property sup- - port, all characters can be tested with \p and \P, or, alternatively, - the PCRE_UCP option can be set when a pattern is compiled; this causes - \w and friends to use Unicode property support instead of the built-in + than 256. By default, higher-valued code points never match escapes + such as \w or \d. However, if PCRE is built with Unicode property sup- + port, all characters can be tested with \p and \P, or, alternatively, + the PCRE_UCP option can be set when a pattern is compiled; this causes + \w and friends to use Unicode property support instead of the built-in tables. - The use of locales with Unicode is discouraged. If you are handling - characters with code points greater than 128, you should either use + The use of locales with Unicode is discouraged. If you are handling + characters with code points greater than 128, you should either use Unicode support, or use locales, but not try to mix the two. - PCRE contains an internal set of tables that are used when the final - argument of pcre_compile() is NULL. These are sufficient for many + PCRE contains an internal set of tables that are used when the final + argument of pcre_compile() is NULL. These are sufficient for many applications. Normally, the internal tables recognize only ASCII char- acters. However, when PCRE is built, it is possible to cause the inter- nal tables to be rebuilt in the default "C" locale of the local system, which may cause them to be different. - The internal tables can always be overridden by tables supplied by the + The internal tables can always be overridden by tables supplied by the application that calls PCRE. These may be created in a different locale - from the default. As more and more applications change to using Uni- + from the default. As more and more applications change to using Uni- code, the need for this locale support is expected to die away. - External tables are built by calling the pcre_maketables() function, - which has no arguments, in the relevant locale. The result can then be - passed to pcre_compile() as often as necessary. For example, to build - and use tables that are appropriate for the French locale (where - accented characters with values greater than 128 are treated as let- + External tables are built by calling the pcre_maketables() function, + which has no arguments, in the relevant locale. The result can then be + passed to pcre_compile() as often as necessary. For example, to build + and use tables that are appropriate for the French locale (where + accented characters with values greater than 128 are treated as let- ters), the following code could be used: setlocale(LC_CTYPE, "fr_FR"); tables = pcre_maketables(); re = pcre_compile(..., tables); - The locale name "fr_FR" is used on Linux and other Unix-like systems; + The locale name "fr_FR" is used on Linux and other Unix-like systems; if you are using Windows, the name for the French locale is "french". - When pcre_maketables() runs, the tables are built in memory that is - obtained via pcre_malloc. It is the caller's responsibility to ensure - that the memory containing the tables remains available for as long as + When pcre_maketables() runs, the tables are built in memory that is + obtained via pcre_malloc. It is the caller's responsibility to ensure + that the memory containing the tables remains available for as long as it is needed. The pointer that is passed to pcre_compile() is saved with the compiled - pattern, and the same tables are used via this pointer by pcre_study() - and also by pcre_exec() and pcre_dfa_exec(). Thus, for any single pat- + pattern, and the same tables are used via this pointer by pcre_study() + and also by pcre_exec() and pcre_dfa_exec(). Thus, for any single pat- tern, compilation, studying and matching all happen in the same locale, but different patterns can be processed in different locales. - It is possible to pass a table pointer or NULL (indicating the use of + It is possible to pass a table pointer or NULL (indicating the use of the internal tables) to pcre_exec() or pcre_dfa_exec() (see the discus- sion below in the section on matching a pattern). This facility is pro- - vided for use with pre-compiled patterns that have been saved and - reloaded. Character tables are not saved with patterns, so if a non- + vided for use with pre-compiled patterns that have been saved and + reloaded. Character tables are not saved with patterns, so if a non- standard table was used at compile time, it must be provided again when - the reloaded pattern is matched. Attempting to use this facility to + the reloaded pattern is matched. Attempting to use this facility to match a pattern in a different locale from the one in which it was com- piled is likely to lead to anomalous (usually incorrect) results. @@ -2688,15 +2687,15 @@ INFORMATION ABOUT A PATTERN int pcre_fullinfo(const pcre *code, const pcre_extra *extra, int what, void *where); - The pcre_fullinfo() function returns information about a compiled pat- - tern. It replaces the pcre_info() function, which was removed from the + The pcre_fullinfo() function returns information about a compiled pat- + tern. It replaces the pcre_info() function, which was removed from the library at version 8.30, after more than 10 years of obsolescence. - The first argument for pcre_fullinfo() is a pointer to the compiled - pattern. The second argument is the result of pcre_study(), or NULL if - the pattern was not studied. The third argument specifies which piece - of information is required, and the fourth argument is a pointer to a - variable to receive the data. The yield of the function is zero for + The first argument for pcre_fullinfo() is a pointer to the compiled + pattern. The second argument is the result of pcre_study(), or NULL if + the pattern was not studied. The third argument specifies which piece + of information is required, and the fourth argument is a pointer to a + variable to receive the data. The yield of the function is zero for success, or one of the following negative numbers: PCRE_ERROR_NULL the argument code was NULL @@ -2707,10 +2706,10 @@ INFORMATION ABOUT A PATTERN PCRE_ERROR_BADOPTION the value of what was invalid PCRE_ERROR_UNSET the requested field is not set - The "magic number" is placed at the start of each compiled pattern as - an simple check against passing an arbitrary memory pointer. The endi- + The "magic number" is placed at the start of each compiled pattern as + an simple check against passing an arbitrary memory pointer. The endi- anness error can occur if a compiled pattern is saved and reloaded on a - different host. Here is a typical call of pcre_fullinfo(), to obtain + different host. Here is a typical call of pcre_fullinfo(), to obtain the length of the compiled pattern: int rc; @@ -2721,81 +2720,81 @@ INFORMATION ABOUT A PATTERN PCRE_INFO_SIZE, /* what is required */ &length); /* where to put the data */ - The possible values for the third argument are defined in pcre.h, and + The possible values for the third argument are defined in pcre.h, and are as follows: PCRE_INFO_BACKREFMAX - Return the number of the highest back reference in the pattern. The - fourth argument should point to an int variable. Zero is returned if + Return the number of the highest back reference in the pattern. The + fourth argument should point to an int variable. Zero is returned if there are no back references. PCRE_INFO_CAPTURECOUNT - Return the number of capturing subpatterns in the pattern. The fourth + Return the number of capturing subpatterns in the pattern. The fourth argument should point to an int variable. PCRE_INFO_DEFAULT_TABLES - Return a pointer to the internal default character tables within PCRE. - The fourth argument should point to an unsigned char * variable. This + Return a pointer to the internal default character tables within PCRE. + The fourth argument should point to an unsigned char * variable. This information call is provided for internal use by the pcre_study() func- - tion. External callers can cause PCRE to use its internal tables by + tion. External callers can cause PCRE to use its internal tables by passing a NULL table pointer. PCRE_INFO_FIRSTBYTE (deprecated) Return information about the first data unit of any matched string, for - a non-anchored pattern. The name of this option refers to the 8-bit - library, where data units are bytes. The fourth argument should point - to an int variable. Negative values are used for special cases. How- - ever, this means that when the 32-bit library is in non-UTF-32 mode, - the full 32-bit range of characters cannot be returned. For this rea- - son, this value is deprecated; use PCRE_INFO_FIRSTCHARACTERFLAGS and + a non-anchored pattern. The name of this option refers to the 8-bit + library, where data units are bytes. The fourth argument should point + to an int variable. Negative values are used for special cases. How- + ever, this means that when the 32-bit library is in non-UTF-32 mode, + the full 32-bit range of characters cannot be returned. For this rea- + son, this value is deprecated; use PCRE_INFO_FIRSTCHARACTERFLAGS and PCRE_INFO_FIRSTCHARACTER instead. - If there is a fixed first value, for example, the letter "c" from a - pattern such as (cat|cow|coyote), its value is returned. In the 8-bit - library, the value is always less than 256. In the 16-bit library the + If there is a fixed first value, for example, the letter "c" from a + pattern such as (cat|cow|coyote), its value is returned. In the 8-bit + library, the value is always less than 256. In the 16-bit library the value can be up to 0xffff. In the 32-bit library the value can be up to 0x10ffff. If there is no fixed first value, and if either - (a) the pattern was compiled with the PCRE_MULTILINE option, and every + (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set (if it were set, the pattern would be anchored), - -1 is returned, indicating that the pattern matches only at the start - of a subject string or after any newline within the string. Otherwise + -1 is returned, indicating that the pattern matches only at the start + of a subject string or after any newline within the string. Otherwise -2 is returned. For anchored patterns, -2 is returned. PCRE_INFO_FIRSTCHARACTER - Return the value of the first data unit (non-UTF character) of any - matched string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS - returns 1; otherwise return 0. The fourth argument should point to an + Return the value of the first data unit (non-UTF character) of any + matched string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS + returns 1; otherwise return 0. The fourth argument should point to an uint_t variable. - In the 8-bit library, the value is always less than 256. In the 16-bit - library the value can be up to 0xffff. In the 32-bit library in UTF-32 - mode the value can be up to 0x10ffff, and up to 0xffffffff when not + In the 8-bit library, the value is always less than 256. In the 16-bit + library the value can be up to 0xffff. In the 32-bit library in UTF-32 + mode the value can be up to 0x10ffff, and up to 0xffffffff when not using UTF-32 mode. PCRE_INFO_FIRSTCHARACTERFLAGS Return information about the first data unit of any matched string, for - a non-anchored pattern. The fourth argument should point to an int + a non-anchored pattern. The fourth argument should point to an int variable. - If there is a fixed first value, for example, the letter "c" from a - pattern such as (cat|cow|coyote), 1 is returned, and the character - value can be retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no + If there is a fixed first value, for example, the letter "c" from a + pattern such as (cat|cow|coyote), 1 is returned, and the character + value can be retrieved using PCRE_INFO_FIRSTCHARACTER. If there is no fixed first value, and if either - (a) the pattern was compiled with the PCRE_MULTILINE option, and every + (a) the pattern was compiled with the PCRE_MULTILINE option, and every branch starts with "^", or (b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not @@ -2807,139 +2806,139 @@ INFORMATION ABOUT A PATTERN PCRE_INFO_FIRSTTABLE - If the pattern was studied, and this resulted in the construction of a - 256-bit table indicating a fixed set of values for the first data unit - in any matching string, a pointer to the table is returned. Otherwise - NULL is returned. The fourth argument should point to an unsigned char + If the pattern was studied, and this resulted in the construction of a + 256-bit table indicating a fixed set of values for the first data unit + in any matching string, a pointer to the table is returned. Otherwise + NULL is returned. The fourth argument should point to an unsigned char * variable. PCRE_INFO_HASCRORLF - Return 1 if the pattern contains any explicit matches for CR or LF - characters, otherwise 0. The fourth argument should point to an int - variable. An explicit match is either a literal CR or LF character, or + Return 1 if the pattern contains any explicit matches for CR or LF + characters, otherwise 0. The fourth argument should point to an int + variable. An explicit match is either a literal CR or LF character, or \r or \n. PCRE_INFO_JCHANGED - Return 1 if the (?J) or (?-J) option setting is used in the pattern, - otherwise 0. The fourth argument should point to an int variable. (?J) + Return 1 if the (?J) or (?-J) option setting is used in the pattern, + otherwise 0. The fourth argument should point to an int variable. (?J) and (?-J) set and unset the local PCRE_DUPNAMES option, respectively. PCRE_INFO_JIT - Return 1 if the pattern was studied with one of the JIT options, and + Return 1 if the pattern was studied with one of the JIT options, and just-in-time compiling was successful. The fourth argument should point - to an int variable. A return value of 0 means that JIT support is not - available in this version of PCRE, or that the pattern was not studied - with a JIT option, or that the JIT compiler could not handle this par- - ticular pattern. See the pcrejit documentation for details of what can + to an int variable. A return value of 0 means that JIT support is not + available in this version of PCRE, or that the pattern was not studied + with a JIT option, or that the JIT compiler could not handle this par- + ticular pattern. See the pcrejit documentation for details of what can and cannot be handled. PCRE_INFO_JITSIZE - If the pattern was successfully studied with a JIT option, return the - size of the JIT compiled code, otherwise return zero. The fourth argu- + If the pattern was successfully studied with a JIT option, return the + size of the JIT compiled code, otherwise return zero. The fourth argu- ment should point to a size_t variable. PCRE_INFO_LASTLITERAL - Return the value of the rightmost literal data unit that must exist in - any matched string, other than at its start, if such a value has been + Return the value of the rightmost literal data unit that must exist in + any matched string, other than at its start, if such a value has been recorded. The fourth argument should point to an int variable. If there is no such value, -1 is returned. For anchored patterns, a last literal - value is recorded only if it follows something of variable length. For + value is recorded only if it follows something of variable length. For example, for the pattern /^a\d+z\d+/ the returned value is "z", but for /^a\dz\d/ the returned value is -1. - Since for the 32-bit library using the non-UTF-32 mode, this function - is unable to return the full 32-bit range of characters, this value is + Since for the 32-bit library using the non-UTF-32 mode, this function + is unable to return the full 32-bit range of characters, this value is deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_REQUIREDCHAR values should be used. PCRE_INFO_MATCH_EMPTY - Return 1 if the pattern can match an empty string, otherwise 0. The + Return 1 if the pattern can match an empty string, otherwise 0. The fourth argument should point to an int variable. PCRE_INFO_MATCHLIMIT - If the pattern set a match limit by including an item of the form - (*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth - argument should point to an unsigned 32-bit integer. If no such value - has been set, the call to pcre_fullinfo() returns the error + If the pattern set a match limit by including an item of the form + (*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth + argument should point to an unsigned 32-bit integer. If no such value + has been set, the call to pcre_fullinfo() returns the error PCRE_ERROR_UNSET. PCRE_INFO_MAXLOOKBEHIND - Return the number of characters (NB not data units) in the longest - lookbehind assertion in the pattern. This information is useful when - doing multi-segment matching using the partial matching facilities. + Return the number of characters (NB not data units) in the longest + lookbehind assertion in the pattern. This information is useful when + doing multi-segment matching using the partial matching facilities. Note that the simple assertions \b and \B require a one-character look- - behind. \A also registers a one-character lookbehind, though it does - not actually inspect the previous character. This is to ensure that at + behind. \A also registers a one-character lookbehind, though it does + not actually inspect the previous character. This is to ensure that at least one character from the old segment is retained when a new segment is processed. Otherwise, if there are no lookbehinds in the pattern, \A might match incorrectly at the start of a new segment. PCRE_INFO_MINLENGTH - If the pattern was studied and a minimum length for matching subject - strings was computed, its value is returned. Otherwise the returned + If the pattern was studied and a minimum length for matching subject + strings was computed, its value is returned. Otherwise the returned value is -1. The value is a number of characters, which in UTF mode may - be different from the number of data units. The fourth argument should - point to an int variable. A non-negative value is a lower bound to the - length of any matching string. There may not be any strings of that - length that do actually match, but every string that does match is at + be different from the number of data units. The fourth argument should + point to an int variable. A non-negative value is a lower bound to the + length of any matching string. There may not be any strings of that + length that do actually match, but every string that does match is at least that long. PCRE_INFO_NAMECOUNT PCRE_INFO_NAMEENTRYSIZE PCRE_INFO_NAMETABLE - PCRE supports the use of named as well as numbered capturing parenthe- - ses. The names are just an additional way of identifying the parenthe- + PCRE supports the use of named as well as numbered capturing parenthe- + ses. The names are just an additional way of identifying the parenthe- ses, which still acquire numbers. Several convenience functions such as - pcre_get_named_substring() are provided for extracting captured sub- - strings by name. It is also possible to extract the data directly, by - first converting the name to a number in order to access the correct + pcre_get_named_substring() are provided for extracting captured sub- + strings by name. It is also possible to extract the data directly, by + first converting the name to a number in order to access the correct pointers in the output vector (described with pcre_exec() below). To do - the conversion, you need to use the name-to-number map, which is + the conversion, you need to use the name-to-number map, which is described by these three values. The map consists of a number of fixed-size entries. PCRE_INFO_NAMECOUNT gives the number of entries, and PCRE_INFO_NAMEENTRYSIZE gives the size - of each entry; both of these return an int value. The entry size - depends on the length of the longest name. PCRE_INFO_NAMETABLE returns + of each entry; both of these return an int value. The entry size + depends on the length of the longest name. PCRE_INFO_NAMETABLE returns a pointer to the first entry of the table. This is a pointer to char in the 8-bit library, where the first two bytes of each entry are the num- - ber of the capturing parenthesis, most significant byte first. In the - 16-bit library, the pointer points to 16-bit data units, the first of - which contains the parenthesis number. In the 32-bit library, the - pointer points to 32-bit data units, the first of which contains the - parenthesis number. The rest of the entry is the corresponding name, + ber of the capturing parenthesis, most significant byte first. In the + 16-bit library, the pointer points to 16-bit data units, the first of + which contains the parenthesis number. In the 32-bit library, the + pointer points to 32-bit data units, the first of which contains the + parenthesis number. The rest of the entry is the corresponding name, zero terminated. - The names are in alphabetical order. If (?| is used to create multiple - groups with the same number, as described in the section on duplicate + The names are in alphabetical order. If (?| is used to create multiple + groups with the same number, as described in the section on duplicate subpattern numbers in the pcrepattern page, the groups may be given the - same name, but there is only one entry in the table. Different names - for groups of the same number are not permitted. Duplicate names for + same name, but there is only one entry in the table. Different names + for groups of the same number are not permitted. Duplicate names for subpatterns with different numbers are permitted, but only if PCRE_DUP- - NAMES is set. They appear in the table in the order in which they were - found in the pattern. In the absence of (?| this is the order of - increasing number; when (?| is used this is not necessarily the case + NAMES is set. They appear in the table in the order in which they were + found in the pattern. In the absence of (?| this is the order of + increasing number; when (?| is used this is not necessarily the case because later subpatterns may have lower numbers. - As a simple example of the name/number table, consider the following + As a simple example of the name/number table, consider the following pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is set, so white space - including newlines - is ignored): (? (?(\d\d)?\d\d) - (?\d\d) - (?\d\d) ) - There are four named subpatterns, so the table has four entries, and - each entry in the table is eight bytes long. The table is as follows, + There are four named subpatterns, so the table has four entries, and + each entry in the table is eight bytes long. The table is as follows, with non-printing bytes shows in hexadecimal, and undefined bytes shown as ??: @@ -2948,31 +2947,31 @@ INFORMATION ABOUT A PATTERN 00 04 m o n t h 00 00 02 y e a r 00 ?? - When writing code to extract data from named subpatterns using the - name-to-number map, remember that the length of the entries is likely + When writing code to extract data from named subpatterns using the + name-to-number map, remember that the length of the entries is likely to be different for each compiled pattern. PCRE_INFO_OKPARTIAL - Return 1 if the pattern can be used for partial matching with - pcre_exec(), otherwise 0. The fourth argument should point to an int - variable. From release 8.00, this always returns 1, because the - restrictions that previously applied to partial matching have been - lifted. The pcrepartial documentation gives details of partial match- + Return 1 if the pattern can be used for partial matching with + pcre_exec(), otherwise 0. The fourth argument should point to an int + variable. From release 8.00, this always returns 1, because the + restrictions that previously applied to partial matching have been + lifted. The pcrepartial documentation gives details of partial match- ing. PCRE_INFO_OPTIONS - Return a copy of the options with which the pattern was compiled. The - fourth argument should point to an unsigned long int variable. These + Return a copy of the options with which the pattern was compiled. The + fourth argument should point to an unsigned long int variable. These option bits are those specified in the call to pcre_compile(), modified by any top-level option settings at the start of the pattern itself. In - other words, they are the options that will be in force when matching - starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with - the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, + other words, they are the options that will be in force when matching + starts. For example, if the pattern /(?im)abc(?-i)d/ is compiled with + the PCRE_EXTENDED option, the result is PCRE_CASELESS, PCRE_MULTILINE, and PCRE_EXTENDED. - A pattern is automatically anchored by PCRE if all of its top-level + A pattern is automatically anchored by PCRE if all of its top-level alternatives begin with one of the following: ^ unless PCRE_MULTILINE is set @@ -2986,53 +2985,53 @@ INFORMATION ABOUT A PATTERN PCRE_INFO_RECURSIONLIMIT - If the pattern set a recursion limit by including an item of the form + If the pattern set a recursion limit by including an item of the form (*LIMIT_RECURSION=nnnn) at the start, the value is returned. The fourth - argument should point to an unsigned 32-bit integer. If no such value - has been set, the call to pcre_fullinfo() returns the error + argument should point to an unsigned 32-bit integer. If no such value + has been set, the call to pcre_fullinfo() returns the error PCRE_ERROR_UNSET. PCRE_INFO_SIZE - Return the size of the compiled pattern in bytes (for all three + Return the size of the compiled pattern in bytes (for all three libraries). The fourth argument should point to a size_t variable. This - value does not include the size of the pcre structure that is returned - by pcre_compile(). The value that is passed as the argument to - pcre_malloc() when pcre_compile() is getting memory in which to place + value does not include the size of the pcre structure that is returned + by pcre_compile(). The value that is passed as the argument to + pcre_malloc() when pcre_compile() is getting memory in which to place the compiled data is the value returned by this option plus the size of - the pcre structure. Studying a compiled pattern, with or without JIT, + the pcre structure. Studying a compiled pattern, with or without JIT, does not alter the value returned by this option. PCRE_INFO_STUDYSIZE - Return the size in bytes (for all three libraries) of the data block + Return the size in bytes (for all three libraries) of the data block pointed to by the study_data field in a pcre_extra block. If pcre_extra - is NULL, or there is no study data, zero is returned. The fourth argu- - ment should point to a size_t variable. The study_data field is set by + is NULL, or there is no study data, zero is returned. The fourth argu- + ment should point to a size_t variable. The study_data field is set by pcre_study() to record information that will speed up matching (see the - section entitled "Studying a pattern" above). The format of the - study_data block is private, but its length is made available via this - option so that it can be saved and restored (see the pcreprecompile + section entitled "Studying a pattern" above). The format of the + study_data block is private, but its length is made available via this + option so that it can be saved and restored (see the pcreprecompile documentation for details). PCRE_INFO_REQUIREDCHARFLAGS - Returns 1 if there is a rightmost literal data unit that must exist in + Returns 1 if there is a rightmost literal data unit that must exist in any matched string, other than at its start. The fourth argument should - point to an int variable. If there is no such value, 0 is returned. If + point to an int variable. If there is no such value, 0 is returned. If returning 1, the character value itself can be retrieved using PCRE_INFO_REQUIREDCHAR. For anchored patterns, a last literal value is recorded only if it fol- - lows something of variable length. For example, for the pattern - /^a\d+z\d+/ the returned value 1 (with "z" returned from + lows something of variable length. For example, for the pattern + /^a\d+z\d+/ the returned value 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for /^a\dz\d/ the returned value is 0. PCRE_INFO_REQUIREDCHAR - Return the value of the rightmost literal data unit that must exist in - any matched string, other than at its start, if such a value has been - recorded. The fourth argument should point to an uint32_t variable. If + Return the value of the rightmost literal data unit that must exist in + any matched string, other than at its start, if such a value has been + recorded. The fourth argument should point to an uint32_t variable. If there is no such value, 0 is returned. @@ -3040,21 +3039,21 @@ REFERENCE COUNTS int pcre_refcount(pcre *code, int adjust); - The pcre_refcount() function is used to maintain a reference count in + The pcre_refcount() function is used to maintain a reference count in the data block that contains a compiled pattern. It is provided for the - benefit of applications that operate in an object-oriented manner, + benefit of applications that operate in an object-oriented manner, where different parts of the application may be using the same compiled pattern, but you want to free the block when they are all done. When a pattern is compiled, the reference count field is initialized to - zero. It is changed only by calling this function, whose action is to - add the adjust value (which may be positive or negative) to it. The + zero. It is changed only by calling this function, whose action is to + add the adjust value (which may be positive or negative) to it. The yield of the function is the new value. However, the value of the count - is constrained to lie between 0 and 65535, inclusive. If the new value + is constrained to lie between 0 and 65535, inclusive. If the new value is outside these limits, it is forced to the appropriate limit value. - Except when it is zero, the reference count is not correctly preserved - if a pattern is compiled on one host and then transferred to a host + Except when it is zero, the reference count is not correctly preserved + if a pattern is compiled on one host and then transferred to a host whose byte-order is different. (This seems a highly unlikely scenario.) @@ -3064,22 +3063,22 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); - The function pcre_exec() is called to match a subject string against a - compiled pattern, which is passed in the code argument. If the pattern - was studied, the result of the study should be passed in the extra - argument. You can call pcre_exec() with the same code and extra argu- - ments as many times as you like, in order to match different subject + The function pcre_exec() is called to match a subject string against a + compiled pattern, which is passed in the code argument. If the pattern + was studied, the result of the study should be passed in the extra + argument. You can call pcre_exec() with the same code and extra argu- + ments as many times as you like, in order to match different subject strings with the same pattern. - This function is the main matching facility of the library, and it - operates in a Perl-like manner. For specialist use there is also an - alternative matching function, which is described below in the section + This function is the main matching facility of the library, and it + operates in a Perl-like manner. For specialist use there is also an + alternative matching function, which is described below in the section about the pcre_dfa_exec() function. - In most applications, the pattern will have been compiled (and option- - ally studied) in the same process that calls pcre_exec(). However, it + In most applications, the pattern will have been compiled (and option- + ally studied) in the same process that calls pcre_exec(). However, it is possible to save compiled patterns and study data, and then use them - later in different processes, possibly even on different hosts. For a + later in different processes, possibly even on different hosts. For a discussion about this, see the pcreprecompile documentation. Here is an example of a simple call to pcre_exec(): @@ -3098,10 +3097,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION Extra data for pcre_exec() - If the extra argument is not NULL, it must point to a pcre_extra data - block. The pcre_study() function returns such a block (when it doesn't - return NULL), but you can also create one for yourself, and pass addi- - tional information in it. The pcre_extra block contains the following + If the extra argument is not NULL, it must point to a pcre_extra data + block. The pcre_study() function returns such a block (when it doesn't + return NULL), but you can also create one for yourself, and pass addi- + tional information in it. The pcre_extra block contains the following fields (not necessarily in this order): unsigned long int flags; @@ -3113,13 +3112,13 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION const unsigned char *tables; unsigned char **mark; - In the 16-bit version of this structure, the mark field has type + In the 16-bit version of this structure, the mark field has type "PCRE_UCHAR16 **". - In the 32-bit version of this structure, the mark field has type + In the 32-bit version of this structure, the mark field has type "PCRE_UCHAR32 **". - The flags field is used to specify which of the other fields are set. + The flags field is used to specify which of the other fields are set. The flag bits are: PCRE_EXTRA_CALLOUT_DATA @@ -3130,134 +3129,134 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_TABLES - Other flag bits should be set to zero. The study_data field and some- - times the executable_jit field are set in the pcre_extra block that is - returned by pcre_study(), together with the appropriate flag bits. You - should not set these yourself, but you may add to the block by setting + Other flag bits should be set to zero. The study_data field and some- + times the executable_jit field are set in the pcre_extra block that is + returned by pcre_study(), together with the appropriate flag bits. You + should not set these yourself, but you may add to the block by setting other fields and their corresponding flag bits. The match_limit field provides a means of preventing PCRE from using up - a vast amount of resources when running patterns that are not going to - match, but which have a very large number of possibilities in their - search trees. The classic example is a pattern that uses nested unlim- + a vast amount of resources when running patterns that are not going to + match, but which have a very large number of possibilities in their + search trees. The classic example is a pattern that uses nested unlim- ited repeats. - Internally, pcre_exec() uses a function called match(), which it calls - repeatedly (sometimes recursively). The limit set by match_limit is - imposed on the number of times this function is called during a match, - which has the effect of limiting the amount of backtracking that can + Internally, pcre_exec() uses a function called match(), which it calls + repeatedly (sometimes recursively). The limit set by match_limit is + imposed on the number of times this function is called during a match, + which has the effect of limiting the amount of backtracking that can take place. For patterns that are not anchored, the count restarts from zero for each position in the subject string. When pcre_exec() is called with a pattern that was successfully studied - with a JIT option, the way that the matching is executed is entirely + with a JIT option, the way that the matching is executed is entirely different. However, there is still the possibility of runaway matching that goes on for a very long time, and so the match_limit value is also used in this case (but in a different way) to limit how long the match- ing can continue. - The default value for the limit can be set when PCRE is built; the - default default is 10 million, which handles all but the most extreme - cases. You can override the default by suppling pcre_exec() with a - pcre_extra block in which match_limit is set, and - PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is + The default value for the limit can be set when PCRE is built; the + default default is 10 million, which handles all but the most extreme + cases. You can override the default by suppling pcre_exec() with a + pcre_extra block in which match_limit is set, and + PCRE_EXTRA_MATCH_LIMIT is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. - A value for the match limit may also be supplied by an item at the + A value for the match limit may also be supplied by an item at the start of a pattern of the form (*LIMIT_MATCH=d) - where d is a decimal number. However, such a setting is ignored unless - d is less than the limit set by the caller of pcre_exec() or, if no + where d is a decimal number. However, such a setting is ignored unless + d is less than the limit set by the caller of pcre_exec() or, if no such limit is set, less than the default. - The match_limit_recursion field is similar to match_limit, but instead + The match_limit_recursion field is similar to match_limit, but instead of limiting the total number of times that match() is called, it limits - the depth of recursion. The recursion depth is a smaller number than - the total number of calls, because not all calls to match() are recur- + the depth of recursion. The recursion depth is a smaller number than + the total number of calls, because not all calls to match() are recur- sive. This limit is of use only if it is set smaller than match_limit. - Limiting the recursion depth limits the amount of machine stack that - can be used, or, when PCRE has been compiled to use memory on the heap - instead of the stack, the amount of heap memory that can be used. This - limit is not relevant, and is ignored, when matching is done using JIT + Limiting the recursion depth limits the amount of machine stack that + can be used, or, when PCRE has been compiled to use memory on the heap + instead of the stack, the amount of heap memory that can be used. This + limit is not relevant, and is ignored, when matching is done using JIT compiled code. - The default value for match_limit_recursion can be set when PCRE is - built; the default default is the same value as the default for - match_limit. You can override the default by suppling pcre_exec() with - a pcre_extra block in which match_limit_recursion is set, and - PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the + The default value for match_limit_recursion can be set when PCRE is + built; the default default is the same value as the default for + match_limit. You can override the default by suppling pcre_exec() with + a pcre_extra block in which match_limit_recursion is set, and + PCRE_EXTRA_MATCH_LIMIT_RECURSION is set in the flags field. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_RECURSIONLIMIT. - A value for the recursion limit may also be supplied by an item at the + A value for the recursion limit may also be supplied by an item at the start of a pattern of the form (*LIMIT_RECURSION=d) - where d is a decimal number. However, such a setting is ignored unless - d is less than the limit set by the caller of pcre_exec() or, if no + where d is a decimal number. However, such a setting is ignored unless + d is less than the limit set by the caller of pcre_exec() or, if no such limit is set, less than the default. - The callout_data field is used in conjunction with the "callout" fea- + The callout_data field is used in conjunction with the "callout" fea- ture, and is described in the pcrecallout documentation. - The tables field is provided for use with patterns that have been pre- + The tables field is provided for use with patterns that have been pre- compiled using custom character tables, saved to disc or elsewhere, and - then reloaded, because the tables that were used to compile a pattern - are not saved with it. See the pcreprecompile documentation for a dis- - cussion of saving compiled patterns for later use. If NULL is passed + then reloaded, because the tables that were used to compile a pattern + are not saved with it. See the pcreprecompile documentation for a dis- + cussion of saving compiled patterns for later use. If NULL is passed using this mechanism, it forces PCRE's internal tables to be used. - Warning: The tables that pcre_exec() uses must be the same as those - that were used when the pattern was compiled. If this is not the case, + Warning: The tables that pcre_exec() uses must be the same as those + that were used when the pattern was compiled. If this is not the case, the behaviour of pcre_exec() is undefined. Therefore, when a pattern is - compiled and matched in the same process, this field should never be + compiled and matched in the same process, this field should never be set. In this (the most common) case, the correct table pointer is auto- - matically passed with the compiled pattern from pcre_compile() to + matically passed with the compiled pattern from pcre_compile() to pcre_exec(). - If PCRE_EXTRA_MARK is set in the flags field, the mark field must be - set to point to a suitable variable. If the pattern contains any back- - tracking control verbs such as (*MARK:NAME), and the execution ends up - with a name to pass back, a pointer to the name string (zero termi- - nated) is placed in the variable pointed to by the mark field. The - names are within the compiled pattern; if you wish to retain such a - name you must copy it before freeing the memory of a compiled pattern. - If there is no name to pass back, the variable pointed to by the mark - field is set to NULL. For details of the backtracking control verbs, + If PCRE_EXTRA_MARK is set in the flags field, the mark field must be + set to point to a suitable variable. If the pattern contains any back- + tracking control verbs such as (*MARK:NAME), and the execution ends up + with a name to pass back, a pointer to the name string (zero termi- + nated) is placed in the variable pointed to by the mark field. The + names are within the compiled pattern; if you wish to retain such a + name you must copy it before freeing the memory of a compiled pattern. + If there is no name to pass back, the variable pointed to by the mark + field is set to NULL. For details of the backtracking control verbs, see the section entitled "Backtracking control" in the pcrepattern doc- umentation. Option bits for pcre_exec() - The unused bits of the options argument for pcre_exec() must be zero. - The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, - PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, - PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and + The unused bits of the options argument for pcre_exec() must be zero. + The only bits that may be set are PCRE_ANCHORED, PCRE_NEWLINE_xxx, + PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, + PCRE_NO_START_OPTIMIZE, PCRE_NO_UTF8_CHECK, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. - If the pattern was successfully studied with one of the just-in-time + If the pattern was successfully studied with one of the just-in-time (JIT) compile options, the only supported options for JIT execution are - PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, - PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an - unsupported option is used, JIT execution is disabled and the normal + PCRE_NO_UTF8_CHECK, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, + PCRE_NOTEMPTY_ATSTART, PCRE_PARTIAL_HARD, and PCRE_PARTIAL_SOFT. If an + unsupported option is used, JIT execution is disabled and the normal interpretive code in pcre_exec() is run. PCRE_ANCHORED - The PCRE_ANCHORED option limits pcre_exec() to matching at the first - matching position. If a pattern was compiled with PCRE_ANCHORED, or - turned out to be anchored by virtue of its contents, it cannot be made + The PCRE_ANCHORED option limits pcre_exec() to matching at the first + matching position. If a pattern was compiled with PCRE_ANCHORED, or + turned out to be anchored by virtue of its contents, it cannot be made unachored at matching time. PCRE_BSR_ANYCRLF PCRE_BSR_UNICODE These options (which are mutually exclusive) control what the \R escape - sequence matches. The choice is either to match only CR, LF, or CRLF, - or to match any Unicode newline sequence. These options override the + sequence matches. The choice is either to match only CR, LF, or CRLF, + or to match any Unicode newline sequence. These options override the choice that was made or defaulted when the pattern was compiled. PCRE_NEWLINE_CR @@ -3266,345 +3265,345 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_NEWLINE_ANYCRLF PCRE_NEWLINE_ANY - These options override the newline definition that was chosen or - defaulted when the pattern was compiled. For details, see the descrip- - tion of pcre_compile() above. During matching, the newline choice - affects the behaviour of the dot, circumflex, and dollar metacharac- - ters. It may also alter the way the match position is advanced after a + These options override the newline definition that was chosen or + defaulted when the pattern was compiled. For details, see the descrip- + tion of pcre_compile() above. During matching, the newline choice + affects the behaviour of the dot, circumflex, and dollar metacharac- + ters. It may also alter the way the match position is advanced after a match failure for an unanchored pattern. - When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is - set, and a match attempt for an unanchored pattern fails when the cur- - rent position is at a CRLF sequence, and the pattern contains no - explicit matches for CR or LF characters, the match position is + When PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANYCRLF, or PCRE_NEWLINE_ANY is + set, and a match attempt for an unanchored pattern fails when the cur- + rent position is at a CRLF sequence, and the pattern contains no + explicit matches for CR or LF characters, the match position is advanced by two characters instead of one, in other words, to after the CRLF. The above rule is a compromise that makes the most common cases work as - expected. For example, if the pattern is .+A (and the PCRE_DOTALL + expected. For example, if the pattern is .+A (and the PCRE_DOTALL option is not set), it does not match the string "\r\nA" because, after - failing at the start, it skips both the CR and the LF before retrying. - However, the pattern [\r\n]A does match that string, because it con- + failing at the start, it skips both the CR and the LF before retrying. + However, the pattern [\r\n]A does match that string, because it con- tains an explicit CR or LF reference, and so advances only by one char- acter after the first failure. An explicit match for CR of LF is either a literal appearance of one of - those characters, or one of the \r or \n escape sequences. Implicit - matches such as [^X] do not count, nor does \s (which includes CR and + those characters, or one of the \r or \n escape sequences. Implicit + matches such as [^X] do not count, nor does \s (which includes CR and LF in the characters that it matches). - Notwithstanding the above, anomalous effects may still occur when CRLF + Notwithstanding the above, anomalous effects may still occur when CRLF is a valid newline sequence and explicit \r or \n escapes appear in the pattern. PCRE_NOTBOL This option specifies that first character of the subject string is not - the beginning of a line, so the circumflex metacharacter should not - match before it. Setting this without PCRE_MULTILINE (at compile time) - causes circumflex never to match. This option affects only the behav- + the beginning of a line, so the circumflex metacharacter should not + match before it. Setting this without PCRE_MULTILINE (at compile time) + causes circumflex never to match. This option affects only the behav- iour of the circumflex metacharacter. It does not affect \A. PCRE_NOTEOL This option specifies that the end of the subject string is not the end - of a line, so the dollar metacharacter should not match it nor (except - in multiline mode) a newline immediately before it. Setting this with- + of a line, so the dollar metacharacter should not match it nor (except + in multiline mode) a newline immediately before it. Setting this with- out PCRE_MULTILINE (at compile time) causes dollar never to match. This - option affects only the behaviour of the dollar metacharacter. It does + option affects only the behaviour of the dollar metacharacter. It does not affect \Z or \z. PCRE_NOTEMPTY An empty string is not considered to be a valid match if this option is - set. If there are alternatives in the pattern, they are tried. If all - the alternatives match the empty string, the entire match fails. For + set. If there are alternatives in the pattern, they are tried. If all + the alternatives match the empty string, the entire match fails. For example, if the pattern a?b? - is applied to a string not beginning with "a" or "b", it matches an - empty string at the start of the subject. With PCRE_NOTEMPTY set, this + is applied to a string not beginning with "a" or "b", it matches an + empty string at the start of the subject. With PCRE_NOTEMPTY set, this match is not valid, so PCRE searches further into the string for occur- rences of "a" or "b". PCRE_NOTEMPTY_ATSTART - This is like PCRE_NOTEMPTY, except that an empty string match that is - not at the start of the subject is permitted. If the pattern is + This is like PCRE_NOTEMPTY, except that an empty string match that is + not at the start of the subject is permitted. If the pattern is anchored, such a match can occur only if the pattern contains \K. - Perl has no direct equivalent of PCRE_NOTEMPTY or - PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern - match of the empty string within its split() function, and when using - the /g modifier. It is possible to emulate Perl's behaviour after + Perl has no direct equivalent of PCRE_NOTEMPTY or + PCRE_NOTEMPTY_ATSTART, but it does make a special case of a pattern + match of the empty string within its split() function, and when using + the /g modifier. It is possible to emulate Perl's behaviour after matching a null string by first trying the match again at the same off- - set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that + set with PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED, and then if that fails, by advancing the starting offset (see below) and trying an ordi- - nary match again. There is some code that demonstrates how to do this - in the pcredemo sample program. In the most general case, you have to - check to see if the newline convention recognizes CRLF as a newline, - and if so, and the current character is CR followed by LF, advance the + nary match again. There is some code that demonstrates how to do this + in the pcredemo sample program. In the most general case, you have to + check to see if the newline convention recognizes CRLF as a newline, + and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. PCRE_NO_START_OPTIMIZE - There are a number of optimizations that pcre_exec() uses at the start - of a match, in order to speed up the process. For example, if it is + There are a number of optimizations that pcre_exec() uses at the start + of a match, in order to speed up the process. For example, if it is known that an unanchored match must start with a specific character, it - searches the subject for that character, and fails immediately if it - cannot find it, without actually running the main matching function. + searches the subject for that character, and fails immediately if it + cannot find it, without actually running the main matching function. This means that a special item such as (*COMMIT) at the start of a pat- - tern is not considered until after a suitable starting point for the - match has been found. Also, when callouts or (*MARK) items are in use, + tern is not considered until after a suitable starting point for the + match has been found. Also, when callouts or (*MARK) items are in use, these "start-up" optimizations can cause them to be skipped if the pat- tern is never actually used. The start-up optimizations are in effect a pre-scan of the subject that takes place before the pattern is run. - The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, - possibly causing performance to suffer, but ensuring that in cases - where the result is "no match", the callouts do occur, and that items + The PCRE_NO_START_OPTIMIZE option disables the start-up optimizations, + possibly causing performance to suffer, but ensuring that in cases + where the result is "no match", the callouts do occur, and that items such as (*COMMIT) and (*MARK) are considered at every possible starting - position in the subject string. If PCRE_NO_START_OPTIMIZE is set at - compile time, it cannot be unset at matching time. The use of + position in the subject string. If PCRE_NO_START_OPTIMIZE is set at + compile time, it cannot be unset at matching time. The use of PCRE_NO_START_OPTIMIZE at matching time (that is, passing it to - pcre_exec()) disables JIT execution; in this situation, matching is + pcre_exec()) disables JIT execution; in this situation, matching is always done using interpretively. - Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching + Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching operation. Consider the pattern (*COMMIT)ABC - When this is compiled, PCRE records the fact that a match must start - with the character "A". Suppose the subject string is "DEFABC". The - start-up optimization scans along the subject, finds "A" and runs the - first match attempt from there. The (*COMMIT) item means that the pat- - tern must match the current starting position, which in this case, it - does. However, if the same match is run with PCRE_NO_START_OPTIMIZE - set, the initial scan along the subject string does not happen. The - first match attempt is run starting from "D" and when this fails, - (*COMMIT) prevents any further matches being tried, so the overall - result is "no match". If the pattern is studied, more start-up opti- - mizations may be used. For example, a minimum length for the subject + When this is compiled, PCRE records the fact that a match must start + with the character "A". Suppose the subject string is "DEFABC". The + start-up optimization scans along the subject, finds "A" and runs the + first match attempt from there. The (*COMMIT) item means that the pat- + tern must match the current starting position, which in this case, it + does. However, if the same match is run with PCRE_NO_START_OPTIMIZE + set, the initial scan along the subject string does not happen. The + first match attempt is run starting from "D" and when this fails, + (*COMMIT) prevents any further matches being tried, so the overall + result is "no match". If the pattern is studied, more start-up opti- + mizations may be used. For example, a minimum length for the subject may be recorded. Consider the pattern (*MARK:A)(X|Y) - The minimum length for a match is one character. If the subject is - "ABC", there will be attempts to match "ABC", "BC", "C", and then - finally an empty string. If the pattern is studied, the final attempt - does not take place, because PCRE knows that the subject is too short, - and so the (*MARK) is never encountered. In this case, studying the - pattern does not affect the overall match result, which is still "no + The minimum length for a match is one character. If the subject is + "ABC", there will be attempts to match "ABC", "BC", "C", and then + finally an empty string. If the pattern is studied, the final attempt + does not take place, because PCRE knows that the subject is too short, + and so the (*MARK) is never encountered. In this case, studying the + pattern does not affect the overall match result, which is still "no match", but it does affect the auxiliary information that is returned. PCRE_NO_UTF8_CHECK When PCRE_UTF8 is set at compile time, the validity of the subject as a - UTF-8 string is automatically checked when pcre_exec() is subsequently + UTF-8 string is automatically checked when pcre_exec() is subsequently called. The entire string is checked before any other processing takes - place. The value of startoffset is also checked to ensure that it - points to the start of a UTF-8 character. There is a discussion about - the validity of UTF-8 strings in the pcreunicode page. If an invalid - sequence of bytes is found, pcre_exec() returns the error + place. The value of startoffset is also checked to ensure that it + points to the start of a UTF-8 character. There is a discussion about + the validity of UTF-8 strings in the pcreunicode page. If an invalid + sequence of bytes is found, pcre_exec() returns the error PCRE_ERROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a truncated character at the end of the subject, PCRE_ERROR_SHORTUTF8. In - both cases, information about the precise nature of the error may also - be returned (see the descriptions of these errors in the section enti- - tled Error return values from pcre_exec() below). If startoffset con- + both cases, information about the precise nature of the error may also + be returned (see the descriptions of these errors in the section enti- + tled Error return values from pcre_exec() below). If startoffset con- tains a value that does not point to the start of a UTF-8 character (or to the end of the subject), PCRE_ERROR_BADUTF8_OFFSET is returned. - If you already know that your subject is valid, and you want to skip - these checks for performance reasons, you can set the - PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to - do this for the second and subsequent calls to pcre_exec() if you are - making repeated calls to find all the matches in a single subject - string. However, you should be sure that the value of startoffset - points to the start of a character (or the end of the subject). When + If you already know that your subject is valid, and you want to skip + these checks for performance reasons, you can set the + PCRE_NO_UTF8_CHECK option when calling pcre_exec(). You might want to + do this for the second and subsequent calls to pcre_exec() if you are + making repeated calls to find all the matches in a single subject + string. However, you should be sure that the value of startoffset + points to the start of a character (or the end of the subject). When PCRE_NO_UTF8_CHECK is set, the effect of passing an invalid string as a - subject or an invalid value of startoffset is undefined. Your program + subject or an invalid value of startoffset is undefined. Your program may crash or loop. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These options turn on the partial matching feature. For backwards com- - patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial - match occurs if the end of the subject string is reached successfully, - but there are not enough subject characters to complete the match. If + These options turn on the partial matching feature. For backwards com- + patibility, PCRE_PARTIAL is a synonym for PCRE_PARTIAL_SOFT. A partial + match occurs if the end of the subject string is reached successfully, + but there are not enough subject characters to complete the match. If this happens when PCRE_PARTIAL_SOFT (but not PCRE_PARTIAL_HARD) is set, - matching continues by testing any remaining alternatives. Only if no - complete match can be found is PCRE_ERROR_PARTIAL returned instead of - PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the - caller is prepared to handle a partial match, but only if no complete + matching continues by testing any remaining alternatives. Only if no + complete match can be found is PCRE_ERROR_PARTIAL returned instead of + PCRE_ERROR_NOMATCH. In other words, PCRE_PARTIAL_SOFT says that the + caller is prepared to handle a partial match, but only if no complete match can be found. - If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this - case, if a partial match is found, pcre_exec() immediately returns - PCRE_ERROR_PARTIAL, without considering any other alternatives. In - other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- + If PCRE_PARTIAL_HARD is set, it overrides PCRE_PARTIAL_SOFT. In this + case, if a partial match is found, pcre_exec() immediately returns + PCRE_ERROR_PARTIAL, without considering any other alternatives. In + other words, when PCRE_PARTIAL_HARD is set, a partial match is consid- ered to be more important that an alternative complete match. - In both cases, the portion of the string that was inspected when the + In both cases, the portion of the string that was inspected when the partial match was found is set as the first matching string. There is a - more detailed discussion of partial and multi-segment matching, with + more detailed discussion of partial and multi-segment matching, with examples, in the pcrepartial documentation. The string to be matched by pcre_exec() - The subject string is passed to pcre_exec() as a pointer in subject, a - length in length, and a starting offset in startoffset. The units for - length and startoffset are bytes for the 8-bit library, 16-bit data - items for the 16-bit library, and 32-bit data items for the 32-bit + The subject string is passed to pcre_exec() as a pointer in subject, a + length in length, and a starting offset in startoffset. The units for + length and startoffset are bytes for the 8-bit library, 16-bit data + items for the 16-bit library, and 32-bit data items for the 32-bit library. - If startoffset is negative or greater than the length of the subject, - pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is - zero, the search for a match starts at the beginning of the subject, - and this is by far the most common case. In UTF-8 or UTF-16 mode, the - offset must point to the start of a character, or the end of the sub- - ject (in UTF-32 mode, one data unit equals one character, so all off- - sets are valid). Unlike the pattern string, the subject may contain + If startoffset is negative or greater than the length of the subject, + pcre_exec() returns PCRE_ERROR_BADOFFSET. When the starting offset is + zero, the search for a match starts at the beginning of the subject, + and this is by far the most common case. In UTF-8 or UTF-16 mode, the + offset must point to the start of a character, or the end of the sub- + ject (in UTF-32 mode, one data unit equals one character, so all off- + sets are valid). Unlike the pattern string, the subject may contain binary zeroes. - A non-zero starting offset is useful when searching for another match - in the same subject by calling pcre_exec() again after a previous suc- - cess. Setting startoffset differs from just passing over a shortened - string and setting PCRE_NOTBOL in the case of a pattern that begins + A non-zero starting offset is useful when searching for another match + in the same subject by calling pcre_exec() again after a previous suc- + cess. Setting startoffset differs from just passing over a shortened + string and setting PCRE_NOTBOL in the case of a pattern that begins with any kind of lookbehind. For example, consider the pattern \Biss\B - which finds occurrences of "iss" in the middle of words. (\B matches - only if the current position in the subject is not a word boundary.) - When applied to the string "Mississipi" the first call to pcre_exec() - finds the first occurrence. If pcre_exec() is called again with just - the remainder of the subject, namely "issipi", it does not match, + which finds occurrences of "iss" in the middle of words. (\B matches + only if the current position in the subject is not a word boundary.) + When applied to the string "Mississipi" the first call to pcre_exec() + finds the first occurrence. If pcre_exec() is called again with just + the remainder of the subject, namely "issipi", it does not match, because \B is always false at the start of the subject, which is deemed - to be a word boundary. However, if pcre_exec() is passed the entire + to be a word boundary. However, if pcre_exec() is passed the entire string again, but with startoffset set to 4, it finds the second occur- - rence of "iss" because it is able to look behind the starting point to + rence of "iss" because it is able to look behind the starting point to discover that it is preceded by a letter. - Finding all the matches in a subject is tricky when the pattern can + Finding all the matches in a subject is tricky when the pattern can match an empty string. It is possible to emulate Perl's /g behaviour by - first trying the match again at the same offset, with the - PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that - fails, advancing the starting offset and trying an ordinary match + first trying the match again at the same offset, with the + PCRE_NOTEMPTY_ATSTART and PCRE_ANCHORED options, and then if that + fails, advancing the starting offset and trying an ordinary match again. There is some code that demonstrates how to do this in the pcre- demo sample program. In the most general case, you have to check to see - if the newline convention recognizes CRLF as a newline, and if so, and + if the newline convention recognizes CRLF as a newline, and if so, and the current character is CR followed by LF, advance the starting offset by two characters instead of one. - If a non-zero starting offset is passed when the pattern is anchored, + If a non-zero starting offset is passed when the pattern is anchored, one attempt to match at the given offset is made. This can only succeed - if the pattern does not require the match to be at the start of the + if the pattern does not require the match to be at the start of the subject. How pcre_exec() returns captured substrings - In general, a pattern matches a certain portion of the subject, and in - addition, further substrings from the subject may be picked out by - parts of the pattern. Following the usage in Jeffrey Friedl's book, - this is called "capturing" in what follows, and the phrase "capturing - subpattern" is used for a fragment of a pattern that picks out a sub- - string. PCRE supports several other kinds of parenthesized subpattern + In general, a pattern matches a certain portion of the subject, and in + addition, further substrings from the subject may be picked out by + parts of the pattern. Following the usage in Jeffrey Friedl's book, + this is called "capturing" in what follows, and the phrase "capturing + subpattern" is used for a fragment of a pattern that picks out a sub- + string. PCRE supports several other kinds of parenthesized subpattern that do not cause substrings to be captured. Captured substrings are returned to the caller via a vector of integers - whose address is passed in ovector. The number of elements in the vec- - tor is passed in ovecsize, which must be a non-negative number. Note: + whose address is passed in ovector. The number of elements in the vec- + tor is passed in ovecsize, which must be a non-negative number. Note: this argument is NOT the size of ovector in bytes. - The first two-thirds of the vector is used to pass back captured sub- - strings, each substring using a pair of integers. The remaining third - of the vector is used as workspace by pcre_exec() while matching cap- - turing subpatterns, and is not available for passing back information. - The number passed in ovecsize should always be a multiple of three. If + The first two-thirds of the vector is used to pass back captured sub- + strings, each substring using a pair of integers. The remaining third + of the vector is used as workspace by pcre_exec() while matching cap- + turing subpatterns, and is not available for passing back information. + The number passed in ovecsize should always be a multiple of three. If it is not, it is rounded down. - When a match is successful, information about captured substrings is - returned in pairs of integers, starting at the beginning of ovector, - and continuing up to two-thirds of its length at the most. The first - element of each pair is set to the offset of the first character in a - substring, and the second is set to the offset of the first character - after the end of a substring. These values are always data unit off- - sets, even in UTF mode. They are byte offsets in the 8-bit library, - 16-bit data item offsets in the 16-bit library, and 32-bit data item + When a match is successful, information about captured substrings is + returned in pairs of integers, starting at the beginning of ovector, + and continuing up to two-thirds of its length at the most. The first + element of each pair is set to the offset of the first character in a + substring, and the second is set to the offset of the first character + after the end of a substring. These values are always data unit off- + sets, even in UTF mode. They are byte offsets in the 8-bit library, + 16-bit data item offsets in the 16-bit library, and 32-bit data item offsets in the 32-bit library. Note: they are not character counts. - The first pair of integers, ovector[0] and ovector[1], identify the - portion of the subject string matched by the entire pattern. The next - pair is used for the first capturing subpattern, and so on. The value + The first pair of integers, ovector[0] and ovector[1], identify the + portion of the subject string matched by the entire pattern. The next + pair is used for the first capturing subpattern, and so on. The value returned by pcre_exec() is one more than the highest numbered pair that - has been set. For example, if two substrings have been captured, the - returned value is 3. If there are no capturing subpatterns, the return + has been set. For example, if two substrings have been captured, the + returned value is 3. If there are no capturing subpatterns, the return value from a successful match is 1, indicating that just the first pair of offsets has been set. If a capturing subpattern is matched repeatedly, it is the last portion of the string that it matched that is returned. - If the vector is too small to hold all the captured substring offsets, + If the vector is too small to hold all the captured substring offsets, it is used as far as possible (up to two-thirds of its length), and the - function returns a value of zero. If neither the actual string matched - nor any captured substrings are of interest, pcre_exec() may be called - with ovector passed as NULL and ovecsize as zero. However, if the pat- - tern contains back references and the ovector is not big enough to - remember the related substrings, PCRE has to get additional memory for - use during matching. Thus it is usually advisable to supply an ovector + function returns a value of zero. If neither the actual string matched + nor any captured substrings are of interest, pcre_exec() may be called + with ovector passed as NULL and ovecsize as zero. However, if the pat- + tern contains back references and the ovector is not big enough to + remember the related substrings, PCRE has to get additional memory for + use during matching. Thus it is usually advisable to supply an ovector of reasonable size. - There are some cases where zero is returned (indicating vector over- - flow) when in fact the vector is exactly the right size for the final + There are some cases where zero is returned (indicating vector over- + flow) when in fact the vector is exactly the right size for the final match. For example, consider the pattern (a)(?:(b)c|bd) - If a vector of 6 elements (allowing for only 1 captured substring) is + If a vector of 6 elements (allowing for only 1 captured substring) is given with subject string "abd", pcre_exec() will try to set the second captured string, thereby recording a vector overflow, before failing to - match "c" and backing up to try the second alternative. The zero - return, however, does correctly indicate that the maximum number of + match "c" and backing up to try the second alternative. The zero + return, however, does correctly indicate that the maximum number of slots (namely 2) have been filled. In similar cases where there is tem- - porary overflow, but the final number of used slots is actually less + porary overflow, but the final number of used slots is actually less than the maximum, a non-zero value is returned. The pcre_fullinfo() function can be used to find out how many capturing - subpatterns there are in a compiled pattern. The smallest size for - ovector that will allow for n captured substrings, in addition to the + subpatterns there are in a compiled pattern. The smallest size for + ovector that will allow for n captured substrings, in addition to the offsets of the substring matched by the whole pattern, is (n+1)*3. - It is possible for capturing subpattern number n+1 to match some part + It is possible for capturing subpattern number n+1 to match some part of the subject when subpattern n has not been used at all. For example, - if the string "abc" is matched against the pattern (a|(z))(bc) the + if the string "abc" is matched against the pattern (a|(z))(bc) the return from the function is 4, and subpatterns 1 and 3 are matched, but - 2 is not. When this happens, both values in the offset pairs corre- + 2 is not. When this happens, both values in the offset pairs corre- sponding to unused subpatterns are set to -1. - Offset values that correspond to unused subpatterns at the end of the - expression are also set to -1. For example, if the string "abc" is - matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not - matched. The return from the function is 2, because the highest used - capturing subpattern number is 1, and the offsets for for the second - and third capturing subpatterns (assuming the vector is large enough, + Offset values that correspond to unused subpatterns at the end of the + expression are also set to -1. For example, if the string "abc" is + matched against the pattern (abc)(x(yz)?)? subpatterns 2 and 3 are not + matched. The return from the function is 2, because the highest used + capturing subpattern number is 1, and the offsets for for the second + and third capturing subpatterns (assuming the vector is large enough, of course) are set to -1. - Note: Elements in the first two-thirds of ovector that do not corre- - spond to capturing parentheses in the pattern are never changed. That - is, if a pattern contains n capturing parentheses, no more than ovec- - tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in + Note: Elements in the first two-thirds of ovector that do not corre- + spond to capturing parentheses in the pattern are never changed. That + is, if a pattern contains n capturing parentheses, no more than ovec- + tor[0] to ovector[2n+1] are set by pcre_exec(). The other elements (in the first two-thirds) retain whatever values they previously had. - Some convenience functions are provided for extracting the captured + Some convenience functions are provided for extracting the captured substrings as separate strings. These are described below. Error return values from pcre_exec() - If pcre_exec() fails, it returns a negative number. The following are + If pcre_exec() fails, it returns a negative number. The following are defined in the header file: PCRE_ERROR_NOMATCH (-1) @@ -3613,7 +3612,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_ERROR_NULL (-2) - Either code or subject was passed as NULL, or ovector was NULL and + Either code or subject was passed as NULL, or ovector was NULL and ovecsize was not zero. PCRE_ERROR_BADOPTION (-3) @@ -3622,82 +3621,82 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_ERROR_BADMAGIC (-4) - PCRE stores a 4-byte "magic number" at the start of the compiled code, + PCRE stores a 4-byte "magic number" at the start of the compiled code, to catch the case when it is passed a junk pointer and to detect when a pattern that was compiled in an environment of one endianness is run in - an environment with the other endianness. This is the error that PCRE + an environment with the other endianness. This is the error that PCRE gives when the magic number is not present. PCRE_ERROR_UNKNOWN_OPCODE (-5) While running the pattern match, an unknown item was encountered in the - compiled pattern. This error could be caused by a bug in PCRE or by + compiled pattern. This error could be caused by a bug in PCRE or by overwriting of the compiled pattern. PCRE_ERROR_NOMEMORY (-6) - If a pattern contains back references, but the ovector that is passed + If a pattern contains back references, but the ovector that is passed to pcre_exec() is not big enough to remember the referenced substrings, - PCRE gets a block of memory at the start of matching to use for this - purpose. If the call via pcre_malloc() fails, this error is given. The + PCRE gets a block of memory at the start of matching to use for this + purpose. If the call via pcre_malloc() fails, this error is given. The memory is automatically freed at the end of matching. - This error is also given if pcre_stack_malloc() fails in pcre_exec(). - This can happen only when PCRE has been compiled with --disable-stack- + This error is also given if pcre_stack_malloc() fails in pcre_exec(). + This can happen only when PCRE has been compiled with --disable-stack- for-recursion. PCRE_ERROR_NOSUBSTRING (-7) - This error is used by the pcre_copy_substring(), pcre_get_substring(), + This error is used by the pcre_copy_substring(), pcre_get_substring(), and pcre_get_substring_list() functions (see below). It is never returned by pcre_exec(). PCRE_ERROR_MATCHLIMIT (-8) - The backtracking limit, as specified by the match_limit field in a - pcre_extra structure (or defaulted) was reached. See the description + The backtracking limit, as specified by the match_limit field in a + pcre_extra structure (or defaulted) was reached. See the description above. PCRE_ERROR_CALLOUT (-9) This error is never generated by pcre_exec() itself. It is provided for - use by callout functions that want to yield a distinctive error code. + use by callout functions that want to yield a distinctive error code. See the pcrecallout documentation for details. PCRE_ERROR_BADUTF8 (-10) - A string that contains an invalid UTF-8 byte sequence was passed as a - subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of - the output vector (ovecsize) is at least 2, the byte offset to the - start of the the invalid UTF-8 character is placed in the first ele- - ment, and a reason code is placed in the second element. The reason + A string that contains an invalid UTF-8 byte sequence was passed as a + subject, and the PCRE_NO_UTF8_CHECK option was not set. If the size of + the output vector (ovecsize) is at least 2, the byte offset to the + start of the the invalid UTF-8 character is placed in the first ele- + ment, and a reason code is placed in the second element. The reason codes are listed in the following section. For backward compatibility, - if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char- - acter at the end of the subject (reason codes 1 to 5), + if PCRE_PARTIAL_HARD is set and the problem is a truncated UTF-8 char- + acter at the end of the subject (reason codes 1 to 5), PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8. PCRE_ERROR_BADUTF8_OFFSET (-11) - The UTF-8 byte sequence that was passed as a subject was checked and - found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the - value of startoffset did not point to the beginning of a UTF-8 charac- + The UTF-8 byte sequence that was passed as a subject was checked and + found to be valid (the PCRE_NO_UTF8_CHECK option was not set), but the + value of startoffset did not point to the beginning of a UTF-8 charac- ter or the end of the subject. PCRE_ERROR_PARTIAL (-12) - The subject string did not match, but it did match partially. See the + The subject string did not match, but it did match partially. See the pcrepartial documentation for details of partial matching. PCRE_ERROR_BADPARTIAL (-13) - This code is no longer in use. It was formerly returned when the - PCRE_PARTIAL option was used with a compiled pattern containing items - that were not supported for partial matching. From release 8.00 + This code is no longer in use. It was formerly returned when the + PCRE_PARTIAL option was used with a compiled pattern containing items + that were not supported for partial matching. From release 8.00 onwards, there are no restrictions on partial matching. PCRE_ERROR_INTERNAL (-14) - An unexpected internal error has occurred. This error could be caused + An unexpected internal error has occurred. This error could be caused by a bug in PCRE or by overwriting of the compiled pattern. PCRE_ERROR_BADCOUNT (-15) @@ -3707,7 +3706,7 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_ERROR_RECURSIONLIMIT (-21) The internal recursion limit, as specified by the match_limit_recursion - field in a pcre_extra structure (or defaulted) was reached. See the + field in a pcre_extra structure (or defaulted) was reached. See the description above. PCRE_ERROR_BADNEWLINE (-23) @@ -3721,29 +3720,29 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_ERROR_SHORTUTF8 (-25) - This error is returned instead of PCRE_ERROR_BADUTF8 when the subject - string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD - option is set. Information about the failure is returned as for - PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but - this special error code for PCRE_PARTIAL_HARD precedes the implementa- - tion of returned information; it is retained for backwards compatibil- + This error is returned instead of PCRE_ERROR_BADUTF8 when the subject + string ends with a truncated UTF-8 character and the PCRE_PARTIAL_HARD + option is set. Information about the failure is returned as for + PCRE_ERROR_BADUTF8. It is in fact sufficient to detect this case, but + this special error code for PCRE_PARTIAL_HARD precedes the implementa- + tion of returned information; it is retained for backwards compatibil- ity. PCRE_ERROR_RECURSELOOP (-26) This error is returned when pcre_exec() detects a recursion loop within - the pattern. Specifically, it means that either the whole pattern or a - subpattern has been called recursively for the second time at the same + the pattern. Specifically, it means that either the whole pattern or a + subpattern has been called recursively for the second time at the same position in the subject string. Some simple patterns that might do this - are detected and faulted at compile time, but more complicated cases, + are detected and faulted at compile time, but more complicated cases, in particular mutual recursions between two different subpatterns, can- not be detected until run time. PCRE_ERROR_JIT_STACKLIMIT (-27) - This error is returned when a pattern that was successfully studied - using a JIT compile option is being matched, but the memory available - for the just-in-time processing stack is not large enough. See the + This error is returned when a pattern that was successfully studied + using a JIT compile option is being matched, but the memory available + for the just-in-time processing stack is not large enough. See the pcrejit documentation for more details. PCRE_ERROR_BADMODE (-28) @@ -3753,38 +3752,38 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_ERROR_BADENDIANNESS (-29) - This error is given if a pattern that was compiled and saved is - reloaded on a host with different endianness. The utility function + This error is given if a pattern that was compiled and saved is + reloaded on a host with different endianness. The utility function pcre_pattern_to_host_byte_order() can be used to convert such a pattern so that it runs on the new host. PCRE_ERROR_JIT_BADOPTION - This error is returned when a pattern that was successfully studied - using a JIT compile option is being matched, but the matching mode - (partial or complete match) does not correspond to any JIT compilation - mode. When the JIT fast path function is used, this error may be also - given for invalid options. See the pcrejit documentation for more + This error is returned when a pattern that was successfully studied + using a JIT compile option is being matched, but the matching mode + (partial or complete match) does not correspond to any JIT compilation + mode. When the JIT fast path function is used, this error may be also + given for invalid options. See the pcrejit documentation for more details. PCRE_ERROR_BADLENGTH (-32) - This error is given if pcre_exec() is called with a negative value for + This error is given if pcre_exec() is called with a negative value for the length argument. Error numbers -16 to -20, -22, and 30 are not used by pcre_exec(). Reason codes for invalid UTF-8 strings - This section applies only to the 8-bit library. The corresponding - information for the 16-bit and 32-bit libraries is given in the pcre16 + This section applies only to the 8-bit library. The corresponding + information for the 16-bit and 32-bit libraries is given in the pcre16 and pcre32 pages. When pcre_exec() returns either PCRE_ERROR_BADUTF8 or PCRE_ERROR_SHORT- - UTF8, and the size of the output vector (ovecsize) is at least 2, the - offset of the start of the invalid UTF-8 character is placed in the + UTF8, and the size of the output vector (ovecsize) is at least 2, the + offset of the start of the invalid UTF-8 character is placed in the first output vector element (ovector[0]) and a reason code is placed in - the second element (ovector[1]). The reason codes are given names in + the second element (ovector[1]). The reason codes are given names in the pcre.h header file: PCRE_UTF8_ERR1 @@ -3793,10 +3792,10 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_UTF8_ERR4 PCRE_UTF8_ERR5 - The string ends with a truncated UTF-8 character; the code specifies - how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 - characters to be no longer than 4 bytes, the encoding scheme (origi- - nally defined by RFC 2279) allows for up to 6 bytes, and this is + The string ends with a truncated UTF-8 character; the code specifies + how many bytes are missing (1 to 5). Although RFC 3629 restricts UTF-8 + characters to be no longer than 4 bytes, the encoding scheme (origi- + nally defined by RFC 2279) allows for up to 6 bytes, and this is checked first; hence the possibility of 4 or 5 missing bytes. PCRE_UTF8_ERR6 @@ -3806,24 +3805,24 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_UTF8_ERR10 The two most significant bits of the 2nd, 3rd, 4th, 5th, or 6th byte of - the character do not have the binary value 0b10 (that is, either the + the character do not have the binary value 0b10 (that is, either the most significant bit is 0, or the next bit is 1). PCRE_UTF8_ERR11 PCRE_UTF8_ERR12 - A character that is valid by the RFC 2279 rules is either 5 or 6 bytes + A character that is valid by the RFC 2279 rules is either 5 or 6 bytes long; these code points are excluded by RFC 3629. PCRE_UTF8_ERR13 - A 4-byte character has a value greater than 0x10fff; these code points + A 4-byte character has a value greater than 0x10fff; these code points are excluded by RFC 3629. PCRE_UTF8_ERR14 - A 3-byte character has a value in the range 0xd800 to 0xdfff; this - range of code points are reserved by RFC 3629 for use with UTF-16, and + A 3-byte character has a value in the range 0xd800 to 0xdfff; this + range of code points are reserved by RFC 3629 for use with UTF-16, and so are excluded from UTF-8. PCRE_UTF8_ERR15 @@ -3832,28 +3831,28 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION PCRE_UTF8_ERR18 PCRE_UTF8_ERR19 - A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes - for a value that can be represented by fewer bytes, which is invalid. - For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor- + A 2-, 3-, 4-, 5-, or 6-byte character is "overlong", that is, it codes + for a value that can be represented by fewer bytes, which is invalid. + For example, the two bytes 0xc0, 0xae give the value 0x2e, whose cor- rect coding uses just one byte. PCRE_UTF8_ERR20 The two most significant bits of the first byte of a character have the - binary value 0b10 (that is, the most significant bit is 1 and the sec- - ond is 0). Such a byte can only validly occur as the second or subse- + binary value 0b10 (that is, the most significant bit is 1 and the sec- + ond is 0). Such a byte can only validly occur as the second or subse- quent byte of a multi-byte character. PCRE_UTF8_ERR21 - The first byte of a character has the value 0xfe or 0xff. These values + The first byte of a character has the value 0xfe or 0xff. These values can never occur in a valid UTF-8 string. PCRE_UTF8_ERR22 - This error code was formerly used when the presence of a so-called - "non-character" caused an error. Unicode corrigendum #9 makes it clear - that such characters should not cause a string to be rejected, and so + This error code was formerly used when the presence of a so-called + "non-character" caused an error. Unicode corrigendum #9 makes it clear + that such characters should not cause a string to be rejected, and so this code is no longer in use and is never returned. @@ -3870,78 +3869,78 @@ EXTRACTING CAPTURED SUBSTRINGS BY NUMBER int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr); - Captured substrings can be accessed directly by using the offsets - returned by pcre_exec() in ovector. For convenience, the functions + Captured substrings can be accessed directly by using the offsets + returned by pcre_exec() in ovector. For convenience, the functions pcre_copy_substring(), pcre_get_substring(), and pcre_get_sub- - string_list() are provided for extracting captured substrings as new, - separate, zero-terminated strings. These functions identify substrings - by number. The next section describes functions for extracting named + string_list() are provided for extracting captured substrings as new, + separate, zero-terminated strings. These functions identify substrings + by number. The next section describes functions for extracting named substrings. - A substring that contains a binary zero is correctly extracted and has - a further zero added on the end, but the result is not, of course, a C - string. However, you can process such a string by referring to the - length that is returned by pcre_copy_substring() and pcre_get_sub- + A substring that contains a binary zero is correctly extracted and has + a further zero added on the end, but the result is not, of course, a C + string. However, you can process such a string by referring to the + length that is returned by pcre_copy_substring() and pcre_get_sub- string(). Unfortunately, the interface to pcre_get_substring_list() is - not adequate for handling strings containing binary zeros, because the + not adequate for handling strings containing binary zeros, because the end of the final string is not independently indicated. - The first three arguments are the same for all three of these func- - tions: subject is the subject string that has just been successfully + The first three arguments are the same for all three of these func- + tions: subject is the subject string that has just been successfully matched, ovector is a pointer to the vector of integer offsets that was passed to pcre_exec(), and stringcount is the number of substrings that - were captured by the match, including the substring that matched the + were captured by the match, including the substring that matched the entire regular expression. This is the value returned by pcre_exec() if - it is greater than zero. If pcre_exec() returned zero, indicating that - it ran out of space in ovector, the value passed as stringcount should + it is greater than zero. If pcre_exec() returned zero, indicating that + it ran out of space in ovector, the value passed as stringcount should be the number of elements in the vector divided by three. - The functions pcre_copy_substring() and pcre_get_substring() extract a - single substring, whose number is given as stringnumber. A value of - zero extracts the substring that matched the entire pattern, whereas - higher values extract the captured substrings. For pcre_copy_sub- - string(), the string is placed in buffer, whose length is given by - buffersize, while for pcre_get_substring() a new block of memory is - obtained via pcre_malloc, and its address is returned via stringptr. - The yield of the function is the length of the string, not including + The functions pcre_copy_substring() and pcre_get_substring() extract a + single substring, whose number is given as stringnumber. A value of + zero extracts the substring that matched the entire pattern, whereas + higher values extract the captured substrings. For pcre_copy_sub- + string(), the string is placed in buffer, whose length is given by + buffersize, while for pcre_get_substring() a new block of memory is + obtained via pcre_malloc, and its address is returned via stringptr. + The yield of the function is the length of the string, not including the terminating zero, or one of these error codes: PCRE_ERROR_NOMEMORY (-6) - The buffer was too small for pcre_copy_substring(), or the attempt to + The buffer was too small for pcre_copy_substring(), or the attempt to get memory failed for pcre_get_substring(). PCRE_ERROR_NOSUBSTRING (-7) There is no substring whose number is stringnumber. - The pcre_get_substring_list() function extracts all available sub- - strings and builds a list of pointers to them. All this is done in a + The pcre_get_substring_list() function extracts all available sub- + strings and builds a list of pointers to them. All this is done in a single block of memory that is obtained via pcre_malloc. The address of - the memory block is returned via listptr, which is also the start of - the list of string pointers. The end of the list is marked by a NULL - pointer. The yield of the function is zero if all went well, or the + the memory block is returned via listptr, which is also the start of + the list of string pointers. The end of the list is marked by a NULL + pointer. The yield of the function is zero if all went well, or the error code PCRE_ERROR_NOMEMORY (-6) if the attempt to get the memory block failed. - When any of these functions encounter a substring that is unset, which - can happen when capturing subpattern number n+1 matches some part of - the subject, but subpattern n has not been used at all, they return an + When any of these functions encounter a substring that is unset, which + can happen when capturing subpattern number n+1 matches some part of + the subject, but subpattern n has not been used at all, they return an empty string. This can be distinguished from a genuine zero-length sub- - string by inspecting the appropriate offset in ovector, which is nega- + string by inspecting the appropriate offset in ovector, which is nega- tive for unset substrings. - The two convenience functions pcre_free_substring() and pcre_free_sub- - string_list() can be used to free the memory returned by a previous + The two convenience functions pcre_free_substring() and pcre_free_sub- + string_list() can be used to free the memory returned by a previous call of pcre_get_substring() or pcre_get_substring_list(), respec- - tively. They do nothing more than call the function pointed to by - pcre_free, which of course could be called directly from a C program. - However, PCRE is used in some situations where it is linked via a spe- - cial interface to another programming language that cannot use - pcre_free directly; it is for these cases that the functions are pro- + tively. They do nothing more than call the function pointed to by + pcre_free, which of course could be called directly from a C program. + However, PCRE is used in some situations where it is linked via a spe- + cial interface to another programming language that cannot use + pcre_free directly; it is for these cases that the functions are pro- vided. @@ -3960,7 +3959,7 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME int stringcount, const char *stringname, const char **stringptr); - To extract a substring by name, you first have to find associated num- + To extract a substring by name, you first have to find associated num- ber. For example, for this pattern (a+)b(?\d+)... @@ -3969,35 +3968,35 @@ EXTRACTING CAPTURED SUBSTRINGS BY NAME be unique (PCRE_DUPNAMES was not set), you can find the number from the name by calling pcre_get_stringnumber(). The first argument is the com- piled pattern, and the second is the name. The yield of the function is - the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no + the subpattern number, or PCRE_ERROR_NOSUBSTRING (-7) if there is no subpattern of that name. Given the number, you can extract the substring directly, or use one of the functions described in the previous section. For convenience, there are also two functions that do the whole job. - Most of the arguments of pcre_copy_named_substring() and - pcre_get_named_substring() are the same as those for the similarly - named functions that extract by number. As these are described in the - previous section, they are not re-described here. There are just two + Most of the arguments of pcre_copy_named_substring() and + pcre_get_named_substring() are the same as those for the similarly + named functions that extract by number. As these are described in the + previous section, they are not re-described here. There are just two differences: - First, instead of a substring number, a substring name is given. Sec- + First, instead of a substring number, a substring name is given. Sec- ond, there is an extra argument, given at the start, which is a pointer - to the compiled pattern. This is needed in order to gain access to the + to the compiled pattern. This is needed in order to gain access to the name-to-number translation table. - These functions call pcre_get_stringnumber(), and if it succeeds, they - then call pcre_copy_substring() or pcre_get_substring(), as appropri- - ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the + These functions call pcre_get_stringnumber(), and if it succeeds, they + then call pcre_copy_substring() or pcre_get_substring(), as appropri- + ate. NOTE: If PCRE_DUPNAMES is set and there are duplicate names, the behaviour may not be what you want (see the next section). Warning: If the pattern uses the (?| feature to set up multiple subpat- - terns with the same number, as described in the section on duplicate - subpattern numbers in the pcrepattern page, you cannot use names to - distinguish the different subpatterns, because names are not included - in the compiled code. The matching process uses only numbers. For this - reason, the use of different names for subpatterns of the same number + terns with the same number, as described in the section on duplicate + subpattern numbers in the pcrepattern page, you cannot use names to + distinguish the different subpatterns, because names are not included + in the compiled code. The matching process uses only numbers. For this + reason, the use of different names for subpatterns of the same number causes an error at compile time. @@ -4006,76 +4005,76 @@ DUPLICATE SUBPATTERN NAMES int pcre_get_stringtable_entries(const pcre *code, const char *name, char **first, char **last); - When a pattern is compiled with the PCRE_DUPNAMES option, names for - subpatterns are not required to be unique. (Duplicate names are always - allowed for subpatterns with the same number, created by using the (?| - feature. Indeed, if such subpatterns are named, they are required to + When a pattern is compiled with the PCRE_DUPNAMES option, names for + subpatterns are not required to be unique. (Duplicate names are always + allowed for subpatterns with the same number, created by using the (?| + feature. Indeed, if such subpatterns are named, they are required to use the same names.) Normally, patterns with duplicate names are such that in any one match, - only one of the named subpatterns participates. An example is shown in + only one of the named subpatterns participates. An example is shown in the pcrepattern documentation. - When duplicates are present, pcre_copy_named_substring() and - pcre_get_named_substring() return the first substring corresponding to - the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING - (-7) is returned; no data is returned. The pcre_get_stringnumber() - function returns one of the numbers that are associated with the name, + When duplicates are present, pcre_copy_named_substring() and + pcre_get_named_substring() return the first substring corresponding to + the given name that is set. If none are set, PCRE_ERROR_NOSUBSTRING + (-7) is returned; no data is returned. The pcre_get_stringnumber() + function returns one of the numbers that are associated with the name, but it is not defined which it is. - If you want to get full details of all captured substrings for a given - name, you must use the pcre_get_stringtable_entries() function. The + If you want to get full details of all captured substrings for a given + name, you must use the pcre_get_stringtable_entries() function. The first argument is the compiled pattern, and the second is the name. The - third and fourth are pointers to variables which are updated by the + third and fourth are pointers to variables which are updated by the function. After it has run, they point to the first and last entries in - the name-to-number table for the given name. The function itself - returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if - there are none. The format of the table is described above in the sec- - tion entitled Information about a pattern above. Given all the rele- - vant entries for the name, you can extract each of their numbers, and + the name-to-number table for the given name. The function itself + returns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if + there are none. The format of the table is described above in the sec- + tion entitled Information about a pattern above. Given all the rele- + vant entries for the name, you can extract each of their numbers, and hence the captured data, if any. FINDING ALL POSSIBLE MATCHES - The traditional matching function uses a similar algorithm to Perl, + The traditional matching function uses a similar algorithm to Perl, which stops when it finds the first match, starting at a given point in - the subject. If you want to find all possible matches, or the longest - possible match, consider using the alternative matching function (see - below) instead. If you cannot use the alternative function, but still - need to find all possible matches, you can kludge it up by making use + the subject. If you want to find all possible matches, or the longest + possible match, consider using the alternative matching function (see + below) instead. If you cannot use the alternative function, but still + need to find all possible matches, you can kludge it up by making use of the callout facility, which is described in the pcrecallout documen- tation. What you have to do is to insert a callout right at the end of the pat- - tern. When your callout function is called, extract and save the cur- - rent matched substring. Then return 1, which forces pcre_exec() to - backtrack and try other alternatives. Ultimately, when it runs out of + tern. When your callout function is called, extract and save the cur- + rent matched substring. Then return 1, which forces pcre_exec() to + backtrack and try other alternatives. Ultimately, when it runs out of matches, pcre_exec() will yield PCRE_ERROR_NOMATCH. OBTAINING AN ESTIMATE OF STACK USAGE - Matching certain patterns using pcre_exec() can use a lot of process - stack, which in certain environments can be rather limited in size. - Some users find it helpful to have an estimate of the amount of stack - that is used by pcre_exec(), to help them set recursion limits, as - described in the pcrestack documentation. The estimate that is output + Matching certain patterns using pcre_exec() can use a lot of process + stack, which in certain environments can be rather limited in size. + Some users find it helpful to have an estimate of the amount of stack + that is used by pcre_exec(), to help them set recursion limits, as + described in the pcrestack documentation. The estimate that is output by pcretest when called with the -m and -C options is obtained by call- - ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its + ing pcre_exec with the values NULL, NULL, NULL, -999, and -999 for its first five arguments. - Normally, if its first argument is NULL, pcre_exec() immediately - returns the negative error code PCRE_ERROR_NULL, but with this special - combination of arguments, it returns instead a negative number whose - absolute value is the approximate stack frame size in bytes. (A nega- - tive number is used so that it is clear that no match has happened.) - The value is approximate because in some cases, recursive calls to + Normally, if its first argument is NULL, pcre_exec() immediately + returns the negative error code PCRE_ERROR_NULL, but with this special + combination of arguments, it returns instead a negative number whose + absolute value is the approximate stack frame size in bytes. (A nega- + tive number is used so that it is clear that no match has happened.) + The value is approximate because in some cases, recursive calls to pcre_exec() occur when there are one or two additional variables on the stack. - If PCRE has been compiled to use the heap instead of the stack for - recursion, the value returned is the size of each block that is + If PCRE has been compiled to use the heap instead of the stack for + recursion, the value returned is the size of each block that is obtained from the heap. @@ -4086,26 +4085,26 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION int options, int *ovector, int ovecsize, int *workspace, int wscount); - The function pcre_dfa_exec() is called to match a subject string - against a compiled pattern, using a matching algorithm that scans the - subject string just once, and does not backtrack. This has different - characteristics to the normal algorithm, and is not compatible with - Perl. Some of the features of PCRE patterns are not supported. Never- - theless, there are times when this kind of matching can be useful. For - a discussion of the two matching algorithms, and a list of features - that pcre_dfa_exec() does not support, see the pcrematching documenta- + The function pcre_dfa_exec() is called to match a subject string + against a compiled pattern, using a matching algorithm that scans the + subject string just once, and does not backtrack. This has different + characteristics to the normal algorithm, and is not compatible with + Perl. Some of the features of PCRE patterns are not supported. Never- + theless, there are times when this kind of matching can be useful. For + a discussion of the two matching algorithms, and a list of features + that pcre_dfa_exec() does not support, see the pcrematching documenta- tion. - The arguments for the pcre_dfa_exec() function are the same as for + The arguments for the pcre_dfa_exec() function are the same as for pcre_exec(), plus two extras. The ovector argument is used in a differ- - ent way, and this is described below. The other common arguments are - used in the same way as for pcre_exec(), so their description is not + ent way, and this is described below. The other common arguments are + used in the same way as for pcre_exec(), so their description is not repeated here. - The two additional arguments provide workspace for the function. The - workspace vector should contain at least 20 elements. It is used for + The two additional arguments provide workspace for the function. The + workspace vector should contain at least 20 elements. It is used for keeping track of multiple paths through the pattern tree. More - workspace will be needed for patterns and subjects where there are a + workspace will be needed for patterns and subjects where there are a lot of potential matches. Here is an example of a simple call to pcre_dfa_exec(): @@ -4127,55 +4126,55 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION Option bits for pcre_dfa_exec() - The unused bits of the options argument for pcre_dfa_exec() must be - zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- + The unused bits of the options argument for pcre_dfa_exec() must be + zero. The only bits that may be set are PCRE_ANCHORED, PCRE_NEW- LINE_xxx, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, - PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, - PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- - TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last - four of these are exactly the same as for pcre_exec(), so their + PCRE_NOTEMPTY_ATSTART, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, + PCRE_BSR_UNICODE, PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PAR- + TIAL_SOFT, PCRE_DFA_SHORTEST, and PCRE_DFA_RESTART. All but the last + four of these are exactly the same as for pcre_exec(), so their description is not repeated here. PCRE_PARTIAL_HARD PCRE_PARTIAL_SOFT - These have the same general effect as they do for pcre_exec(), but the - details are slightly different. When PCRE_PARTIAL_HARD is set for - pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- - ject is reached and there is still at least one matching possibility + These have the same general effect as they do for pcre_exec(), but the + details are slightly different. When PCRE_PARTIAL_HARD is set for + pcre_dfa_exec(), it returns PCRE_ERROR_PARTIAL if the end of the sub- + ject is reached and there is still at least one matching possibility that requires additional characters. This happens even if some complete matches have also been found. When PCRE_PARTIAL_SOFT is set, the return code PCRE_ERROR_NOMATCH is converted into PCRE_ERROR_PARTIAL if the end - of the subject is reached, there have been no complete matches, but - there is still at least one matching possibility. The portion of the - string that was inspected when the longest partial match was found is - set as the first matching string in both cases. There is a more - detailed discussion of partial and multi-segment matching, with exam- + of the subject is reached, there have been no complete matches, but + there is still at least one matching possibility. The portion of the + string that was inspected when the longest partial match was found is + set as the first matching string in both cases. There is a more + detailed discussion of partial and multi-segment matching, with exam- ples, in the pcrepartial documentation. PCRE_DFA_SHORTEST - Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to + Setting the PCRE_DFA_SHORTEST option causes the matching algorithm to stop as soon as it has found one match. Because of the way the alterna- - tive algorithm works, this is necessarily the shortest possible match + tive algorithm works, this is necessarily the shortest possible match at the first possible matching point in the subject string. PCRE_DFA_RESTART When pcre_dfa_exec() returns a partial match, it is possible to call it - again, with additional subject characters, and have it continue with - the same match. The PCRE_DFA_RESTART option requests this action; when - it is set, the workspace and wscount options must reference the same - vector as before because data about the match so far is left in them + again, with additional subject characters, and have it continue with + the same match. The PCRE_DFA_RESTART option requests this action; when + it is set, the workspace and wscount options must reference the same + vector as before because data about the match so far is left in them after a partial match. There is more discussion of this facility in the pcrepartial documentation. Successful returns from pcre_dfa_exec() - When pcre_dfa_exec() succeeds, it may have matched more than one sub- + When pcre_dfa_exec() succeeds, it may have matched more than one sub- string in the subject. Note, however, that all the matches from one run - of the function start at the same point in the subject. The shorter - matches are all initial substrings of the longer matches. For example, + of the function start at the same point in the subject. The shorter + matches are all initial substrings of the longer matches. For example, if the pattern <.*> @@ -4190,79 +4189,79 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION - On success, the yield of the function is a number greater than zero, - which is the number of matched substrings. The substrings themselves - are returned in ovector. Each string uses two elements; the first is - the offset to the start, and the second is the offset to the end. In - fact, all the strings have the same start offset. (Space could have - been saved by giving this only once, but it was decided to retain some - compatibility with the way pcre_exec() returns data, even though the + On success, the yield of the function is a number greater than zero, + which is the number of matched substrings. The substrings themselves + are returned in ovector. Each string uses two elements; the first is + the offset to the start, and the second is the offset to the end. In + fact, all the strings have the same start offset. (Space could have + been saved by giving this only once, but it was decided to retain some + compatibility with the way pcre_exec() returns data, even though the meaning of the strings is different.) The strings are returned in reverse order of length; that is, the long- - est matching string is given first. If there were too many matches to - fit into ovector, the yield of the function is zero, and the vector is - filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec() + est matching string is given first. If there were too many matches to + fit into ovector, the yield of the function is zero, and the vector is + filled with the longest matches. Unlike pcre_exec(), pcre_dfa_exec() can use the entire ovector for returning matched strings. - NOTE: PCRE's "auto-possessification" optimization usually applies to - character repeats at the end of a pattern (as well as internally). For - example, the pattern "a\d+" is compiled as if it were "a\d++" because + NOTE: PCRE's "auto-possessification" optimization usually applies to + character repeats at the end of a pattern (as well as internally). For + example, the pattern "a\d+" is compiled as if it were "a\d++" because there is no point even considering the possibility of backtracking into - the repeated digits. For DFA matching, this means that only one possi- - ble match is found. If you really do want multiple matches in such - cases, either use an ungreedy repeat ("a\d+?") or set the + the repeated digits. For DFA matching, this means that only one possi- + ble match is found. If you really do want multiple matches in such + cases, either use an ungreedy repeat ("a\d+?") or set the PCRE_NO_AUTO_POSSESS option when compiling. Error returns from pcre_dfa_exec() - The pcre_dfa_exec() function returns a negative number when it fails. - Many of the errors are the same as for pcre_exec(), and these are - described above. There are in addition the following errors that are + The pcre_dfa_exec() function returns a negative number when it fails. + Many of the errors are the same as for pcre_exec(), and these are + described above. There are in addition the following errors that are specific to pcre_dfa_exec(): PCRE_ERROR_DFA_UITEM (-16) - This return is given if pcre_dfa_exec() encounters an item in the pat- - tern that it does not support, for instance, the use of \C or a back + This return is given if pcre_dfa_exec() encounters an item in the pat- + tern that it does not support, for instance, the use of \C or a back reference. PCRE_ERROR_DFA_UCOND (-17) - This return is given if pcre_dfa_exec() encounters a condition item - that uses a back reference for the condition, or a test for recursion + This return is given if pcre_dfa_exec() encounters a condition item + that uses a back reference for the condition, or a test for recursion in a specific group. These are not supported. PCRE_ERROR_DFA_UMLIMIT (-18) - This return is given if pcre_dfa_exec() is called with an extra block - that contains a setting of the match_limit or match_limit_recursion - fields. This is not supported (these fields are meaningless for DFA + This return is given if pcre_dfa_exec() is called with an extra block + that contains a setting of the match_limit or match_limit_recursion + fields. This is not supported (these fields are meaningless for DFA matching). PCRE_ERROR_DFA_WSSIZE (-19) - This return is given if pcre_dfa_exec() runs out of space in the + This return is given if pcre_dfa_exec() runs out of space in the workspace vector. PCRE_ERROR_DFA_RECURSE (-20) - When a recursive subpattern is processed, the matching function calls - itself recursively, using private vectors for ovector and workspace. - This error is given if the output vector is not large enough. This + When a recursive subpattern is processed, the matching function calls + itself recursively, using private vectors for ovector and workspace. + This error is given if the output vector is not large enough. This should be extremely rare, as a vector of size 1000 is used. PCRE_ERROR_DFA_BADRESTART (-30) - When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some - plausibility checks are made on the contents of the workspace, which - should contain data about the previous partial match. If any of these + When pcre_dfa_exec() is called with the PCRE_DFA_RESTART option, some + plausibility checks are made on the contents of the workspace, which + should contain data about the previous partial match. If any of these checks fail, this error is given. SEE ALSO - pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), + pcre16(3), pcre32(3), pcrebuild(3), pcrecallout(3), pcrecpp(3)(3), pcrematching(3), pcrepartial(3), pcreposix(3), pcreprecompile(3), pcre- sample(3), pcrestack(3). @@ -4276,8 +4275,8 @@ AUTHOR REVISION - Last updated: 09 February 2014 - Copyright (c) 1997-2014 University of Cambridge. + Last updated: 18 December 2015 + Copyright (c) 1997-2015 University of Cambridge. ------------------------------------------------------------------------------ diff --git a/pcre/doc/pcreapi.3 b/pcre/doc/pcreapi.3 index ab3eaa0b52162..6e7c7c6e3ce8f 100644 --- a/pcre/doc/pcreapi.3 +++ b/pcre/doc/pcreapi.3 @@ -1,4 +1,4 @@ -.TH PCREAPI 3 "09 February 2014" "PCRE 8.35" +.TH PCREAPI 3 "18 December 2015" "PCRE 8.39" .SH NAME PCRE - Perl-compatible regular expressions .sp @@ -273,9 +273,8 @@ documentation for details of how to do this. It is a non-standard way of building PCRE, for use in environments that have limited stacks. Because of the greater use of memory management, it runs more slowly. Separate functions are provided so that special-purpose external code can be used for this case. When -used, these functions are always called in a stack-like manner (last obtained, -first freed), and always for memory blocks of the same size. There is a -discussion about PCRE's stack usage in the +used, these functions always allocate memory blocks of the same size. There is +a discussion about PCRE's stack usage in the .\" HREF \fBpcrestack\fP .\" @@ -2914,6 +2913,6 @@ Cambridge CB2 3QH, England. .rs .sp .nf -Last updated: 09 February 2014 -Copyright (c) 1997-2014 University of Cambridge. +Last updated: 18 December 2015 +Copyright (c) 1997-2015 University of Cambridge. .fi diff --git a/pcre/pcre.h.generic b/pcre/pcre.h.generic index bf6351f8837b4..7055970065415 100644 --- a/pcre/pcre.h.generic +++ b/pcre/pcre.h.generic @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 38 +#define PCRE_MINOR 39 #define PCRE_PRERELEASE -#define PCRE_DATE 2015-11-23 +#define PCRE_DATE 2016-06-14 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate diff --git a/pcre/pcre_compile.c b/pcre/pcre_compile.c index 4d3b3139dea1f..7cd395012304e 100644 --- a/pcre/pcre_compile.c +++ b/pcre/pcre_compile.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2014 University of Cambridge + Copyright (c) 1997-2016 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -485,7 +485,7 @@ static const char error_texts[] = "lookbehind assertion is not fixed length\0" "malformed number or name after (?(\0" "conditional group contains more than two branches\0" - "assertion expected after (?(\0" + "assertion expected after (?( or (?(?C)\0" "(?R or (?[+-]digits must be followed by )\0" /* 30 */ "unknown POSIX class name\0" @@ -560,6 +560,7 @@ static const char error_texts[] = /* 85 */ "parentheses are too deeply nested (stack check)\0" "digits missing in \\x{} or \\o{}\0" + "regular expression is too complicated\0" ; /* Table to identify digits and hex digits. This is used when compiling @@ -4566,6 +4567,10 @@ for (;; ptr++) pcre_uint32 ec; pcre_uchar mcbuffer[8]; + /* Come here to restart the loop without advancing the pointer. */ + + REDO_LOOP: + /* Get next character in the pattern */ c = *ptr; @@ -4591,7 +4596,8 @@ for (;; ptr++) if (code > cd->start_workspace + cd->workspace_size - WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */ { - *errorcodeptr = ERR52; + *errorcodeptr = (code >= cd->start_workspace + cd->workspace_size)? + ERR52 : ERR87; goto FAILED; } @@ -4645,9 +4651,10 @@ for (;; ptr++) goto FAILED; } - /* If in \Q...\E, check for the end; if not, we have a literal */ + /* If in \Q...\E, check for the end; if not, we have a literal. Otherwise an + isolated \E is ignored. */ - if (inescq && c != CHAR_NULL) + if (c != CHAR_NULL) { if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) { @@ -4655,7 +4662,7 @@ for (;; ptr++) ptr++; continue; } - else + else if (inescq) { if (previous_callout != NULL) { @@ -4670,18 +4677,27 @@ for (;; ptr++) } goto NORMAL_CHAR; } - /* Control does not reach here. */ + + /* Check for the start of a \Q...\E sequence. We must do this here rather + than later in case it is immediately followed by \E, which turns it into a + "do nothing" sequence. */ + + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_Q) + { + inescq = TRUE; + ptr++; + continue; + } } - /* In extended mode, skip white space and comments. We need a loop in order - to check for more white space and more comments after a comment. */ + /* In extended mode, skip white space and comments. */ if ((options & PCRE_EXTENDED) != 0) { - for (;;) + const pcre_uchar *wscptr = ptr; + while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr); + if (c == CHAR_NUMBER_SIGN) { - while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr); - if (c != CHAR_NUMBER_SIGN) break; ptr++; while (*ptr != CHAR_NULL) { @@ -4695,8 +4711,29 @@ for (;; ptr++) if (utf) FORWARDCHAR(ptr); #endif } - c = *ptr; /* Either NULL or the char after a newline */ } + + /* If we skipped any characters, restart the loop. Otherwise, we didn't see + a comment. */ + + if (ptr > wscptr) goto REDO_LOOP; + } + + /* Skip over (?# comments. We need to do this here because we want to know if + the next thing is a quantifier, and these comments may come between an item + and its quantifier. */ + + if (c == CHAR_LEFT_PARENTHESIS && ptr[1] == CHAR_QUESTION_MARK && + ptr[2] == CHAR_NUMBER_SIGN) + { + ptr += 3; + while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr == CHAR_NULL) + { + *errorcodeptr = ERR18; + goto FAILED; + } + continue; } /* See if the next thing is a quantifier. */ @@ -4820,15 +4857,15 @@ for (;; ptr++) if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_STARTWORD, 6) == 0) { nestptr = ptr + 7; - ptr = sub_start_of_word - 1; - continue; + ptr = sub_start_of_word; + goto REDO_LOOP; } if (STRNCMP_UC_C8(ptr+1, STRING_WEIRD_ENDWORD, 6) == 0) { nestptr = ptr + 7; - ptr = sub_end_of_word - 1; - continue; + ptr = sub_end_of_word; + goto REDO_LOOP; } /* Handle a real character class. */ @@ -5046,20 +5083,22 @@ for (;; ptr++) ptr = tempptr + 1; continue; - /* For the other POSIX classes (ascii, xdigit) we are going to fall - through to the non-UCP case and build a bit map for characters with - code points less than 256. If we are in a negated POSIX class - within a non-negated overall class, characters with code points - greater than 255 must all match. In the special case where we have - not yet generated any xclass data, and this is the final item in - the overall class, we need do nothing: later on, the opcode + /* For the other POSIX classes (ascii, cntrl, xdigit) we are going + to fall through to the non-UCP case and build a bit map for + characters with code points less than 256. If we are in a negated + POSIX class, characters with code points greater than 255 must + either all match or all not match. In the special case where we + have not yet generated any xclass data, and this is the final item + in the overall class, we need do nothing: later on, the opcode OP_NCLASS will be used to indicate that characters greater than 255 are acceptable. If we have already seen an xclass item or one may follow (we have to assume that it might if this is not the end of - the class), explicitly match all wide codepoints. */ + the class), explicitly list all wide codepoints, which will then + either not match or match, depending on whether the class is or is + not negated. */ default: - if (!negate_class && local_negate && + if (local_negate && (xclass || tempptr[2] != CHAR_RIGHT_SQUARE_BRACKET)) { *class_uchardata++ = XCL_RANGE; @@ -6529,21 +6568,6 @@ for (;; ptr++) case CHAR_LEFT_PARENTHESIS: ptr++; - /* First deal with comments. Putting this code right at the start ensures - that comments have no bad side effects. */ - - if (ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN) - { - ptr += 2; - while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; - if (*ptr == CHAR_NULL) - { - *errorcodeptr = ERR18; - goto FAILED; - } - continue; - } - /* Now deal with various "verbs" that can be introduced by '*'. */ if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' @@ -6604,8 +6628,21 @@ for (;; ptr++) cd->had_accept = TRUE; for (oc = cd->open_caps; oc != NULL; oc = oc->next) { - *code++ = OP_CLOSE; - PUT2INC(code, 0, oc->number); + if (lengthptr != NULL) + { +#ifdef COMPILE_PCRE8 + *lengthptr += 1 + IMM2_SIZE; +#elif defined COMPILE_PCRE16 + *lengthptr += 2 + IMM2_SIZE; +#elif defined COMPILE_PCRE32 + *lengthptr += 4 + IMM2_SIZE; +#endif + } + else + { + *code++ = OP_CLOSE; + PUT2INC(code, 0, oc->number); + } } setverb = *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; @@ -6734,6 +6771,15 @@ for (;; ptr++) for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break; if (ptr[i] == CHAR_RIGHT_PARENTHESIS) tempptr += i + 1; + + /* tempptr should now be pointing to the opening parenthesis of the + assertion condition. */ + + if (*tempptr != CHAR_LEFT_PARENTHESIS) + { + *errorcodeptr = ERR28; + goto FAILED; + } } /* For conditions that are assertions, check the syntax, and then exit @@ -7258,7 +7304,7 @@ for (;; ptr++) issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance only mode, we finesse the bug by allowing more memory always. */ - *lengthptr += 2 + 2*LINK_SIZE; + *lengthptr += 4 + 4*LINK_SIZE; /* It is even worse than that. The current reference may be to an existing named group with a different number (so apparently not @@ -7274,7 +7320,12 @@ for (;; ptr++) so far in order to get the number. If the name is not found, leave the value of recno as 0 for a forward reference. */ - else + /* This patch (removing "else") fixes a problem when a reference is + to multiple identically named nested groups from within the nest. + Once again, it is not the "proper" fix, and it results in an + over-allocation of memory. */ + + /* else */ { ng = cd->named_groups; for (i = 0; i < cd->names_found; i++, ng++) @@ -7585,39 +7636,15 @@ for (;; ptr++) newoptions = (options | set) & (~unset); /* If the options ended with ')' this is not the start of a nested - group with option changes, so the options change at this level. If this - item is right at the start of the pattern, the options can be - abstracted and made external in the pre-compile phase, and ignored in - the compile phase. This can be helpful when matching -- for instance in - caseless checking of required bytes. - - If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are - definitely *not* at the start of the pattern because something has been - compiled. In the pre-compile phase, however, the code pointer can have - that value after the start, because it gets reset as code is discarded - during the pre-compile. However, this can happen only at top level - if - we are within parentheses, the starting BRA will still be present. At - any parenthesis level, the length value can be used to test if anything - has been compiled at that level. Thus, a test for both these conditions - is necessary to ensure we correctly detect the start of the pattern in - both phases. - + group with option changes, so the options change at this level. If we are not at the pattern start, reset the greedy defaults and the case value for firstchar and reqchar. */ if (*ptr == CHAR_RIGHT_PARENTHESIS) { - if (code == cd->start_code + 1 + LINK_SIZE && - (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE)) - { - cd->external_options = newoptions; - } - else - { - greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); - greedy_non_default = greedy_default ^ 1; - req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; - } + greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); + greedy_non_default = greedy_default ^ 1; + req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; /* Change options at this level, and pass them back for use in subsequent branches. */ @@ -7896,16 +7923,6 @@ for (;; ptr++) c = ec; else { - if (escape == ESC_Q) /* Handle start of quoted string */ - { - if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) - ptr += 2; /* avoid empty string */ - else inescq = TRUE; - continue; - } - - if (escape == ESC_E) continue; /* Perl ignores an orphan \E */ - /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ diff --git a/pcre/pcre_get.c b/pcre/pcre_get.c index 8094b34bbfb77..9475d5e88cdcc 100644 --- a/pcre/pcre_get.c +++ b/pcre/pcre_get.c @@ -250,6 +250,7 @@ It returns the number of the first one that was set in a pattern match. code the compiled regex stringname the name of the capturing substring ovector the vector of matched substrings + stringcount number of captured substrings Returns: the number of the first that is set, or the number of the last one if none are set, @@ -258,13 +259,16 @@ Returns: the number of the first that is set, #if defined COMPILE_PCRE8 static int -get_first_set(const pcre *code, const char *stringname, int *ovector) +get_first_set(const pcre *code, const char *stringname, int *ovector, + int stringcount) #elif defined COMPILE_PCRE16 static int -get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) +get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector, + int stringcount) #elif defined COMPILE_PCRE32 static int -get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector) +get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector, + int stringcount) #endif { const REAL_PCRE *re = (const REAL_PCRE *)code; @@ -295,7 +299,7 @@ if (entrysize <= 0) return entrysize; for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) { int n = GET2(entry, 0); - if (ovector[n*2] >= 0) return n; + if (n < stringcount && ovector[n*2] >= 0) return n; } return GET2(entry, 0); } @@ -402,7 +406,7 @@ pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject, PCRE_UCHAR32 *buffer, int size) #endif { -int n = get_first_set(code, stringname, ovector); +int n = get_first_set(code, stringname, ovector, stringcount); if (n <= 0) return n; #if defined COMPILE_PCRE8 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); @@ -457,7 +461,10 @@ pcre_uchar **stringlist; pcre_uchar *p; for (i = 0; i < double_count; i += 2) - size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1); + { + size += sizeof(pcre_uchar *) + IN_UCHARS(1); + if (ovector[i+1] > ovector[i]) size += IN_UCHARS(ovector[i+1] - ovector[i]); + } stringlist = (pcre_uchar **)(PUBL(malloc))(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; @@ -473,7 +480,7 @@ p = (pcre_uchar *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { - int len = ovector[i+1] - ovector[i]; + int len = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0; memcpy(p, subject + ovector[i], IN_UCHARS(len)); *stringlist++ = p; p += len; @@ -619,7 +626,7 @@ pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject, PCRE_SPTR32 *stringptr) #endif { -int n = get_first_set(code, stringname, ovector); +int n = get_first_set(code, stringname, ovector, stringcount); if (n <= 0) return n; #if defined COMPILE_PCRE8 return pcre_get_substring(subject, ovector, stringcount, n, stringptr); diff --git a/pcre/pcre_internal.h b/pcre/pcre_internal.h index f7a5ee7aa6f3b..2923b29f82dec 100644 --- a/pcre/pcre_internal.h +++ b/pcre/pcre_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2014 University of Cambridge + Copyright (c) 1997-2016 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -275,7 +275,7 @@ pcre.h(.in) and disable (comment out) this message. */ typedef pcre_uint16 pcre_uchar; #define UCHAR_SHIFT (1) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define IN_UCHARS(x) ((x) * 2) #define MAX_255(c) ((c) <= 255u) #define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) @@ -283,7 +283,7 @@ typedef pcre_uint16 pcre_uchar; typedef pcre_uint32 pcre_uchar; #define UCHAR_SHIFT (2) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define IN_UCHARS(x) ((x) * 4) #define MAX_255(c) ((c) <= 255u) #define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) @@ -2289,7 +2289,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, - ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERRCOUNT }; + ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERRCOUNT }; /* JIT compiling modes. The function list is indexed by them. */ diff --git a/pcre/pcre_jit_compile.c b/pcre/pcre_jit_compile.c index 445de0cbefebc..4f15a27ac2817 100644 --- a/pcre/pcre_jit_compile.c +++ b/pcre/pcre_jit_compile.c @@ -168,13 +168,13 @@ typedef struct jit_arguments { pcre_uchar *mark_ptr; void *callout_data; /* Everything else after. */ - pcre_uint32 limit_match; + sljit_u32 limit_match; int real_offset_count; int offset_count; - pcre_uint8 notbol; - pcre_uint8 noteol; - pcre_uint8 notempty; - pcre_uint8 notempty_atstart; + sljit_u8 notbol; + sljit_u8 noteol; + sljit_u8 notempty; + sljit_u8 notempty_atstart; } jit_arguments; typedef struct executable_functions { @@ -183,8 +183,8 @@ typedef struct executable_functions { sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; PUBL(jit_callback) callback; void *userdata; - pcre_uint32 top_bracket; - pcre_uint32 limit_match; + sljit_u32 top_bracket; + sljit_u32 limit_match; } executable_functions; typedef struct jump_list { @@ -277,11 +277,25 @@ typedef struct braminzero_backtrack { struct sljit_label *matchingpath; } braminzero_backtrack; -typedef struct iterator_backtrack { +typedef struct char_iterator_backtrack { backtrack_common common; /* Next iteration. */ struct sljit_label *matchingpath; -} iterator_backtrack; + union { + jump_list *backtracks; + struct { + unsigned int othercasebit; + pcre_uchar chr; + BOOL enabled; + } charpos; + } u; +} char_iterator_backtrack; + +typedef struct ref_iterator_backtrack { + backtrack_common common; + /* Next iteration. */ + struct sljit_label *matchingpath; +} ref_iterator_backtrack; typedef struct recurse_entry { struct recurse_entry *next; @@ -321,40 +335,46 @@ typedef struct compiler_common { /* First byte code. */ pcre_uchar *start; /* Maps private data offset to each opcode. */ - sljit_si *private_data_ptrs; + sljit_s32 *private_data_ptrs; /* Chain list of read-only data ptrs. */ void *read_only_data_head; /* Tells whether the capturing bracket is optimized. */ - pcre_uint8 *optimized_cbracket; + sljit_u8 *optimized_cbracket; /* Tells whether the starting offset is a target of then. */ - pcre_uint8 *then_offsets; + sljit_u8 *then_offsets; /* Current position where a THEN must jump. */ then_trap_backtrack *then_trap; /* Starting offset of private data for capturing brackets. */ - int cbra_ptr; + sljit_s32 cbra_ptr; /* Output vector starting point. Must be divisible by 2. */ - int ovector_start; + sljit_s32 ovector_start; + /* Points to the starting character of the current match. */ + sljit_s32 start_ptr; /* Last known position of the requested byte. */ - int req_char_ptr; + sljit_s32 req_char_ptr; /* Head of the last recursion. */ - int recursive_head_ptr; - /* First inspected character for partial matching. */ - int start_used_ptr; + sljit_s32 recursive_head_ptr; + /* First inspected character for partial matching. + (Needed for avoiding zero length partial matches.) */ + sljit_s32 start_used_ptr; /* Starting pointer for partial soft matches. */ - int hit_start; - /* End pointer of the first line. */ - int first_line_end; + sljit_s32 hit_start; + /* Pointer of the match end position. */ + sljit_s32 match_end_ptr; /* Points to the marked string. */ - int mark_ptr; + sljit_s32 mark_ptr; /* Recursive control verb management chain. */ - int control_head_ptr; + sljit_s32 control_head_ptr; /* Points to the last matched capture block index. */ - int capture_last_ptr; - /* Points to the starting position of the current match. */ - int start_ptr; + sljit_s32 capture_last_ptr; + /* Fast forward skipping byte code pointer. */ + pcre_uchar *fast_forward_bc_ptr; + /* Locals used by fast fail optimization. */ + sljit_s32 fast_fail_start_ptr; + sljit_s32 fast_fail_end_ptr; /* Flipped and lower case tables. */ - const pcre_uint8 *fcc; + const sljit_u8 *fcc; sljit_sw lcc; /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ int mode; @@ -366,20 +386,20 @@ typedef struct compiler_common { BOOL has_skip_arg; /* (*THEN) is found in the pattern. */ BOOL has_then; - /* Needs to know the start position anytime. */ - BOOL needs_start_ptr; + /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */ + BOOL has_skip_in_assert_back; /* Currently in recurse or negative assert. */ BOOL local_exit; /* Currently in a positive assert. */ BOOL positive_assert; /* Newline control. */ int nltype; - pcre_uint32 nlmax; - pcre_uint32 nlmin; + sljit_u32 nlmax; + sljit_u32 nlmin; int newline; int bsr_nltype; - pcre_uint32 bsr_nlmax; - pcre_uint32 bsr_nlmin; + sljit_u32 bsr_nlmax; + sljit_u32 bsr_nlmin; /* Dollar endonly. */ int endonly; /* Tables. */ @@ -419,6 +439,7 @@ typedef struct compiler_common { BOOL utf; #ifdef SUPPORT_UCP BOOL use_ucp; + jump_list *getucd; #endif #ifdef COMPILE_PCRE8 jump_list *utfreadchar; @@ -426,9 +447,6 @@ typedef struct compiler_common { jump_list *utfreadtype8; #endif #endif /* SUPPORT_UTF */ -#ifdef SUPPORT_UCP - jump_list *getucd; -#endif } compiler_common; /* For byte_sequence_compare. */ @@ -439,27 +457,27 @@ typedef struct compare_context { #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED int ucharptr; union { - sljit_si asint; - sljit_uh asushort; + sljit_s32 asint; + sljit_u16 asushort; #if defined COMPILE_PCRE8 - sljit_ub asbyte; - sljit_ub asuchars[4]; + sljit_u8 asbyte; + sljit_u8 asuchars[4]; #elif defined COMPILE_PCRE16 - sljit_uh asuchars[2]; + sljit_u16 asuchars[2]; #elif defined COMPILE_PCRE32 - sljit_ui asuchars[1]; + sljit_u32 asuchars[1]; #endif } c; union { - sljit_si asint; - sljit_uh asushort; + sljit_s32 asint; + sljit_u16 asushort; #if defined COMPILE_PCRE8 - sljit_ub asbyte; - sljit_ub asuchars[4]; + sljit_u8 asbyte; + sljit_u8 asuchars[4]; #elif defined COMPILE_PCRE16 - sljit_uh asuchars[2]; + sljit_u16 asuchars[2]; #elif defined COMPILE_PCRE32 - sljit_ui asuchars[1]; + sljit_u32 asuchars[1]; #endif } oc; #endif @@ -501,14 +519,14 @@ the start pointers when the end of the capturing group has not yet reached. */ #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) #if defined COMPILE_PCRE8 -#define MOV_UCHAR SLJIT_MOV_UB -#define MOVU_UCHAR SLJIT_MOVU_UB +#define MOV_UCHAR SLJIT_MOV_U8 +#define MOVU_UCHAR SLJIT_MOVU_U8 #elif defined COMPILE_PCRE16 -#define MOV_UCHAR SLJIT_MOV_UH -#define MOVU_UCHAR SLJIT_MOVU_UH +#define MOV_UCHAR SLJIT_MOV_U16 +#define MOVU_UCHAR SLJIT_MOVU_U16 #elif defined COMPILE_PCRE32 -#define MOV_UCHAR SLJIT_MOV_UI -#define MOVU_UCHAR SLJIT_MOVU_UI +#define MOV_UCHAR SLJIT_MOV_U32 +#define MOVU_UCHAR SLJIT_MOVU_U32 #else #error Unsupported compiling mode #endif @@ -564,11 +582,6 @@ SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); return count; } -static int ones_in_half_byte[16] = { - /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3, - /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4 -}; - /* Functions whose might need modification for all new supported opcodes: next_opcode check_opcode_types @@ -780,6 +793,7 @@ static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uch { int count; pcre_uchar *slot; +pcre_uchar *assert_back_end = cc - 1; /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ while (cc < ccend) @@ -850,15 +864,19 @@ while (cc < ccend) cc += 2 + 2 * LINK_SIZE; break; + case OP_ASSERTBACK: + slot = bracketend(cc); + if (slot > assert_back_end) + assert_back_end = slot; + cc += 1 + LINK_SIZE; + break; + case OP_THEN_ARG: common->has_then = TRUE; common->control_head_ptr = 1; /* Fall through. */ case OP_PRUNE_ARG: - common->needs_start_ptr = TRUE; - /* Fall through. */ - case OP_MARK: if (common->mark_ptr == 0) { @@ -871,17 +889,20 @@ while (cc < ccend) case OP_THEN: common->has_then = TRUE; common->control_head_ptr = 1; - /* Fall through. */ + cc += 1; + break; - case OP_PRUNE: case OP_SKIP: - common->needs_start_ptr = TRUE; + if (cc < assert_back_end) + common->has_skip_in_assert_back = TRUE; cc += 1; break; case OP_SKIP_ARG: common->control_head_ptr = 1; common->has_skip_arg = TRUE; + if (cc < assert_back_end) + common->has_skip_in_assert_back = TRUE; cc += 1 + 2 + cc[1]; break; @@ -895,8 +916,189 @@ while (cc < ccend) return TRUE; } +static BOOL is_accelerated_repeat(pcre_uchar *cc) +{ +switch(*cc) + { + case OP_TYPESTAR: + case OP_TYPEMINSTAR: + case OP_TYPEPLUS: + case OP_TYPEMINPLUS: + case OP_TYPEPOSSTAR: + case OP_TYPEPOSPLUS: + return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI); + + case OP_STAR: + case OP_MINSTAR: + case OP_PLUS: + case OP_MINPLUS: + case OP_POSSTAR: + case OP_POSPLUS: + + case OP_STARI: + case OP_MINSTARI: + case OP_PLUSI: + case OP_MINPLUSI: + case OP_POSSTARI: + case OP_POSPLUSI: + + case OP_NOTSTAR: + case OP_NOTMINSTAR: + case OP_NOTPLUS: + case OP_NOTMINPLUS: + case OP_NOTPOSSTAR: + case OP_NOTPOSPLUS: + + case OP_NOTSTARI: + case OP_NOTMINSTARI: + case OP_NOTPLUSI: + case OP_NOTMINPLUSI: + case OP_NOTPOSSTARI: + case OP_NOTPOSPLUSI: + return TRUE; + + case OP_CLASS: + case OP_NCLASS: +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(pcre_uchar))); +#else + cc += (1 + (32 / sizeof(pcre_uchar))); +#endif + + switch(*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSSTAR: + case OP_CRPOSPLUS: + return TRUE; + } + break; + } +return FALSE; +} + +static SLJIT_INLINE BOOL detect_fast_forward_skip(compiler_common *common, int *private_data_start) +{ +pcre_uchar *cc = common->start; +pcre_uchar *end; + +/* Skip not repeated brackets. */ +while (TRUE) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + } + + if (*cc != OP_BRA && *cc != OP_CBRA) + break; + + end = cc + GET(cc, 1); + if (*end != OP_KET || PRIVATE_DATA(end) != 0) + return FALSE; + if (*cc == OP_CBRA) + { + if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + return FALSE; + cc += IMM2_SIZE; + } + cc += 1 + LINK_SIZE; + } + +if (is_accelerated_repeat(cc)) + { + common->fast_forward_bc_ptr = cc; + common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; + *private_data_start += sizeof(sljit_sw); + return TRUE; + } +return FALSE; +} + +static SLJIT_INLINE void detect_fast_fail(compiler_common *common, pcre_uchar *cc, int *private_data_start, sljit_s32 depth) +{ + pcre_uchar *next_alt; + + SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA); + + if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) + return; + + next_alt = bracketend(cc) - (1 + LINK_SIZE); + if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0) + return; + + do + { + next_alt = cc + GET(cc, 1); + + cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0); + + while (TRUE) + { + switch(*cc) + { + case OP_SOD: + case OP_SOM: + case OP_SET_SOM: + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + /* Zero width assertions. */ + cc++; + continue; + } + break; + } + + if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA)) + detect_fast_fail(common, cc, private_data_start, depth - 1); + + if (is_accelerated_repeat(cc)) + { + common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start; + + if (common->fast_fail_start_ptr == 0) + common->fast_fail_start_ptr = *private_data_start; + + *private_data_start += sizeof(sljit_sw); + common->fast_fail_end_ptr = *private_data_start; + + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return; + } + + cc = next_alt; + } + while (*cc == OP_ALT); +} + static int get_class_iterator_size(pcre_uchar *cc) { +sljit_u32 min; +sljit_u32 max; switch(*cc) { case OP_CRSTAR: @@ -911,9 +1113,14 @@ switch(*cc) case OP_CRRANGE: case OP_CRMINRANGE: - if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) - return 0; - return 2; + min = GET2(cc, 1); + max = GET2(cc, 1 + IMM2_SIZE); + if (max == 0) + return (*cc == OP_CRRANGE) ? 2 : 1; + max -= min; + if (max > 2) + max = 2; + return max; default: return 0; @@ -1186,14 +1393,14 @@ while (cc < ccend) case OP_CLASS: case OP_NCLASS: - size += 1 + 32 / sizeof(pcre_uchar); space = get_class_iterator_size(cc + size); + size = 1 + 32 / sizeof(pcre_uchar); break; #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: - size = GET(cc, 1); space = get_class_iterator_size(cc + size); + size = GET(cc, 1); break; #endif @@ -1406,6 +1613,7 @@ while (cc < ccend) case OP_CLASS: case OP_NCLASS: case OP_XCLASS: + case OP_CALLOUT: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); @@ -1990,7 +2198,7 @@ if (save) SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); } -static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset) +static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, sljit_u8 *current_offset) { pcre_uchar *end = bracketend(cc); BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT; @@ -2113,6 +2321,7 @@ static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) /* May destroy all locals and registers except TMP2. */ DEFINE_COMPILER; +SLJIT_ASSERT(size > 0); OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); #ifdef DESTROY_REGISTERS OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); @@ -2127,6 +2336,8 @@ add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0)); static SLJIT_INLINE void free_stack(compiler_common *common, int size) { DEFINE_COMPILER; + +SLJIT_ASSERT(size > 0); OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); } @@ -2190,6 +2401,18 @@ else } } +static SLJIT_INLINE void reset_fast_fail(compiler_common *common) +{ +DEFINE_COMPILER; +sljit_s32 i; + +SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr); + +OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw)) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0); +} + static SLJIT_INLINE void do_reset_match(compiler_common *common, int length) { DEFINE_COMPILER; @@ -2262,7 +2485,7 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr); -OP1(SLJIT_MOV_SI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offset_count)); +OP1(SLJIT_MOV_S32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offset_count)); if (common->mark_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0); OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); @@ -2277,7 +2500,7 @@ OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw)); #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0); +OP1(SLJIT_MOVU_S32, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, loop); JUMPHERE(early_quit); @@ -2310,7 +2533,7 @@ SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0 OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); -OP1(SLJIT_MOV_SI, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count)); +OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count)); CMPTO(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit); /* Store match begin and end. */ @@ -2322,7 +2545,7 @@ OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HA #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 2 * sizeof(int), SLJIT_R2, 0); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R1), 2 * sizeof(int), SLJIT_R2, 0); JUMPHERE(jump); OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); @@ -2330,13 +2553,13 @@ OP2(SLJIT_SUB, SLJIT_S1, 0, STR_END, 0, SLJIT_S0, 0); #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), sizeof(int), SLJIT_S1, 0); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R1), sizeof(int), SLJIT_S1, 0); OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0); #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R2, 0); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R2, 0); JUMPTO(SLJIT_JUMP, quit); } @@ -2573,7 +2796,7 @@ else JUMPHERE(jump); } -static void peek_char(compiler_common *common, pcre_uint32 max) +static void peek_char(compiler_common *common, sljit_u32 max) { /* Reads the character into TMP1, keeps STR_PTR. Does not check STR_END. TMP2 Destroyed. */ @@ -2618,12 +2841,12 @@ if (common->utf) #if defined SUPPORT_UTF && defined COMPILE_PCRE8 -static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass) +static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass) { /* Tells whether the character codes below 128 are enough to determine a match. */ -const pcre_uint8 value = nclass ? 0xff : 0; -const pcre_uint8 *end = bitset + 32; +const sljit_u8 value = nclass ? 0xff : 0; +const sljit_u8 *end = bitset + 32; bitset += 16; do @@ -2648,12 +2871,12 @@ SLJIT_ASSERT(common->utf); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); if (full_read) { jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); JUMPHERE(jump); } @@ -2661,7 +2884,7 @@ if (full_read) #endif /* SUPPORT_UTF && COMPILE_PCRE8 */ -static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr) +static void read_char_range(compiler_common *common, sljit_u32 min, sljit_u32 max, BOOL update_str_ptr) { /* Reads the precise value of a character into TMP1, if the character is between min and max (c >= min && c <= max). Otherwise it returns with a value @@ -2692,7 +2915,7 @@ if (common->utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); if (update_str_ptr) - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); @@ -2716,7 +2939,7 @@ if (common->utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); if (update_str_ptr) - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); @@ -2736,7 +2959,7 @@ if (common->utf) add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); else if (max < 128) { - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); } else @@ -2745,7 +2968,7 @@ if (common->utf) if (!update_str_ptr) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); else - OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); @@ -2815,7 +3038,7 @@ if (common->utf) { /* This can be an extra read in some situations, but hopefully it is needed in most cases. */ - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); if (!update_str_ptr) { @@ -2827,7 +3050,7 @@ if (common->utf) OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); JUMPHERE(jump2); } else @@ -2842,7 +3065,7 @@ if (common->utf) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); #endif -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); #if !defined COMPILE_PCRE8 JUMPHERE(jump); #endif @@ -3034,7 +3257,7 @@ compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(compare); @@ -3043,7 +3266,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); /* We only have types for characters less than 256. */ JUMPHERE(jump); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); +OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); @@ -3069,26 +3292,26 @@ SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); +OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); -OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); +OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } #endif -static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline) +static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf) { DEFINE_COMPILER; struct sljit_label *mainloop; struct sljit_label *newlinelabel = NULL; struct sljit_jump *start; struct sljit_jump *end = NULL; -struct sljit_jump *nl = NULL; +struct sljit_jump *end2 = NULL; #if defined SUPPORT_UTF && !defined COMPILE_PCRE32 struct sljit_jump *singlechar; #endif @@ -3096,14 +3319,13 @@ jump_list *newline = NULL; BOOL newlinecheck = FALSE; BOOL readuchar = FALSE; -if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY || - common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) +if (!(hascrorlf || (common->match_end_ptr != 0)) && + (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF || common->newline > 255)) newlinecheck = TRUE; -if (firstline) +if (common->match_end_ptr != 0) { /* Search for the end of the first line. */ - SLJIT_ASSERT(common->first_line_end != 0); OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); if (common->nltype == NLTYPE_FIXED && common->newline > 255) @@ -3116,19 +3338,19 @@ if (firstline) CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); JUMPHERE(end); - OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } else { end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); mainloop = LABEL(); /* Continual stores does not cause data dependency. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); read_char_range(common, common->nlmin, common->nlmax, TRUE); check_newlinechar(common, common->nltype, &newline, TRUE); CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop); JUMPHERE(end); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); set_jumps(newline, LABEL()); } @@ -3149,7 +3371,7 @@ if (newlinecheck) OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - nl = JUMP(SLJIT_JUMP); + end2 = JUMP(SLJIT_JUMP); } mainloop = LABEL(); @@ -3172,7 +3394,7 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); if (common->utf) { singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(singlechar); } @@ -3194,51 +3416,52 @@ JUMPHERE(start); if (newlinecheck) { JUMPHERE(end); - JUMPHERE(nl); + JUMPHERE(end2); } return mainloop; } #define MAX_N_CHARS 16 -#define MAX_N_BYTES 8 +#define MAX_DIFF_CHARS 6 -static SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes) +static SLJIT_INLINE void add_prefix_char(pcre_uchar chr, pcre_uchar *chars) { -pcre_uint8 len = bytes[0]; -int i; +pcre_uchar i, len; +len = chars[0]; if (len == 255) return; if (len == 0) { - bytes[0] = 1; - bytes[1] = byte; + chars[0] = 1; + chars[1] = chr; return; } for (i = len; i > 0; i--) - if (bytes[i] == byte) + if (chars[i] == chr) return; -if (len >= MAX_N_BYTES - 1) +if (len >= MAX_DIFF_CHARS - 1) { - bytes[0] = 255; + chars[0] = 255; return; } len++; -bytes[len] = byte; -bytes[0] = len; +chars[len] = chr; +chars[0] = len; } -static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count) +static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uchar *chars, int max_chars, sljit_u32 *rec_count) { /* Recursive function, which scans prefix literals. */ -BOOL last, any, caseless; +BOOL last, any, class, caseless; int len, repeat, len_save, consumed = 0; -pcre_uint32 chr, mask; +sljit_u32 chr; /* Any unicode character. */ +sljit_u8 *bytes, *bytes_end, byte; pcre_uchar *alternative, *cc_save, *oc; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 pcre_uchar othercase[8]; @@ -3257,6 +3480,7 @@ while (TRUE) last = TRUE; any = FALSE; + class = FALSE; caseless = FALSE; switch (*cc) @@ -3320,7 +3544,7 @@ while (TRUE) #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); #endif - max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count); + max_chars = scan_prefix(common, cc + len, chars, max_chars, rec_count); if (max_chars == 0) return consumed; last = FALSE; @@ -3343,7 +3567,7 @@ while (TRUE) alternative = cc + GET(cc, 1); while (*alternative == OP_ALT) { - max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count); + max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars, rec_count); if (max_chars == 0) return consumed; alternative += GET(alternative, 1); @@ -3356,18 +3580,17 @@ while (TRUE) case OP_CLASS: #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && !is_char7_bitset((const pcre_uint8 *)(cc + 1), FALSE)) return consumed; + if (common->utf && !is_char7_bitset((const sljit_u8 *)(cc + 1), FALSE)) + return consumed; #endif - any = TRUE; - cc += 1 + 32 / sizeof(pcre_uchar); + class = TRUE; break; case OP_NCLASS: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32 if (common->utf) return consumed; #endif - any = TRUE; - cc += 1 + 32 / sizeof(pcre_uchar); + class = TRUE; break; #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 @@ -3382,7 +3605,7 @@ while (TRUE) case OP_DIGIT: #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) + if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) return consumed; #endif any = TRUE; @@ -3391,7 +3614,7 @@ while (TRUE) case OP_WHITESPACE: #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_space, FALSE)) + if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE)) return consumed; #endif any = TRUE; @@ -3400,7 +3623,7 @@ while (TRUE) case OP_WORDCHAR: #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_word, FALSE)) + if (common->utf && !is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE)) return consumed; #endif any = TRUE; @@ -3423,10 +3646,10 @@ while (TRUE) cc++; break; -#ifdef SUPPORT_UCP +#ifdef SUPPORT_UTF case OP_NOTPROP: case OP_PROP: -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifndef COMPILE_PCRE32 if (common->utf) return consumed; #endif any = TRUE; @@ -3455,30 +3678,114 @@ while (TRUE) if (any) { -#if defined COMPILE_PCRE8 - mask = 0xff; -#elif defined COMPILE_PCRE16 - mask = 0xffff; -#elif defined COMPILE_PCRE32 - mask = 0xffffffff; -#else - SLJIT_ASSERT_STOP(); -#endif + do + { + chars[0] = 255; + + consumed++; + if (--max_chars == 0) + return consumed; + chars += MAX_DIFF_CHARS; + } + while (--repeat > 0); + + repeat = 1; + continue; + } + + if (class) + { + bytes = (sljit_u8*) (cc + 1); + cc += 1 + 32 / sizeof(pcre_uchar); + + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + max_chars = scan_prefix(common, cc + 1, chars, max_chars, rec_count); + if (max_chars == 0) + return consumed; + break; + + default: + case OP_CRPLUS: + case OP_CRMINPLUS: + case OP_CRPOSPLUS: + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + repeat = GET2(cc, 1); + if (repeat <= 0) + return consumed; + break; + } do { - chars[0] = mask; - chars[1] = mask; - bytes[0] = 255; + if (bytes[31] & 0x80) + chars[0] = 255; + else if (chars[0] != 255) + { + bytes_end = bytes + 32; + chr = 0; + do + { + byte = *bytes++; + SLJIT_ASSERT((chr & 0x7) == 0); + if (byte == 0) + chr += 8; + else + { + do + { + if ((byte & 0x1) != 0) + add_prefix_char(chr, chars); + byte >>= 1; + chr++; + } + while (byte != 0); + chr = (chr + 7) & ~7; + } + } + while (chars[0] != 255 && bytes < bytes_end); + bytes = bytes_end - 32; + } consumed++; if (--max_chars == 0) return consumed; - chars += 2; - bytes += MAX_N_BYTES; + chars += MAX_DIFF_CHARS; } while (--repeat > 0); + switch (*cc) + { + case OP_CRSTAR: + case OP_CRMINSTAR: + case OP_CRPOSSTAR: + return consumed; + + case OP_CRQUERY: + case OP_CRMINQUERY: + case OP_CRPOSQUERY: + cc++; + break; + + case OP_CRRANGE: + case OP_CRMINRANGE: + case OP_CRPOSRANGE: + if (GET2(cc, 1) != GET2(cc, 1 + IMM2_SIZE)) + return consumed; + cc += 1 + 2 * IMM2_SIZE; + break; + } + repeat = 1; continue; } @@ -3505,7 +3812,10 @@ while (TRUE) } } else + { caseless = FALSE; + othercase[0] = 0; /* Stops compiler warning - PH */ + } len_save = len; cc_save = cc; @@ -3515,43 +3825,16 @@ while (TRUE) do { chr = *cc; -#ifdef COMPILE_PCRE32 - if (SLJIT_UNLIKELY(chr == NOTACHAR)) - return consumed; -#endif - add_prefix_byte((pcre_uint8)chr, bytes); + add_prefix_char(*cc, chars); - mask = 0; if (caseless) - { - add_prefix_byte((pcre_uint8)*oc, bytes); - mask = *cc ^ *oc; - chr |= mask; - } - -#ifdef COMPILE_PCRE32 - if (chars[0] == NOTACHAR && chars[1] == 0) -#else - if (chars[0] == NOTACHAR) -#endif - { - chars[0] = chr; - chars[1] = mask; - } - else - { - mask |= chars[0] ^ chr; - chr |= mask; - chars[0] = chr; - chars[1] |= mask; - } + add_prefix_char(*oc, chars); len--; consumed++; if (--max_chars == 0) return consumed; - chars += 2; - bytes += MAX_N_BYTES; + chars += MAX_DIFF_CHARS; cc++; oc++; } @@ -3570,163 +3853,576 @@ while (TRUE) } } -static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline) +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +static sljit_s32 character_to_int32(pcre_uchar chr) +{ +sljit_s32 value = (sljit_s32)chr; +#if defined COMPILE_PCRE8 +#define SSE2_COMPARE_TYPE_INDEX 0 +return (value << 24) | (value << 16) | (value << 8) | value; +#elif defined COMPILE_PCRE16 +#define SSE2_COMPARE_TYPE_INDEX 1 +return (value << 16) | value; +#elif defined COMPILE_PCRE32 +#define SSE2_COMPARE_TYPE_INDEX 2 +return value; +#else +#error "Unsupported unit width" +#endif +} + +static SLJIT_INLINE void fast_forward_first_char2_sse2(compiler_common *common, pcre_uchar char1, pcre_uchar char2) { DEFINE_COMPILER; struct sljit_label *start; -struct sljit_jump *quit; -pcre_uint32 chars[MAX_N_CHARS * 2]; -pcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES]; -pcre_uint8 ones[MAX_N_CHARS]; -int offsets[3]; -pcre_uint32 mask; -pcre_uint8 *byte_set, *byte_set_end; -int i, max, from; -int range_right = -1, range_len = 3 - 1; -sljit_ub *update_table = NULL; -BOOL in_range; -pcre_uint32 rec_count; +struct sljit_jump *quit[3]; +struct sljit_jump *nomatch; +sljit_u8 instruction[8]; +sljit_s32 tmp1_ind = sljit_get_register_index(TMP1); +sljit_s32 tmp2_ind = sljit_get_register_index(TMP2); +sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR); +BOOL load_twice = FALSE; +pcre_uchar bit; + +bit = char1 ^ char2; +if (!is_powerof2(bit)) + bit = 0; -for (i = 0; i < MAX_N_CHARS; i++) - { - chars[i << 1] = NOTACHAR; - chars[(i << 1) + 1] = 0; - bytes[i * MAX_N_BYTES] = 0; - } +if ((char1 != char2) && bit == 0) + load_twice = TRUE; -rec_count = 10000; -max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count); +quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -if (max <= 1) - return FALSE; +/* First part (unaligned start) */ -for (i = 0; i < max; i++) +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); + +SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1); + +/* MOVD xmm, r/m32 */ +instruction[0] = 0x66; +instruction[1] = 0x0f; +instruction[2] = 0x6e; +instruction[3] = 0xc0 | (2 << 3) | tmp1_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (char1 != char2) { - mask = chars[(i << 1) + 1]; - ones[i] = ones_in_half_byte[mask & 0xf]; - mask >>= 4; - while (mask != 0) - { - ones[i] += ones_in_half_byte[mask & 0xf]; - mask >>= 4; - } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); + + /* MOVD xmm, r/m32 */ + instruction[3] = 0xc0 | (3 << 3) | tmp1_ind; + sljit_emit_op_custom(compiler, instruction, 4); } +/* PSHUFD xmm1, xmm2/m128, imm8 */ +instruction[2] = 0x70; +instruction[3] = 0xc0 | (2 << 3) | 2; +instruction[4] = 0; +sljit_emit_op_custom(compiler, instruction, 5); + +if (char1 != char2) + { + /* PSHUFD xmm1, xmm2/m128, imm8 */ + instruction[3] = 0xc0 | (3 << 3) | 3; + instruction[4] = 0; + sljit_emit_op_custom(compiler, instruction, 5); + } + +OP2(SLJIT_AND, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); + +/* MOVDQA xmm1, xmm2/m128 */ +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +if (str_ptr_ind < 8) + { + instruction[2] = 0x6f; + instruction[3] = (0 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + + if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + } +else + { + instruction[1] = 0x41; + instruction[2] = 0x0f; + instruction[3] = 0x6f; + instruction[4] = (0 << 3) | (str_ptr_ind & 0x7); + sljit_emit_op_custom(compiler, instruction, 5); + + if (load_twice) + { + instruction[4] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + instruction[1] = 0x0f; + } + +#else + +instruction[2] = 0x6f; +instruction[3] = (0 << 3) | str_ptr_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +#endif + +if (bit != 0) + { + /* POR xmm1, xmm2/m128 */ + instruction[2] = 0xeb; + instruction[3] = 0xc0 | (0 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PCMPEQB/W/D xmm1, xmm2/m128 */ +instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; +instruction[3] = 0xc0 | (0 << 3) | 2; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = 0xc0 | (1 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PMOVMSKB reg, xmm */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); + instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; + sljit_emit_op_custom(compiler, instruction, 4); + + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, TMP3, 0); + } + +OP2(SLJIT_ASHR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +nomatch = JUMP(SLJIT_ZERO); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +quit[1] = JUMP(SLJIT_JUMP); + +JUMPHERE(nomatch); + +start = LABEL(); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +quit[2] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +/* Second part (aligned) */ + +instruction[0] = 0x66; +instruction[1] = 0x0f; + +/* MOVDQA xmm1, xmm2/m128 */ +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + +if (str_ptr_ind < 8) + { + instruction[2] = 0x6f; + instruction[3] = (0 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + + if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + } +else + { + instruction[1] = 0x41; + instruction[2] = 0x0f; + instruction[3] = 0x6f; + instruction[4] = (0 << 3) | (str_ptr_ind & 0x7); + sljit_emit_op_custom(compiler, instruction, 5); + + if (load_twice) + { + instruction[4] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 5); + } + instruction[1] = 0x0f; + } + +#else + +instruction[2] = 0x6f; +instruction[3] = (0 << 3) | str_ptr_ind; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = (1 << 3) | str_ptr_ind; + sljit_emit_op_custom(compiler, instruction, 4); + } + +#endif + +if (bit != 0) + { + /* POR xmm1, xmm2/m128 */ + instruction[2] = 0xeb; + instruction[3] = 0xc0 | (0 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PCMPEQB/W/D xmm1, xmm2/m128 */ +instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; +instruction[3] = 0xc0 | (0 << 3) | 2; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = 0xc0 | (1 << 3) | 3; + sljit_emit_op_custom(compiler, instruction, 4); + } + +/* PMOVMSKB reg, xmm */ +instruction[2] = 0xd7; +instruction[3] = 0xc0 | (tmp1_ind << 3) | 0; +sljit_emit_op_custom(compiler, instruction, 4); + +if (load_twice) + { + instruction[3] = 0xc0 | (tmp2_ind << 3) | 1; + sljit_emit_op_custom(compiler, instruction, 4); + + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + } + +/* BSF r32, r/m32 */ +instruction[0] = 0x0f; +instruction[1] = 0xbc; +instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind; +sljit_emit_op_custom(compiler, instruction, 3); + +JUMPTO(SLJIT_ZERO, start); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +start = LABEL(); +SET_LABEL(quit[0], start); +SET_LABEL(quit[1], start); +SET_LABEL(quit[2], start); +} + +#undef SSE2_COMPARE_TYPE_INDEX + +#endif + +static void fast_forward_first_char2(compiler_common *common, pcre_uchar char1, pcre_uchar char2, sljit_s32 offset) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +struct sljit_jump *found; +pcre_uchar mask; +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +struct sljit_label *utf_start = NULL; +struct sljit_jump *utf_quit = NULL; +#endif +BOOL has_match_end = (common->match_end_ptr != 0); + +if (offset > 0) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); + +if (has_match_end) + { + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + + OP2(SLJIT_ADD, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, SLJIT_IMM, IN_UCHARS(offset + 1)); +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + if (sljit_x86_is_cmov_available()) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_END, 0, TMP3, 0); + sljit_x86_emit_cmov(compiler, SLJIT_GREATER, STR_END, TMP3, 0); + } +#endif + { + quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP3, 0); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + JUMPHERE(quit); + } + } + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +if (common->utf && offset > 0) + utf_start = LABEL(); +#endif + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +/* SSE2 accelerated first character search. */ + +if (sljit_x86_is_sse2_available()) + { + fast_forward_first_char2_sse2(common, char1, char2); + + SLJIT_ASSERT(common->mode == JIT_COMPILE || offset == 0); + if (common->mode == JIT_COMPILE) + { + /* In complete mode, we don't need to run a match when STR_PTR == STR_END. */ + SLJIT_ASSERT(common->forced_quit_label == NULL); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); + add_jump(compiler, &common->forced_quit, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf && offset > 0) + { + SLJIT_ASSERT(common->mode == JIT_COMPILE); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined COMPILE_PCRE8 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start); +#elif defined COMPILE_PCRE16 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start); +#else +#error "Unknown code width" +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } +#endif + + if (offset > 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); + } + else if (sljit_x86_is_cmov_available()) + { + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0); + sljit_x86_emit_cmov(compiler, SLJIT_GREATER_EQUAL, STR_PTR, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0); + } + else + { + quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_PTR, 0, has_match_end ? SLJIT_MEM1(SLJIT_SP) : STR_END, has_match_end ? common->match_end_ptr : 0); + JUMPHERE(quit); + } + + if (has_match_end) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + return; + } + +#endif + +quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +start = LABEL(); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + +if (char1 == char2) + found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1); +else + { + mask = char1 ^ char2; + if (is_powerof2(mask)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); + found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, char1 | mask); + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char1); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char2); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); + found = JUMP(SLJIT_NOT_ZERO); + } + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, start); + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +if (common->utf && offset > 0) + utf_quit = JUMP(SLJIT_JUMP); +#endif + +JUMPHERE(found); + +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +if (common->utf && offset > 0) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined COMPILE_PCRE8 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, utf_start); +#elif defined COMPILE_PCRE16 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, utf_start); +#else +#error "Unknown code width" +#endif + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(utf_quit); + } +#endif + +JUMPHERE(quit); + +if (has_match_end) + { + quit = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + if (offset > 0) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); + JUMPHERE(quit); + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + } + +if (offset > 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset)); +} + +static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +struct sljit_jump *match; +/* bytes[0] represent the number of characters between 0 +and MAX_N_BYTES - 1, 255 represents any character. */ +pcre_uchar chars[MAX_N_CHARS * MAX_DIFF_CHARS]; +sljit_s32 offset; +pcre_uchar mask; +pcre_uchar *char_set, *char_set_end; +int i, max, from; +int range_right = -1, range_len; +sljit_u8 *update_table = NULL; +BOOL in_range; +sljit_u32 rec_count; + +for (i = 0; i < MAX_N_CHARS; i++) + chars[i * MAX_DIFF_CHARS] = 0; + +rec_count = 10000; +max = scan_prefix(common, common->start, chars, MAX_N_CHARS, &rec_count); + +if (max < 1) + return FALSE; + in_range = FALSE; -from = 0; /* Prevent compiler "uninitialized" warning */ +/* Prevent compiler "uninitialized" warning */ +from = 0; +range_len = 4 /* minimum length */ - 1; for (i = 0; i <= max; i++) { - if (in_range && (i - from) > range_len && (bytes[(i - 1) * MAX_N_BYTES] <= 4)) + if (in_range && (i - from) > range_len && (chars[(i - 1) * MAX_DIFF_CHARS] < 255)) { range_len = i - from; range_right = i - 1; } - if (i < max && bytes[i * MAX_N_BYTES] < 255) + if (i < max && chars[i * MAX_DIFF_CHARS] < 255) { + SLJIT_ASSERT(chars[i * MAX_DIFF_CHARS] > 0); if (!in_range) { in_range = TRUE; from = i; } } - else if (in_range) + else in_range = FALSE; } if (range_right >= 0) { - update_table = (sljit_ub *)allocate_read_only_data(common, 256); + update_table = (sljit_u8 *)allocate_read_only_data(common, 256); if (update_table == NULL) return TRUE; memset(update_table, IN_UCHARS(range_len), 256); for (i = 0; i < range_len; i++) { - byte_set = bytes + ((range_right - i) * MAX_N_BYTES); - SLJIT_ASSERT(byte_set[0] > 0 && byte_set[0] < 255); - byte_set_end = byte_set + byte_set[0]; - byte_set++; - while (byte_set <= byte_set_end) + char_set = chars + ((range_right - i) * MAX_DIFF_CHARS); + SLJIT_ASSERT(char_set[0] > 0 && char_set[0] < 255); + char_set_end = char_set + char_set[0]; + char_set++; + while (char_set <= char_set_end) { - if (update_table[*byte_set] > IN_UCHARS(i)) - update_table[*byte_set] = IN_UCHARS(i); - byte_set++; + if (update_table[(*char_set) & 0xff] > IN_UCHARS(i)) + update_table[(*char_set) & 0xff] = IN_UCHARS(i); + char_set++; } } } -offsets[0] = -1; +offset = -1; /* Scan forward. */ for (i = 0; i < max; i++) - if (ones[i] <= 2) { - offsets[0] = i; - break; - } - -if (offsets[0] < 0 && range_right < 0) - return FALSE; - -if (offsets[0] >= 0) { - /* Scan backward. */ - offsets[1] = -1; - for (i = max - 1; i > offsets[0]; i--) - if (ones[i] <= 2 && i != range_right) - { - offsets[1] = i; - break; - } - - /* This case is handled better by fast_forward_first_char. */ - if (offsets[1] == -1 && offsets[0] == 0 && range_right < 0) - return FALSE; - - offsets[2] = -1; - /* We only search for a middle character if there is no range check. */ - if (offsets[1] >= 0 && range_right == -1) + if (offset == -1) + { + if (chars[i * MAX_DIFF_CHARS] <= 2) + offset = i; + } + else if (chars[offset * MAX_DIFF_CHARS] == 2 && chars[i * MAX_DIFF_CHARS] <= 2) { - /* Scan from middle. */ - for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++) - if (ones[i] <= 2) + if (chars[i * MAX_DIFF_CHARS] == 1) + offset = i; + else + { + mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2]; + if (!is_powerof2(mask)) { - offsets[2] = i; - break; + mask = chars[i * MAX_DIFF_CHARS + 1] ^ chars[i * MAX_DIFF_CHARS + 2]; + if (is_powerof2(mask)) + offset = i; } - - if (offsets[2] == -1) - { - for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--) - if (ones[i] <= 2) - { - offsets[2] = i; - break; - } } } + } - SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1])); - SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2])); - - chars[0] = chars[offsets[0] << 1]; - chars[1] = chars[(offsets[0] << 1) + 1]; - if (offsets[2] >= 0) - { - chars[2] = chars[offsets[2] << 1]; - chars[3] = chars[(offsets[2] << 1) + 1]; - } - if (offsets[1] >= 0) - { - chars[4] = chars[offsets[1] << 1]; - chars[5] = chars[(offsets[1] << 1) + 1]; - } +if (range_right < 0) + { + if (offset < 0) + return FALSE; + SLJIT_ASSERT(chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2); + /* Works regardless the value is 1 or 2. */ + mask = chars[offset * MAX_DIFF_CHARS + chars[offset * MAX_DIFF_CHARS]]; + fast_forward_first_char2(common, chars[offset * MAX_DIFF_CHARS + 1], mask, offset); + return TRUE; } +if (range_right == offset) + offset = -1; + +SLJIT_ASSERT(offset == -1 || (chars[offset * MAX_DIFF_CHARS] >= 1 && chars[offset * MAX_DIFF_CHARS] <= 2)); + max -= 1; -if (firstline) +SLJIT_ASSERT(max > 0); +if (common->match_end_ptr != 0) { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0); @@ -3736,68 +4432,86 @@ if (firstline) else OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); +SLJIT_ASSERT(range_right >= 0); + #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -if (range_right >= 0) - OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); +OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table); #endif start = LABEL(); quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0); - -if (range_right >= 0) - { #if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right)); #else - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1); #endif #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0); #else - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table); #endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); - } +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start); -if (offsets[0] >= 0) +if (offset >= 0) { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0])); - if (offsets[1] >= 0) - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1])); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offset)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - if (chars[1] != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); - if (offsets[2] >= 0) - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1)); - - if (offsets[1] >= 0) + if (chars[offset * MAX_DIFF_CHARS] == 1) + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1], start); + else { - if (chars[5] != 0) - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]); - CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start); + mask = chars[offset * MAX_DIFF_CHARS + 1] ^ chars[offset * MAX_DIFF_CHARS + 2]; + if (is_powerof2(mask)) + { + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, mask); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1] | mask, start); + } + else + { + match = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 1]); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[offset * MAX_DIFF_CHARS + 2], start); + JUMPHERE(match); + } } + } - if (offsets[2] >= 0) +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +if (common->utf && offset != 0) + { + if (offset < 0) { - if (chars[3] != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]); - CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + else + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +#if defined COMPILE_PCRE8 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, start); +#elif defined COMPILE_PCRE16 + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00, start); +#else +#error "Unknown code width" +#endif + if (offset < 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } +#endif + +if (offset >= 0) + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); JUMPHERE(quit); -if (firstline) +if (common->match_end_ptr != 0) { if (range_right >= 0) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); if (range_right >= 0) { @@ -3812,66 +4526,26 @@ return TRUE; } #undef MAX_N_CHARS -#undef MAX_N_BYTES +#undef MAX_DIFF_CHARS -static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) +static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless) { -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit; -struct sljit_jump *found; -pcre_uchar oc, bit; - -if (firstline) - { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); - } - -start = LABEL(); -quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); +pcre_uchar oc; oc = first_char; if (caseless) { oc = TABLE_GET(first_char, common->fcc, first_char); -#if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) +#if defined SUPPORT_UCP && !defined COMPILE_PCRE8 if (first_char > 127 && common->utf) oc = UCD_OTHERCASE(first_char); #endif } -if (first_char == oc) - found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, first_char); -else - { - bit = first_char ^ oc; - if (is_powerof2(bit)) - { - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); - found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); - } - else - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL); - found = JUMP(SLJIT_NOT_ZERO); - } - } -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -JUMPTO(SLJIT_JUMP, start); -JUMPHERE(found); -JUMPHERE(quit); - -if (firstline) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +fast_forward_first_char2(common, first_char, oc, 0); } -static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) +static SLJIT_INLINE void fast_forward_newline(compiler_common *common) { DEFINE_COMPILER; struct sljit_label *loop; @@ -3882,11 +4556,10 @@ struct sljit_jump *foundcr = NULL; struct sljit_jump *notfoundnl; jump_list *newline = NULL; -if (firstline) +if (common->match_end_ptr != 0) { - SLJIT_ASSERT(common->first_line_end != 0); OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); } if (common->nltype == NLTYPE_FIXED && common->newline > 255) @@ -3917,7 +4590,7 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255) JUMPHERE(firstchar); JUMPHERE(lastchar); - if (firstline) + if (common->match_end_ptr != 0) OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); return; } @@ -3955,13 +4628,13 @@ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) JUMPHERE(lastchar); JUMPHERE(firstchar); -if (firstline) +if (common->match_end_ptr != 0) OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); } -static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks); +static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks); -static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline) +static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, const sljit_u8 *start_bits) { DEFINE_COMPILER; struct sljit_label *start; @@ -3972,11 +4645,10 @@ jump_list *matches = NULL; struct sljit_jump *jump; #endif -if (firstline) +if (common->match_end_ptr != 0) { - SLJIT_ASSERT(common->first_line_end != 0); OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); - OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); } start = LABEL(); @@ -3996,7 +4668,7 @@ if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, #endif OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); found = JUMP(SLJIT_NOT_ZERO); @@ -4012,7 +4684,7 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); if (common->utf) { CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } #elif defined COMPILE_PCRE16 @@ -4034,7 +4706,7 @@ if (matches != NULL) set_jumps(matches, LABEL()); JUMPHERE(quit); -if (firstline) +if (common->match_end_ptr != 0) OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); } @@ -4047,7 +4719,7 @@ struct sljit_jump *alreadyfound; struct sljit_jump *found; struct sljit_jump *foundoc = NULL; struct sljit_jump *notfound; -pcre_uint32 oc, bit; +sljit_u32 oc, bit; SLJIT_ASSERT(common->req_char_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr); @@ -4184,7 +4856,7 @@ else if (common->utf) jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif /* COMPILE_PCRE8 */ - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); @@ -4229,7 +4901,7 @@ else if (common->utf) jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); #ifndef COMPILE_PCRE8 @@ -4245,11 +4917,12 @@ OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOC sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); } -static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks) +static BOOL check_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks) { +/* May destroy TMP1. */ DEFINE_COMPILER; int ranges[MAX_RANGE_SIZE]; -pcre_uint8 bit, cbit, all; +sljit_u8 bit, cbit, all; int i, byte, length = 0; bit = bits[0] & 0x1; @@ -4544,12 +5217,12 @@ OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); #ifndef COMPILE_PCRE8 jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255); #endif -OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); +OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0); #ifndef COMPILE_PCRE8 JUMPHERE(jump); jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255); #endif -OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); +OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0); #ifndef COMPILE_PCRE8 JUMPHERE(jump); #endif @@ -4574,11 +5247,11 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1) { /* This function would be ineffective to do in JIT level. */ -pcre_uint32 c1, c2; +sljit_u32 c1, c2; const pcre_uchar *src2 = args->uchar_ptr; const pcre_uchar *end2 = args->end; const ucd_record *ur; -const pcre_uint32 *pp; +const sljit_u32 *pp; while (src1 < end1) { @@ -4638,16 +5311,16 @@ if (context->sourcereg == -1) #if defined COMPILE_PCRE8 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) - OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 2) - OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); #elif defined COMPILE_PCRE16 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) - OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); @@ -4689,12 +5362,12 @@ do #endif { if (context->length >= 4) - OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_S32, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 2) - OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U16, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #if defined COMPILE_PCRE8 else if (context->length >= 1) - OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(SLJIT_MOV_U8, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); #endif /* COMPILE_PCRE8 */ context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; @@ -4777,6 +5450,8 @@ return cc; } \ charoffset = (value); +static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks, BOOL check_str_ptr); + static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) { DEFINE_COMPILER; @@ -4793,8 +5468,8 @@ BOOL utf = common->utf; #ifdef SUPPORT_UCP BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; BOOL charsaved = FALSE; -int typereg = TMP1, scriptreg = TMP1; -const pcre_uint32 *other_cases; +int typereg = TMP1; +const sljit_u32 *other_cases; sljit_uw typeoffset; #endif @@ -4856,6 +5531,14 @@ while (*cc != XCL_END) switch(*cc) { case PT_ANY: + /* Any either accepts everything or ignored. */ + if (cc[-1] == XCL_PROP) + { + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list == backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } break; case PT_LAMP: @@ -4892,10 +5575,10 @@ while (*cc != XCL_END) } #endif } +SLJIT_ASSERT(compares > 0); /* We are not necessary in utf mode even in 8 bit mode. */ cc = ccbegin; -detect_partial_match(common, backtracks); read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); if ((cc[-1] & XCL_HASPROP) == 0) @@ -4903,11 +5586,11 @@ if ((cc[-1] & XCL_HASPROP) == 0) if ((cc[-1] & XCL_MAP) != 0) { jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); - if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found)) + if (!check_class_ranges(common, (const sljit_u8 *)cc, (((const sljit_u8 *)cc)[31] & 0x80) != 0, TRUE, &found)) { OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO)); @@ -4926,11 +5609,11 @@ if ((cc[-1] & XCL_HASPROP) == 0) } else if ((cc[-1] & XCL_MAP) != 0) { - OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); #ifdef SUPPORT_UCP charsaved = TRUE; #endif - if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list)) + if (!check_class_ranges(common, (const sljit_u8 *)cc, FALSE, TRUE, list)) { #ifdef COMPILE_PCRE8 jump = NULL; @@ -4940,7 +5623,7 @@ else if ((cc[-1] & XCL_MAP) != 0) OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); @@ -4951,45 +5634,82 @@ else if ((cc[-1] & XCL_MAP) != 0) JUMPHERE(jump); } - OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); cc += 32 / sizeof(pcre_uchar); } #ifdef SUPPORT_UCP -/* Simple register allocation. TMP1 is preferred if possible. */ if (needstype || needsscript) { if (needschar && !charsaved) - OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - if (needschar) + OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); + + OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); + OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); + + /* Before anything else, we deal with scripts. */ + if (needsscript) { - if (needstype) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); + + ccbegin = cc; + + while (*cc != XCL_END) { - OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); - typereg = RETURN_ADDR; + if (*cc == XCL_SINGLE) + { + cc ++; + GETCHARINCTEST(c, cc); + } + else if (*cc == XCL_RANGE) + { + cc ++; + GETCHARINCTEST(c, cc); + GETCHARINCTEST(c, cc); + } + else + { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); + cc++; + if (*cc == PT_SC) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + if (cc[-1] == XCL_NOTPROP) + invertcmp ^= 0x1; + jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (int)cc[1]); + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + cc += 2; + } } - if (needsscript) - scriptreg = TMP3; - OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); + cc = ccbegin; } - else if (needstype && needsscript) - scriptreg = TMP3; - /* In all other cases only one of them was specified, and that can goes to TMP1. */ - if (needsscript) + if (needschar) { - if (scriptreg == TMP1) + OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); + } + + if (needstype) + { + if (!needschar) { - OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); } else { OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); - OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + typereg = RETURN_ADDR; } } } @@ -5061,20 +5781,15 @@ while (*cc != XCL_END) #ifdef SUPPORT_UCP else { + SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); if (*cc == XCL_NOTPROP) invertcmp ^= 0x1; cc++; switch(*cc) { case PT_ANY: - if (list != backtracks) - { - if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0)) - continue; - } - else if (cc[-1] == XCL_NOTPROP) - continue; - jump = JUMP(SLJIT_JUMP); + if (!invertcmp) + jump = JUMP(SLJIT_JUMP); break; case PT_LAMP: @@ -5098,7 +5813,8 @@ while (*cc != XCL_END) break; case PT_SC: - jump = CMP(SLJIT_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]); + compares++; + /* Do nothing. */ break; case PT_SPACE: @@ -5264,31 +5980,254 @@ while (*cc != XCL_END) OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); break; + + default: + SLJIT_ASSERT_STOP(); + break; } cc += 2; } -#endif +#endif + + if (jump != NULL) + add_jump(compiler, compares > 0 ? list : backtracks, jump); + } + +if (found != NULL) + set_jumps(found, LABEL()); +} + +#undef SET_TYPE_OFFSET +#undef SET_CHAR_OFFSET + +#endif + +static pcre_uchar *compile_simple_assertion_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) +{ +DEFINE_COMPILER; +int length; +struct sljit_jump *jump[4]; +#ifdef SUPPORT_UTF +struct sljit_label *label; +#endif /* SUPPORT_UTF */ + +switch(type) + { + case OP_SOD: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_SOM: + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); + return cc; + + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + + case OP_EODN: + /* Requires rather complex checks. */ + jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == JIT_COMPILE) + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); + OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); + add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else if (common->nltype == NLTYPE_FIXED) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); + } + else + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); + jump[2] = JUMP(SLJIT_GREATER); + add_jump(compiler, backtracks, JUMP(SLJIT_LESS)); + /* Equal. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[1]); + if (common->nltype == NLTYPE_ANYCRLF) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); + } + else + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); + } + JUMPHERE(jump[2]); + JUMPHERE(jump[3]); + } + JUMPHERE(jump[0]); + check_partial(common, FALSE); + return cc; + + case OP_EOD: + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + return cc; + + case OP_DOLL: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + + if (!common->endonly) + compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks); + else + { + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + check_partial(common, FALSE); + } + return cc; + + case OP_DOLLM: + jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + check_partial(common, FALSE); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); + + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (common->mode == JIT_COMPILE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); + else + { + jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); + /* STR_PTR = STR_END - IN_UCHARS(1) */ + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + check_partial(common, TRUE); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + JUMPHERE(jump[1]); + } + + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + peek_char(common, common->nlmax); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; - if (jump != NULL) - add_jump(compiler, compares > 0 ? list : backtracks, jump); - } + case OP_CIRC: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + return cc; -if (found != NULL) - set_jumps(found, LABEL()); -} + case OP_CIRCM: + OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + jump[0] = JUMP(SLJIT_JUMP); + JUMPHERE(jump[1]); -#undef SET_TYPE_OFFSET -#undef SET_CHAR_OFFSET + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + if (common->nltype == NLTYPE_FIXED && common->newline > 255) + { + OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); + } + else + { + skip_char_back(common); + read_char_range(common, common->nlmin, common->nlmax, TRUE); + check_newlinechar(common, common->nltype, backtracks, FALSE); + } + JUMPHERE(jump[0]); + return cc; + case OP_REVERSE: + length = GET(cc, 0); + if (length == 0) + return cc + LINK_SIZE; + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +#ifdef SUPPORT_UTF + if (common->utf) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); + label = LABEL(); + add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); + skip_char_back(common); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else #endif + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0)); + } + check_start_used_ptr(common); + return cc + LINK_SIZE; + } +SLJIT_ASSERT_STOP(); +return cc; +} -static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) +static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks, BOOL check_str_ptr) { DEFINE_COMPILER; int length; unsigned int c, oc, bit; compare_context context; -struct sljit_jump *jump[4]; +struct sljit_jump *jump[3]; jump_list *end_list; #ifdef SUPPORT_UTF struct sljit_label *label; @@ -5299,30 +6238,13 @@ pcre_uchar propdata[5]; switch(type) { - case OP_SOD: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; - - case OP_SOM: - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0)); - return cc; - - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - case OP_NOT_DIGIT: case OP_DIGIT: /* Digits are usually 0-9, so it is worth to optimize them. */ - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE)) + if (common->utf && is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_digit, FALSE)) read_char7_type(common, type == OP_NOT_DIGIT); else #endif @@ -5334,9 +6256,10 @@ switch(type) case OP_NOT_WHITESPACE: case OP_WHITESPACE: - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE)) + if (common->utf && is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_space, FALSE)) read_char7_type(common, type == OP_NOT_WHITESPACE); else #endif @@ -5347,9 +6270,10 @@ switch(type) case OP_NOT_WORDCHAR: case OP_WORDCHAR: - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE)) + if (common->utf && is_char7_bitset((const sljit_u8 *)common->ctypes - cbit_length + cbit_word, FALSE)) read_char7_type(common, type == OP_NOT_WORDCHAR); else #endif @@ -5359,7 +6283,8 @@ switch(type) return cc; case OP_ANY: - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); read_char_range(common, common->nlmin, common->nlmax, TRUE); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { @@ -5380,7 +6305,8 @@ switch(type) return cc; case OP_ALLANY: - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); #ifdef SUPPORT_UTF if (common->utf) { @@ -5389,7 +6315,7 @@ switch(type) #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 #if defined COMPILE_PCRE8 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); #elif defined COMPILE_PCRE16 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); @@ -5402,265 +6328,112 @@ switch(type) JUMPHERE(jump[0]); #endif /* COMPILE_PCRE[8|16] */ return cc; - } -#endif - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - return cc; - - case OP_ANYBYTE: - detect_partial_match(common, backtracks); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - return cc; - -#ifdef SUPPORT_UTF -#ifdef SUPPORT_UCP - case OP_NOTPROP: - case OP_PROP: - propdata[0] = XCL_HASPROP; - propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; - propdata[2] = cc[0]; - propdata[3] = cc[1]; - propdata[4] = XCL_END; - compile_xclass_matchingpath(common, propdata, backtracks); - return cc + 2; -#endif -#endif - - case OP_ANYNL: - detect_partial_match(common, backtracks); - read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); - jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - /* We don't need to handle soft partial matching case. */ - end_list = NULL; - if (common->mode != JIT_PARTIAL_HARD_COMPILE) - add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - else - check_str_end(common, &end_list); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - jump[2] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[0]); - check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); - set_jumps(end_list, LABEL()); - JUMPHERE(jump[1]); - JUMPHERE(jump[2]); - return cc; - - case OP_NOT_HSPACE: - case OP_HSPACE: - detect_partial_match(common, backtracks); - read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); - add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - - case OP_NOT_VSPACE: - case OP_VSPACE: - detect_partial_match(common, backtracks); - read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); - add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); - return cc; - -#ifdef SUPPORT_UCP - case OP_EXTUNI: - detect_partial_match(common, backtracks); - read_char(common); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - /* Optimize register allocation: use a real register. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); - - label = LABEL(); - jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); - read_char(common); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); - - OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); - OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); - OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - JUMPTO(SLJIT_NOT_ZERO, label); - - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); - JUMPHERE(jump[0]); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); - - if (common->mode == JIT_PARTIAL_HARD_COMPILE) - { - jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - /* Since we successfully read a char above, partial matching must occure. */ - check_partial(common, TRUE); - JUMPHERE(jump[0]); - } - return cc; -#endif - - case OP_EODN: - /* Requires rather complex checks. */ - jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == JIT_COMPILE) - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL); - add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else if (common->nltype == NLTYPE_FIXED) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline)); - } - else - { - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); - jump[2] = JUMP(SLJIT_GREATER); - add_jump(compiler, backtracks, JUMP(SLJIT_LESS)); - /* Equal. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - - JUMPHERE(jump[1]); - if (common->nltype == NLTYPE_ANYCRLF) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL)); - } - else - { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); - add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); - add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); - } - JUMPHERE(jump[2]); - JUMPHERE(jump[3]); - } - JUMPHERE(jump[0]); - check_partial(common, FALSE); - return cc; - - case OP_EOD: - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); + } +#endif + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); return cc; - case OP_CIRC: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0)); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + case OP_ANYBYTE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); return cc; - case OP_CIRCM: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); +#ifdef SUPPORT_UTF +#ifdef SUPPORT_UCP + case OP_NOTPROP: + case OP_PROP: + propdata[0] = XCL_HASPROP; + propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP; + propdata[2] = cc[0]; + propdata[3] = cc[1]; + propdata[4] = XCL_END; + if (check_str_ptr) + detect_partial_match(common, backtracks); + compile_xclass_matchingpath(common, propdata, backtracks); + return cc + 2; +#endif +#endif - add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } + case OP_ANYNL: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); + jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); + /* We don't need to handle soft partial matching case. */ + end_list = NULL; + if (common->mode != JIT_PARTIAL_HARD_COMPILE) + add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); else - { - skip_char_back(common); - read_char_range(common, common->nlmin, common->nlmax, TRUE); - check_newlinechar(common, common->nltype, backtracks, FALSE); - } + check_str_end(common, &end_list); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump[2] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); + check_newlinechar(common, common->bsr_nltype, backtracks, FALSE); + set_jumps(end_list, LABEL()); + JUMPHERE(jump[1]); + JUMPHERE(jump[2]); return cc; - case OP_DOLL: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + case OP_NOT_HSPACE: + case OP_HSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; - if (!common->endonly) - compile_char1_matchingpath(common, OP_EODN, cc, backtracks); - else - { - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); - check_partial(common, FALSE); - } + case OP_NOT_VSPACE: + case OP_VSPACE: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; - case OP_DOLLM: - jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); - check_partial(common, FALSE); - jump[0] = JUMP(SLJIT_JUMP); - JUMPHERE(jump[1]); +#ifdef SUPPORT_UCP + case OP_EXTUNI: + if (check_str_ptr) + detect_partial_match(common, backtracks); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); + /* Optimize register allocation: use a real register. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); + OP1(SLJIT_MOV_U8, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); - if (common->nltype == NLTYPE_FIXED && common->newline > 255) - { - OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (common->mode == JIT_COMPILE) - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0)); - else - { - jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); - /* STR_PTR = STR_END - IN_UCHARS(1) */ - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - check_partial(common, TRUE); - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(jump[1]); - } + label = LABEL(); + jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common); + add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); - OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff)); - } - else + OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); + OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); + OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + JUMPTO(SLJIT_NOT_ZERO, label); + + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + JUMPHERE(jump[0]); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); + + if (common->mode == JIT_PARTIAL_HARD_COMPILE) { - peek_char(common, common->nlmax); - check_newlinechar(common, common->nltype, backtracks, FALSE); + jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0); + /* Since we successfully read a char above, partial matching must occure. */ + check_partial(common, TRUE); + JUMPHERE(jump[0]); } - JUMPHERE(jump[0]); return cc; +#endif case OP_CHAR: case OP_CHARI: @@ -5668,7 +6441,8 @@ switch(type) #ifdef SUPPORT_UTF if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); #endif - if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) + if (common->mode == JIT_COMPILE && check_str_ptr + && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) { OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); @@ -5681,7 +6455,8 @@ switch(type) return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); } - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); #ifdef SUPPORT_UTF if (common->utf) { @@ -5713,7 +6488,8 @@ switch(type) case OP_NOT: case OP_NOTI: - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); length = 1; #ifdef SUPPORT_UTF if (common->utf) @@ -5722,7 +6498,7 @@ switch(type) c = *cc; if (c < 128) { - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); if (type == OP_NOT || !char_has_othercase(common, cc)) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); else @@ -5774,16 +6550,17 @@ switch(type) case OP_CLASS: case OP_NCLASS: - detect_partial_match(common, backtracks); + if (check_str_ptr) + detect_partial_match(common, backtracks); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 - bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255; + bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; read_char_range(common, 0, bit, type == OP_NCLASS); #else read_char_range(common, 0, 255, type == OP_NCLASS); #endif - if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks)) + if (check_class_ranges(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) return cc + 32 / sizeof(pcre_uchar); #if defined SUPPORT_UTF && defined COMPILE_PCRE8 @@ -5808,7 +6585,7 @@ switch(type) OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); @@ -5817,40 +6594,15 @@ switch(type) if (jump[0] != NULL) JUMPHERE(jump[0]); #endif - return cc + 32 / sizeof(pcre_uchar); #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 case OP_XCLASS: + if (check_str_ptr) + detect_partial_match(common, backtracks); compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); return cc + GET(cc, 0) - 1; #endif - - case OP_REVERSE: - length = GET(cc, 0); - if (length == 0) - return cc + LINK_SIZE; - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -#ifdef SUPPORT_UTF - if (common->utf) - { - OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); - label = LABEL(); - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); - skip_char_back(common); - OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else -#endif - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0)); - } - check_start_used_ptr(common); - return cc + LINK_SIZE; } SLJIT_ASSERT_STOP(); return cc; @@ -5919,7 +6671,7 @@ if (context.length > 0) } /* A non-fixed length character will be checked if length == 0. */ -return compile_char1_matchingpath(common, *cc, cc + 1, backtracks); +return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE); } /* Forward definitions. */ @@ -6094,7 +6846,7 @@ pcre_uchar *ccbegin = cc; int min = 0, max = 0; BOOL minimize; -PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); +PUSH_BACKTRACK(sizeof(ref_iterator_backtrack), cc, NULL); if (ref) offset = GET2(cc, 1) << 1; @@ -6214,7 +6966,7 @@ if (!minimize) } JUMPHERE(zerolength); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); count_match(common); return cc; @@ -6260,7 +7012,7 @@ else } } -BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); +BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); if (max > 0) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); @@ -6274,7 +7026,7 @@ if (min > 1) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(ref_iterator_backtrack)->matchingpath); } else if (max > 0) OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); @@ -6419,8 +7171,8 @@ allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); SLJIT_ASSERT(common->capture_last_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]); -OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0); /* These pointer sized fields temporarly stores internal variables. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)); @@ -6429,8 +7181,8 @@ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0); if (common->mark_ptr != 0) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr)); -OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2)); -OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE)); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2)); +OP1(SLJIT_MOV_S32, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0); /* Needed to save important temporary registers. */ @@ -6438,7 +7190,7 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0); OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE); GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout)); -OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); +OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0); free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw)); @@ -6455,6 +7207,32 @@ return cc + 2 + 2 * LINK_SIZE; #undef CALLOUT_ARG_SIZE #undef CALLOUT_ARG_OFFSET +static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(pcre_uchar *cc) +{ +while (TRUE) + { + switch (*cc) + { + case OP_NOT_WORD_BOUNDARY: + case OP_WORD_BOUNDARY: + case OP_CIRC: + case OP_CIRCM: + case OP_DOLL: + case OP_DOLLM: + case OP_CALLOUT: + case OP_ALT: + cc += PRIV(OP_lengths)[*cc]; + break; + + case OP_KET: + return FALSE; + + default: + return TRUE; + } + } +} + static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) { DEFINE_COMPILER; @@ -6511,15 +7289,28 @@ if (bra == OP_BRAMINZERO) if (framesize < 0) { - extrasize = needs_control_head ? 2 : 1; + extrasize = 1; + if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE)) + extrasize = 0; + + if (needs_control_head) + extrasize++; + if (framesize == no_frame) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0); - allocate_stack(common, extrasize); + + if (extrasize > 0) + allocate_stack(common, extrasize); + if (needs_control_head) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + + if (extrasize > 0) + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (needs_control_head) { + SLJIT_ASSERT(extrasize == 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); } @@ -6528,12 +7319,14 @@ else { extrasize = needs_control_head ? 3 : 2; allocate_stack(common, framesize + extrasize); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); if (needs_control_head) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (needs_control_head) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); @@ -6542,6 +7335,7 @@ else } else OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE); } @@ -6565,7 +7359,7 @@ while (1) altbacktrack.top = NULL; altbacktrack.topbacktracks = NULL; - if (*ccbegin == OP_ALT) + if (*ccbegin == OP_ALT && extrasize > 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); altbacktrack.cc = ccbegin; @@ -6594,8 +7388,9 @@ while (1) { if (framesize == no_frame) OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - else + else if (extrasize > 0) free_stack(common, extrasize); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0); } @@ -6621,7 +7416,10 @@ while (1) { /* We know that STR_PTR was stored on the top of the stack. */ if (conditional) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); + { + if (extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0); + } else if (bra == OP_BRAZERO) { if (framesize < 0) @@ -6698,7 +7496,7 @@ if (needs_control_head) if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { /* Assert is failed. */ - if (conditional || bra == OP_BRAZERO) + if ((conditional && extrasize > 0) || bra == OP_BRAZERO) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (framesize < 0) @@ -6710,7 +7508,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } - else + else if (extrasize > 0) free_stack(common, extrasize); } else @@ -6735,7 +7533,9 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) if (framesize < 0) { /* We know that STR_PTR was stored on the top of the stack. */ - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); + if (extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw)); + /* Keep the STR_PTR on the top of the stack. */ if (bra == OP_BRAZERO) { @@ -6798,14 +7598,16 @@ else /* AssertNot is successful. */ if (framesize < 0) { - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (extrasize > 0) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + if (bra != OP_BRA) { if (extrasize == 2) free_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } - else + else if (extrasize > 0) free_stack(common, extrasize); } else @@ -6867,7 +7669,9 @@ if (framesize < 0) stacksize = needs_control_head ? 1 : 0; if (ket != OP_KET || has_alternatives) stacksize++; - free_stack(common, stacksize); + + if (stacksize > 0) + free_stack(common, stacksize); } if (needs_control_head) @@ -7513,9 +8317,13 @@ while (*cc == OP_ALT) cc += GET(cc, 1); cc += 1 + LINK_SIZE; -/* Temporarily encoding the needs_control_head in framesize. */ if (opcode == OP_ONCE) + { + /* We temporarily encode the needs_control_head in the lowest bit. + Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns + the same value for small signed numbers (including negative numbers). */ BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); + } return cc + repeat_length; } @@ -7802,11 +8610,13 @@ count_match(common); return cc + 1 + LINK_SIZE; } -static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *max, int *min, pcre_uchar **end) +static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, sljit_u32 *max, sljit_u32 *exact, pcre_uchar **end) { int class_len; *opcode = *cc; +*exact = 0; + if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO) { cc++; @@ -7834,7 +8644,7 @@ else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO) { cc++; *opcode -= OP_TYPESTAR - OP_STAR; - *type = 0; + *type = OP_END; } else { @@ -7843,60 +8653,105 @@ else cc++; class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0); *opcode = cc[class_len - 1]; + if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY) { *opcode -= OP_CRSTAR - OP_STAR; - if (end != NULL) - *end = cc + class_len; + *end = cc + class_len; + + if (*opcode == OP_PLUS || *opcode == OP_MINPLUS) + { + *exact = 1; + *opcode -= OP_PLUS - OP_STAR; + } } else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY) { *opcode -= OP_CRPOSSTAR - OP_POSSTAR; - if (end != NULL) - *end = cc + class_len; + *end = cc + class_len; + + if (*opcode == OP_POSPLUS) + { + *exact = 1; + *opcode = OP_POSSTAR; + } } else { SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE); *max = GET2(cc, (class_len + IMM2_SIZE)); - *min = GET2(cc, class_len); + *exact = GET2(cc, class_len); - if (*min == 0) + if (*max == 0) { - SLJIT_ASSERT(*max != 0); - *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO); + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSSTAR; + else + *opcode -= OP_CRRANGE - OP_STAR; } - if (*max == *min) - *opcode = OP_EXACT; - - if (end != NULL) - *end = cc + class_len + 2 * IMM2_SIZE; + else + { + *max -= *exact; + if (*max == 0) + *opcode = OP_EXACT; + else if (*max == 1) + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSQUERY; + else + *opcode -= OP_CRRANGE - OP_QUERY; + } + else + { + if (*opcode == OP_CRPOSRANGE) + *opcode = OP_POSUPTO; + else + *opcode -= OP_CRRANGE - OP_UPTO; + } + } + *end = cc + class_len + 2 * IMM2_SIZE; } return cc; } -if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO) +switch(*opcode) { + case OP_EXACT: + *exact = GET2(cc, 0); + cc += IMM2_SIZE; + break; + + case OP_PLUS: + case OP_MINPLUS: + *exact = 1; + *opcode -= OP_PLUS - OP_STAR; + break; + + case OP_POSPLUS: + *exact = 1; + *opcode = OP_POSSTAR; + break; + + case OP_UPTO: + case OP_MINUPTO: + case OP_POSUPTO: *max = GET2(cc, 0); cc += IMM2_SIZE; + break; } -if (*type == 0) +if (*type == OP_END) { *type = *cc; - if (end != NULL) - *end = next_opcode(common, cc); + *end = next_opcode(common, cc); cc++; return cc; } -if (end != NULL) - { - *end = cc + 1; +*end = cc + 1; #ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); +if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc); #endif - } return cc; } @@ -7906,9 +8761,15 @@ DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; pcre_uchar type; -int max = -1, min = -1; +sljit_u32 max = 0, exact; +BOOL fast_fail; +sljit_s32 fast_str_ptr; +BOOL charpos_enabled; +pcre_uchar charpos_char; +unsigned int charpos_othercasebit; pcre_uchar *end; -jump_list *nomatch = NULL; +jump_list *no_match = NULL; +jump_list *no_char1_match = NULL; struct sljit_jump *jump = NULL; struct sljit_label *label; int private_data_ptr = PRIVATE_DATA(cc); @@ -7917,83 +8778,92 @@ int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); int tmp_base, tmp_offset; -PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); +PUSH_BACKTRACK(sizeof(char_iterator_backtrack), cc, NULL); + +fast_str_ptr = PRIVATE_DATA(cc + 1); +fast_fail = TRUE; -cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end); +SLJIT_ASSERT(common->fast_forward_bc_ptr == NULL || fast_str_ptr == 0 || cc == common->fast_forward_bc_ptr); -switch(type) +if (cc == common->fast_forward_bc_ptr) + fast_fail = FALSE; +else if (common->fast_fail_start_ptr == 0) + fast_str_ptr = 0; + +SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || fast_str_ptr == 0 + || (fast_str_ptr >= common->fast_fail_start_ptr && fast_str_ptr <= common->fast_fail_end_ptr)); + +cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); + +if (type != OP_EXTUNI) { - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_ANYBYTE: - case OP_ANYNL: - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_CLASS: - case OP_NCLASS: tmp_base = TMP3; tmp_offset = 0; - break; - - default: - SLJIT_ASSERT_STOP(); - /* Fall through. */ - - case OP_EXTUNI: - case OP_XCLASS: - case OP_NOTPROP: - case OP_PROP: + } +else + { tmp_base = SLJIT_MEM1(SLJIT_SP); tmp_offset = POSSESSIVE0; - break; } +if (fast_fail && fast_str_ptr != 0) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), fast_str_ptr)); + +/* Handle fixed part first. */ +if (exact > 1) + { + SLJIT_ASSERT(fast_str_ptr == 0); + if (common->mode == JIT_COMPILE +#ifdef SUPPORT_UTF + && !common->utf +#endif + ) + { + OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + { + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + } +else if (exact == 1) + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + switch(opcode) { case OP_STAR: - case OP_PLUS: case OP_UPTO: - case OP_CRRANGE: + SLJIT_ASSERT(fast_str_ptr == 0 || opcode == OP_STAR); + if (type == OP_ANYNL || type == OP_EXTUNI) { SLJIT_ASSERT(private_data_ptr == 0); - if (opcode == OP_STAR || opcode == OP_UPTO) - { - allocate_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); - } - else - { - allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - } + SLJIT_ASSERT(fast_str_ptr == 0); - if (opcode == OP_UPTO || opcode == OP_CRRANGE) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0); + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); + + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, max); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - if (opcode == OP_UPTO || opcode == OP_CRRANGE) + compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); + if (opcode == OP_UPTO) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - if (opcode == OP_CRRANGE && min > 0) - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label); - if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0)) - jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + jump = JUMP(SLJIT_ZERO); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0); } @@ -8006,134 +8876,268 @@ switch(opcode) } else { - if (opcode == OP_PLUS) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (opcode <= OP_PLUS) + charpos_enabled = FALSE; + charpos_char = 0; + charpos_othercasebit = 0; + + if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI)) + { + charpos_enabled = TRUE; +#ifdef SUPPORT_UTF + charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]); +#endif + if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1)) + { + charpos_othercasebit = char_get_othercase_bit(common, end + 1); + if (charpos_othercasebit == 0) + charpos_enabled = FALSE; + } + + if (charpos_enabled) + { + charpos_char = end[1]; + /* Consumpe the OP_CHAR opcode. */ + end += 2; +#if defined COMPILE_PCRE8 + SLJIT_ASSERT((charpos_othercasebit >> 8) == 0); +#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SLJIT_ASSERT((charpos_othercasebit >> 9) == 0); + if ((charpos_othercasebit & 0x100) != 0) + charpos_othercasebit = (charpos_othercasebit & 0xff) << 8; +#endif + if (charpos_othercasebit != 0) + charpos_char |= charpos_othercasebit; + + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char; + BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit; + } + } + + if (charpos_enabled) + { + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1); + + /* Search the first instance of charpos_char. */ + jump = JUMP(SLJIT_JUMP); + label = LABEL(); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); + } + compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + JUMPHERE(jump); + + detect_partial_match(common, &backtrack->topbacktracks); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + + if (private_data_ptr == 0) + allocate_stack(common, 2); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - else - OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &nomatch); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (opcode <= OP_PLUS) - JUMPTO(SLJIT_JUMP, label); - else if (opcode == OP_CRRANGE && max == 0) + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + add_jump(compiler, &no_match, JUMP(SLJIT_ZERO)); + } + + /* Search the last instance of charpos_char. */ + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, FALSE); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + detect_partial_match(common, &no_match); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + if (charpos_othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); + if (opcode == OP_STAR) + { + CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } + else + { + jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPHERE(jump); + } + + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + } +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + else if (common->utf) { - OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1); - JUMPTO(SLJIT_JUMP, label); + if (private_data_ptr == 0) + allocate_stack(common, 2); + + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + else + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); } +#endif else { - OP1(SLJIT_MOV, TMP1, 0, base, offset1); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, base, offset1, TMP1, 0); - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, max + 1, label); + if (private_data_ptr == 0) + allocate_stack(common, 2); + + OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); + if (opcode == OP_UPTO) + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + + label = LABEL(); + detect_partial_match(common, &no_match); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); + if (opcode == OP_UPTO) + { + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + } + else + JUMPTO(SLJIT_JUMP, label); + + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); } - set_jumps(nomatch, LABEL()); - if (opcode == OP_CRRANGE) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS, base, offset1, SLJIT_IMM, min + 1)); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); } - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; case OP_MINSTAR: - case OP_MINPLUS: - if (opcode == OP_MINPLUS) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); if (private_data_ptr == 0) allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); break; case OP_MINUPTO: - case OP_CRMINRANGE: + SLJIT_ASSERT(fast_str_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 2); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); - if (opcode == OP_CRMINRANGE) - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, max + 1); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; case OP_QUERY: case OP_MINQUERY: + SLJIT_ASSERT(fast_str_ptr == 0); if (private_data_ptr == 0) allocate_stack(common, 1); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); if (opcode == OP_QUERY) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + compile_char1_matchingpath(common, type, cc, &BACKTRACK_AS(char_iterator_backtrack)->u.backtracks, TRUE); + BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL(); break; case OP_EXACT: - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); break; case OP_POSSTAR: - case OP_POSPLUS: - case OP_POSUPTO: - if (opcode == OP_POSPLUS) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - if (opcode == OP_POSUPTO) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &nomatch); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - if (opcode != OP_POSUPTO) - JUMPTO(SLJIT_JUMP, label); - else +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, label); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); + break; } - set_jumps(nomatch, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); - break; - - case OP_POSQUERY: - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - compile_char1_matchingpath(common, type, cc, &nomatch); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - set_jumps(nomatch, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); +#endif + label = LABEL(); + detect_partial_match(common, &no_match); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); + JUMPTO(SLJIT_JUMP, label); + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + if (fast_str_ptr != 0) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0); break; - case OP_CRPOSRANGE: - /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */ - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min); + case OP_POSUPTO: + SLJIT_ASSERT(fast_str_ptr == 0); +#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 + if (common->utf) + { + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); + label = LABEL(); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + set_jumps(no_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); + break; + } +#endif + OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + detect_partial_match(common, &no_match); + compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE); OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_char1_match, LABEL()); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + set_jumps(no_match, LABEL()); + break; - if (max != 0) - { - SLJIT_ASSERT(max - min > 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max - min); - } + case OP_POSQUERY: + SLJIT_ASSERT(fast_str_ptr == 0); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - label = LABEL(); - compile_char1_matchingpath(common, type, cc, &nomatch); + compile_char1_matchingpath(common, type, cc, &no_match, TRUE); OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - if (max == 0) - JUMPTO(SLJIT_JUMP, label); - else - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - set_jumps(nomatch, LABEL()); + set_jumps(no_match, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); break; @@ -8174,9 +9178,9 @@ if (common->accept_label == NULL) else CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); +OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); +OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); if (common->accept_label == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); else @@ -8298,6 +9302,16 @@ while (cc < ccend) case OP_SOM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: + case OP_EODN: + case OP_EOD: + case OP_DOLL: + case OP_DOLLM: + case OP_CIRC: + case OP_CIRCM: + case OP_REVERSE: + cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + break; + case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: @@ -8315,16 +9329,9 @@ while (cc < ccend) case OP_NOT_VSPACE: case OP_VSPACE: case OP_EXTUNI: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: case OP_NOT: case OP_NOTI: - case OP_REVERSE: - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); break; case OP_SET_SOM: @@ -8341,7 +9348,7 @@ while (cc < ccend) if (common->mode == JIT_COMPILE) cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); break; case OP_STAR: @@ -8417,7 +9424,7 @@ while (cc < ccend) if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); break; #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 @@ -8425,7 +9432,7 @@ while (cc < ccend) if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); break; #endif @@ -8601,95 +9608,82 @@ DEFINE_COMPILER; pcre_uchar *cc = current->cc; pcre_uchar opcode; pcre_uchar type; -int max = -1, min = -1; +sljit_u32 max = 0, exact; struct sljit_label *label = NULL; struct sljit_jump *jump = NULL; jump_list *jumplist = NULL; +pcre_uchar *end; int private_data_ptr = PRIVATE_DATA(cc); int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP); int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); -cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL); +cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); switch(opcode) { case OP_STAR: - case OP_PLUS: case OP_UPTO: - case OP_CRRANGE: if (type == OP_ANYNL || type == OP_EXTUNI) { SLJIT_ASSERT(private_data_ptr == 0); - set_jumps(current->topbacktracks, LABEL()); + set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); } else { - if (opcode == OP_UPTO) - min = 0; - if (opcode <= OP_PLUS) + if (CURRENT_AS(char_iterator_backtrack)->u.charpos.enabled) { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); + OP1(SLJIT_MOV, TMP2, 0, base, offset1); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + label = LABEL(); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0) + OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit); + CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); + skip_char_back(common); + CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label); } else { - OP1(SLJIT_MOV, TMP1, 0, base, offset1); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1); - OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); + skip_char_back(common); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); } - skip_char_back(common); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); - if (opcode == OP_CRRANGE) - set_jumps(current->topbacktracks, LABEL()); JUMPHERE(jump); if (private_data_ptr == 0) free_stack(common, 2); - if (opcode == OP_PLUS) - set_jumps(current->topbacktracks, LABEL()); } break; case OP_MINSTAR: - case OP_MINPLUS: OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - compile_char1_matchingpath(common, type, cc, &jumplist); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); set_jumps(jumplist, LABEL()); if (private_data_ptr == 0) free_stack(common, 1); - if (opcode == OP_MINPLUS) - set_jumps(current->topbacktracks, LABEL()); break; case OP_MINUPTO: - case OP_CRMINRANGE: - if (opcode == OP_CRMINRANGE) - { - label = LABEL(); - set_jumps(current->topbacktracks, label); - } + OP1(SLJIT_MOV, TMP1, 0, base, offset1); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - compile_char1_matchingpath(common, type, cc, &jumplist); + OP2(SLJIT_SUB | SLJIT_SET_E, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + add_jump(compiler, &jumplist, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, TMP1, 0, base, offset1); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, base, offset1, TMP1, 0); - - if (opcode == OP_CRMINRANGE) - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min + 1, label); - - if (opcode == OP_CRMINRANGE && max == 0) - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); - else - CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); set_jumps(jumplist, LABEL()); if (private_data_ptr == 0) @@ -8699,12 +9693,12 @@ switch(opcode) case OP_QUERY: OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(char_iterator_backtrack)->matchingpath); jump = JUMP(SLJIT_JUMP); - set_jumps(current->topbacktracks, LABEL()); + set_jumps(CURRENT_AS(char_iterator_backtrack)->u.backtracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); JUMPHERE(jump); if (private_data_ptr == 0) free_stack(common, 1); @@ -8714,8 +9708,8 @@ switch(opcode) OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - compile_char1_matchingpath(common, type, cc, &jumplist); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + compile_char1_matchingpath(common, type, cc, &jumplist, TRUE); + JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); set_jumps(jumplist, LABEL()); JUMPHERE(jump); if (private_data_ptr == 0) @@ -8723,11 +9717,6 @@ switch(opcode) break; case OP_EXACT: - case OP_POSPLUS: - case OP_CRPOSRANGE: - set_jumps(current->topbacktracks, LABEL()); - break; - case OP_POSSTAR: case OP_POSQUERY: case OP_POSUPTO: @@ -8737,6 +9726,8 @@ switch(opcode) SLJIT_ASSERT_STOP(); break; } + +set_jumps(current->topbacktracks, LABEL()); } static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -8754,12 +9745,12 @@ if ((type & 0x1) == 0) set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); - CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); return; } OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); -CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); +CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); set_jumps(current->topbacktracks, LABEL()); free_stack(common, ref ? 2 : 3); } @@ -9258,7 +10249,9 @@ else if (opcode == OP_ONCE) /* The STR_PTR must be released. */ stacksize++; } - free_stack(common, stacksize); + + if (stacksize > 0) + free_stack(common, stacksize); JUMPHERE(once); /* Restore previous private_data_ptr */ @@ -9688,8 +10681,8 @@ common->currententry->entry = LABEL(); set_jumps(common->currententry->calls, common->currententry->entry); sljit_emit_fast_enter(compiler, TMP2, 0); -allocate_stack(common, private_data_size + framesize + alternativesize); count_match(common); +allocate_stack(common, private_data_size + framesize + alternativesize); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head); if (needs_control_head) @@ -9795,7 +10788,7 @@ struct sljit_compiler *compiler; backtrack_common rootbacktrack; compiler_common common_data; compiler_common *common = &common_data; -const pcre_uint8 *tables = re->tables; +const sljit_u8 *tables = re->tables; pcre_study_data *study; int private_data_size; pcre_uchar *ccend; @@ -9907,7 +10900,7 @@ ccend = bracketend(common->start); /* Calculate the local space size on the stack. */ common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw); -common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1, compiler->allocator_data); +common->optimized_cbracket = (sljit_u8 *)SLJIT_MALLOC(re->top_bracket + 1, compiler->allocator_data); if (!common->optimized_cbracket) return; #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1 @@ -9942,15 +10935,10 @@ if (mode != JIT_COMPILE) common->hit_start = common->ovector_start; common->ovector_start += 2 * sizeof(sljit_sw); } - else - { - SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE); - common->needs_start_ptr = TRUE; - } } if ((re->options & PCRE_FIRSTLINE) != 0) { - common->first_line_end = common->ovector_start; + common->match_end_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD @@ -9961,14 +10949,12 @@ if (common->control_head_ptr != 0) common->control_head_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } -if (common->needs_start_ptr && common->has_set_som) +if (common->has_set_som) { /* Saving the real start pointer is necessary. */ common->start_ptr = common->ovector_start; common->ovector_start += sizeof(sljit_sw); } -else - common->needs_start_ptr = FALSE; /* Aligning ovector to even number of sljit words. */ if ((common->ovector_start & sizeof(sljit_sw)) != 0) @@ -9985,16 +10971,24 @@ SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); total_length = ccend - common->start; -common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)), compiler->allocator_data); +common->private_data_ptrs = (sljit_s32 *)SLJIT_MALLOC(total_length * (sizeof(sljit_s32) + (common->has_then ? 1 : 0)), compiler->allocator_data); if (!common->private_data_ptrs) { SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data); return; } -memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si)); +memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); set_private_data_ptrs(common, &private_data_size, ccend); +if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) + { + if (!detect_fast_forward_skip(common, &private_data_size) && !common->has_skip_in_assert_back) + detect_fast_fail(common, common->start, &private_data_size, 4); + } + +SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr); + if (private_data_size > SLJIT_MAX_LOCAL_SIZE) { SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data); @@ -10004,7 +10998,7 @@ if (private_data_size > SLJIT_MAX_LOCAL_SIZE) if (common->has_then) { - common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length); + common->then_offsets = (sljit_u8 *)(common->private_data_ptrs + total_length); memset(common->then_offsets, 0, total_length); set_then_offsets(common, common->start, NULL); } @@ -10031,12 +11025,15 @@ OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack)); -OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); +OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base)); OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0); +if (common->fast_fail_start_ptr < common->fast_fail_end_ptr) + reset_fast_fail(common); + if (mode == JIT_PARTIAL_SOFT_COMPILE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1); if (common->mark_ptr != 0) @@ -10047,19 +11044,19 @@ if (common->control_head_ptr != 0) /* Main part of the matching */ if ((re->options & PCRE_ANCHORED) == 0) { - mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0); + mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0); continue_match_label = LABEL(); /* Forward search if possible. */ if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) { - if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0)) + if (mode == JIT_COMPILE && fast_forward_first_n_chars(common)) ; else if ((re->flags & PCRE_FIRSTSET) != 0) - fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); + fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0); else if ((re->flags & PCRE_STARTLINE) != 0) - fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); + fast_forward_newline(common); else if (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0) - fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0); + fast_forward_start_bits(common, study->start_bits); } } else @@ -10080,14 +11077,11 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0); OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH); if (common->capture_last_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, -1); +if (common->fast_forward_bc_ptr != NULL) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), PRIVATE_DATA(common->fast_forward_bc_ptr + 1), STR_PTR, 0); -if (common->needs_start_ptr) - { - SLJIT_ASSERT(common->start_ptr != OVECTOR(0)); +if (common->start_ptr != OVECTOR(0)) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0); - } -else - SLJIT_ASSERT(common->start_ptr == OVECTOR(0)); /* Copy the beginning of the string. */ if (mode == JIT_PARTIAL_SOFT_COMPILE) @@ -10166,11 +11160,12 @@ if (mode == JIT_PARTIAL_SOFT_COMPILE) /* Check we have remaining characters. */ if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0) { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end); + SLJIT_ASSERT(common->match_end_ptr != 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); } -OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), + (common->fast_forward_bc_ptr != NULL) ? (PRIVATE_DATA(common->fast_forward_bc_ptr + 1)) : common->start_ptr); if ((re->options & PCRE_ANCHORED) == 0) { @@ -10181,12 +11176,7 @@ if ((re->options & PCRE_ANCHORED) == 0) /* There cannot be more newlines here. */ } else - { - if ((re->options & PCRE_FIRSTLINE) == 0) - CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop_label); - else - CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, mainloop_label); - } + CMPTO(SLJIT_LESS, STR_PTR, 0, ((re->options & PCRE_FIRSTLINE) == 0) ? STR_END : TMP1, 0, mainloop_label); } /* No more remaining characters. */ @@ -10205,15 +11195,18 @@ if (common->might_be_empty) { JUMPHERE(empty_match); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty)); CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart)); CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label); JUMPTO(SLJIT_JUMP, empty_match_backtrack_label); } +common->fast_forward_bc_ptr = NULL; +common->fast_fail_start_ptr = 0; +common->fast_fail_end_ptr = 0; common->currententry = common->entries; common->local_exit = TRUE; quit_label = common->quit_label; @@ -10395,7 +11388,7 @@ union { void *executable_func; jit_function call_executable_func; } convert_executable_func; -pcre_uint8 local_space[MACHINE_STACK_SIZE]; +sljit_u8 local_space[MACHINE_STACK_SIZE]; struct sljit_stack local_stack; local_stack.top = (sljit_sw)&local_space; @@ -10435,7 +11428,7 @@ arguments.begin = subject; arguments.end = subject + length; arguments.mark_ptr = NULL; /* JIT decreases this value less frequently than the interpreter. */ -arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); +arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (sljit_u32)(extra_data->match_limit); if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) arguments.limit_match = functions->limit_match; arguments.notbol = (options & PCRE_NOTBOL) != 0; @@ -10528,7 +11521,7 @@ arguments.begin = subject_ptr; arguments.end = subject_ptr + length; arguments.mark_ptr = NULL; /* JIT decreases this value less frequently than the interpreter. */ -arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit); +arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (sljit_u32)(extra_data->match_limit); if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match) arguments.limit_match = functions->limit_match; arguments.notbol = (options & PCRE_NOTBOL) != 0; diff --git a/pcre/pcre_jit_test.c b/pcre/pcre_jit_test.c index 17378957d62e2..9b61ec000fa93 100644 --- a/pcre/pcre_jit_test.c +++ b/pcre/pcre_jit_test.c @@ -242,13 +242,17 @@ static struct regression_test_case regression_test_cases[] = { { MA, 0, "a\\z", "aaa" }, { MA, 0 | F_NOMATCH, "a\\z", "aab" }, - /* Brackets. */ + /* Brackets and alternatives. */ { MUA, 0, "(ab|bb|cd)", "bacde" }, { MUA, 0, "(?:ab|a)(bc|c)", "ababc" }, { MUA, 0, "((ab|(cc))|(bb)|(?:cd|efg))", "abac" }, { CMUA, 0, "((aB|(Cc))|(bB)|(?:cd|EFg))", "AcCe" }, { MUA, 0, "((ab|(cc))|(bb)|(?:cd|ebg))", "acebebg" }, { MUA, 0, "(?:(a)|(?:b))(cc|(?:d|e))(a|b)k", "accabdbbccbk" }, + { MUA, 0, "\xc7\x82|\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" }, + { MUA, 0, "=\xc7\x82|#\xc6\x82", "\xf1\x83\x82\x82=\xc7\x82\xc7\x83" }, + { MUA, 0, "\xc7\x82\xc7\x83|\xc6\x82\xc6\x82", "\xf1\x83\x82\x82\xc7\x82\xc7\x83" }, + { MUA, 0, "\xc6\x82\xc6\x82|\xc7\x83\xc7\x83|\xc8\x84\xc8\x84", "\xf1\x83\x82\x82\xc8\x84\xc8\x84" }, /* Greedy and non-greedy ? operators. */ { MUA, 0, "(?:a)?a", "laab" }, @@ -318,6 +322,14 @@ static struct regression_test_case regression_test_cases[] = { { CMUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, { MUA, 0, "[^\xe1\xbd\xb8][^\xc3\xa9]", "\xe1\xbd\xb8\xe1\xbf\xb8\xc3\xa9\xc3\x89#" }, { MUA, 0, "[^\xe1\xbd\xb8]{3,}?", "##\xe1\xbd\xb8#\xe1\xbd\xb8#\xc3\x89#\xe1\xbd\xb8" }, + { MUA, 0, "\\d+123", "987654321,01234" }, + { MUA, 0, "abcd*|\\w+xy", "aaaaa,abxyz" }, + { MUA, 0, "(?:abc|((?:amc|\\b\\w*xy)))", "aaaaa,abxyz" }, + { MUA, 0, "a(?R)|([a-z]++)#", ".abcd.abcd#."}, + { MUA, 0, "a(?R)|([a-z]++)#", ".abcd.mbcd#."}, + { MUA, 0, ".[ab]*.", "xx" }, + { MUA, 0, ".[ab]*a", "xxa" }, + { MUA, 0, ".[ab]?.", "xx" }, /* Bracket repeats with limit. */ { MUA, 0, "(?:(ab){2}){5}M", "abababababababababababM" }, @@ -574,6 +586,16 @@ static struct regression_test_case regression_test_cases[] = { { MUA, 0, "(?:(?=.)??[a-c])+m", "abacdcbacacdcaccam" }, { MUA, 0, "((?!a)?(?!([^a]))?)+$", "acbab" }, { MUA, 0, "((?!a)?\?(?!([^a]))?\?)+$", "acbab" }, + { MUA, 0, "a(?=(?C)\\B)b", "ab" }, + { MUA, 0, "a(?!(?C)\\B)bb|ab", "abb" }, + { MUA, 0, "a(?=\\b|(?C)\\B)b", "ab" }, + { MUA, 0, "a(?!\\b|(?C)\\B)bb|ab", "abb" }, + { MUA, 0, "c(?(?=(?C)\\B)ab|a)", "cab" }, + { MUA, 0, "c(?(?!(?C)\\B)ab|a)", "cab" }, + { MUA, 0, "c(?(?=\\b|(?C)\\B)ab|a)", "cab" }, + { MUA, 0, "c(?(?!\\b|(?C)\\B)ab|a)", "cab" }, + { MUA, 0, "a(?=)b", "ab" }, + { MUA, 0 | F_NOMATCH, "a(?!)b", "ab" }, /* Not empty, ACCEPT, FAIL */ { MUA | PCRE_NOTEMPTY, 0 | F_NOMATCH, "a*", "bcx" }, @@ -664,6 +686,7 @@ static struct regression_test_case regression_test_cases[] = { { PCRE_MULTILINE | PCRE_UTF8 | PCRE_NEWLINE_CRLF | PCRE_FIRSTLINE, 1, ".", "\r\n" }, { PCRE_FIRSTLINE | PCRE_NEWLINE_LF | PCRE_DOTALL, 0 | F_NOMATCH, "ab.", "ab" }, { MUA | PCRE_FIRSTLINE, 1 | F_NOMATCH, "^[a-d0-9]", "\nxx\nd" }, + { PCRE_NEWLINE_ANY | PCRE_FIRSTLINE | PCRE_DOTALL, 0, "....a", "012\n0a" }, /* Recurse. */ { MUA, 0, "(a)(?1)", "aa" }, @@ -798,6 +821,9 @@ static struct regression_test_case regression_test_cases[] = { /* (*SKIP) verb. */ { MUA, 0 | F_NOMATCH, "(?=a(*SKIP)b)ab|ad", "ad" }, + { MUA, 0, "(\\w+(*SKIP)#)", "abcd,xyz#," }, + { MUA, 0, "\\w+(*SKIP)#|mm", "abcd,xyz#," }, + { MUA, 0 | F_NOMATCH, "b+(?<=(*SKIP)#c)|b+", "#bbb" }, /* (*THEN) verb. */ { MUA, 0, "((?:a(*THEN)|aab)(*THEN)c|a+)+m", "aabcaabcaabcaabcnacm" }, @@ -1534,10 +1560,10 @@ static int regression_tests(void) is_successful = 0; } #endif -#if defined SUPPORT_PCRE16 && defined SUPPORT_PCRE16 - if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector16_1[i] || ovector16_1[i] != ovector16_2[i]) { - printf("\n16 and 16 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", - i, ovector16_1[i], ovector16_2[i], ovector16_1[i], ovector16_2[i], +#if defined SUPPORT_PCRE16 && defined SUPPORT_PCRE32 + if (ovector16_1[i] != ovector16_2[i] || ovector16_1[i] != ovector32_1[i] || ovector16_1[i] != ovector32_2[i]) { + printf("\n16 and 32 bit: Ovector[%d] value differs(J16:%d,I16:%d,J32:%d,I32:%d): [%d] '%s' @ '%s' \n", + i, ovector16_1[i], ovector16_2[i], ovector32_1[i], ovector32_2[i], total, current->pattern, current->input); is_successful = 0; } diff --git a/pcre/pcre_study.c b/pcre/pcre_study.c index 7fd0ba0b3d806..d9d4960d84ecb 100644 --- a/pcre/pcre_study.c +++ b/pcre/pcre_study.c @@ -1371,7 +1371,7 @@ do for (c = 0; c < 16; c++) start_bits[c] |= map[c]; for (c = 128; c < 256; c++) { - if ((map[c/8] && (1 << (c&7))) != 0) + if ((map[c/8] & (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ diff --git a/pcre/pcrecpp.cc b/pcre/pcrecpp.cc index c595cbcab5c4a..d09c9abc51682 100644 --- a/pcre/pcrecpp.cc +++ b/pcre/pcrecpp.cc @@ -66,7 +66,7 @@ Arg RE::no_arg((void*)NULL); // inclusive test if we ever needed it. (Note that not only the // __attribute__ syntax, but also __USER_LABEL_PREFIX__, are // gnu-specific.) -#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) +#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) && !defined(__INTEL_COMPILER) # define ULP_AS_STRING(x) ULP_AS_STRING_INTERNAL(x) # define ULP_AS_STRING_INTERNAL(x) #x # define USER_LABEL_PREFIX_STR ULP_AS_STRING(__USER_LABEL_PREFIX__) @@ -168,22 +168,22 @@ bool RE::FullMatch(const StringPiece& text, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; - if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; - if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; - if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; - if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; - if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; - if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; - if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; - if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; - if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; - if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; - if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; - if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; - if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; - if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; - if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; - if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + if (&ptr1 == &no_arg) { goto done; } args[n++] = &ptr1; + if (&ptr2 == &no_arg) { goto done; } args[n++] = &ptr2; + if (&ptr3 == &no_arg) { goto done; } args[n++] = &ptr3; + if (&ptr4 == &no_arg) { goto done; } args[n++] = &ptr4; + if (&ptr5 == &no_arg) { goto done; } args[n++] = &ptr5; + if (&ptr6 == &no_arg) { goto done; } args[n++] = &ptr6; + if (&ptr7 == &no_arg) { goto done; } args[n++] = &ptr7; + if (&ptr8 == &no_arg) { goto done; } args[n++] = &ptr8; + if (&ptr9 == &no_arg) { goto done; } args[n++] = &ptr9; + if (&ptr10 == &no_arg) { goto done; } args[n++] = &ptr10; + if (&ptr11 == &no_arg) { goto done; } args[n++] = &ptr11; + if (&ptr12 == &no_arg) { goto done; } args[n++] = &ptr12; + if (&ptr13 == &no_arg) { goto done; } args[n++] = &ptr13; + if (&ptr14 == &no_arg) { goto done; } args[n++] = &ptr14; + if (&ptr15 == &no_arg) { goto done; } args[n++] = &ptr15; + if (&ptr16 == &no_arg) { goto done; } args[n++] = &ptr16; done: int consumed; @@ -210,22 +210,22 @@ bool RE::PartialMatch(const StringPiece& text, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; - if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; - if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; - if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; - if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; - if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; - if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; - if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; - if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; - if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; - if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; - if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; - if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; - if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; - if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; - if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; - if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + if (&ptr1 == &no_arg) { goto done; } args[n++] = &ptr1; + if (&ptr2 == &no_arg) { goto done; } args[n++] = &ptr2; + if (&ptr3 == &no_arg) { goto done; } args[n++] = &ptr3; + if (&ptr4 == &no_arg) { goto done; } args[n++] = &ptr4; + if (&ptr5 == &no_arg) { goto done; } args[n++] = &ptr5; + if (&ptr6 == &no_arg) { goto done; } args[n++] = &ptr6; + if (&ptr7 == &no_arg) { goto done; } args[n++] = &ptr7; + if (&ptr8 == &no_arg) { goto done; } args[n++] = &ptr8; + if (&ptr9 == &no_arg) { goto done; } args[n++] = &ptr9; + if (&ptr10 == &no_arg) { goto done; } args[n++] = &ptr10; + if (&ptr11 == &no_arg) { goto done; } args[n++] = &ptr11; + if (&ptr12 == &no_arg) { goto done; } args[n++] = &ptr12; + if (&ptr13 == &no_arg) { goto done; } args[n++] = &ptr13; + if (&ptr14 == &no_arg) { goto done; } args[n++] = &ptr14; + if (&ptr15 == &no_arg) { goto done; } args[n++] = &ptr15; + if (&ptr16 == &no_arg) { goto done; } args[n++] = &ptr16; done: int consumed; @@ -252,22 +252,22 @@ bool RE::Consume(StringPiece* input, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; - if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; - if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; - if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; - if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; - if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; - if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; - if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; - if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; - if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; - if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; - if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; - if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; - if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; - if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; - if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; - if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + if (&ptr1 == &no_arg) { goto done; } args[n++] = &ptr1; + if (&ptr2 == &no_arg) { goto done; } args[n++] = &ptr2; + if (&ptr3 == &no_arg) { goto done; } args[n++] = &ptr3; + if (&ptr4 == &no_arg) { goto done; } args[n++] = &ptr4; + if (&ptr5 == &no_arg) { goto done; } args[n++] = &ptr5; + if (&ptr6 == &no_arg) { goto done; } args[n++] = &ptr6; + if (&ptr7 == &no_arg) { goto done; } args[n++] = &ptr7; + if (&ptr8 == &no_arg) { goto done; } args[n++] = &ptr8; + if (&ptr9 == &no_arg) { goto done; } args[n++] = &ptr9; + if (&ptr10 == &no_arg) { goto done; } args[n++] = &ptr10; + if (&ptr11 == &no_arg) { goto done; } args[n++] = &ptr11; + if (&ptr12 == &no_arg) { goto done; } args[n++] = &ptr12; + if (&ptr13 == &no_arg) { goto done; } args[n++] = &ptr13; + if (&ptr14 == &no_arg) { goto done; } args[n++] = &ptr14; + if (&ptr15 == &no_arg) { goto done; } args[n++] = &ptr15; + if (&ptr16 == &no_arg) { goto done; } args[n++] = &ptr16; done: int consumed; @@ -300,22 +300,22 @@ bool RE::FindAndConsume(StringPiece* input, const Arg& ptr16) const { const Arg* args[kMaxArgs]; int n = 0; - if (&ptr1 == &no_arg) goto done; args[n++] = &ptr1; - if (&ptr2 == &no_arg) goto done; args[n++] = &ptr2; - if (&ptr3 == &no_arg) goto done; args[n++] = &ptr3; - if (&ptr4 == &no_arg) goto done; args[n++] = &ptr4; - if (&ptr5 == &no_arg) goto done; args[n++] = &ptr5; - if (&ptr6 == &no_arg) goto done; args[n++] = &ptr6; - if (&ptr7 == &no_arg) goto done; args[n++] = &ptr7; - if (&ptr8 == &no_arg) goto done; args[n++] = &ptr8; - if (&ptr9 == &no_arg) goto done; args[n++] = &ptr9; - if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10; - if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11; - if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12; - if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13; - if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14; - if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15; - if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; + if (&ptr1 == &no_arg) { goto done; } args[n++] = &ptr1; + if (&ptr2 == &no_arg) { goto done; } args[n++] = &ptr2; + if (&ptr3 == &no_arg) { goto done; } args[n++] = &ptr3; + if (&ptr4 == &no_arg) { goto done; } args[n++] = &ptr4; + if (&ptr5 == &no_arg) { goto done; } args[n++] = &ptr5; + if (&ptr6 == &no_arg) { goto done; } args[n++] = &ptr6; + if (&ptr7 == &no_arg) { goto done; } args[n++] = &ptr7; + if (&ptr8 == &no_arg) { goto done; } args[n++] = &ptr8; + if (&ptr9 == &no_arg) { goto done; } args[n++] = &ptr9; + if (&ptr10 == &no_arg) { goto done; } args[n++] = &ptr10; + if (&ptr11 == &no_arg) { goto done; } args[n++] = &ptr11; + if (&ptr12 == &no_arg) { goto done; } args[n++] = &ptr12; + if (&ptr13 == &no_arg) { goto done; } args[n++] = &ptr13; + if (&ptr14 == &no_arg) { goto done; } args[n++] = &ptr14; + if (&ptr15 == &no_arg) { goto done; } args[n++] = &ptr15; + if (&ptr16 == &no_arg) { goto done; } args[n++] = &ptr16; done: int consumed; diff --git a/pcre/pcregrep.c b/pcre/pcregrep.c index 64986b016e613..cd53c648da205 100644 --- a/pcre/pcregrep.c +++ b/pcre/pcregrep.c @@ -2437,7 +2437,7 @@ return options; static char * ordin(int n) { -static char buffer[8]; +static char buffer[14]; char *p = buffer; sprintf(p, "%d", n); while (*p != 0) p++; diff --git a/pcre/pcreposix.c b/pcre/pcreposix.c index f024423b634b1..cf75588c40d79 100644 --- a/pcre/pcreposix.c +++ b/pcre/pcreposix.c @@ -6,7 +6,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel - Copyright (c) 1997-2014 University of Cambridge + Copyright (c) 1997-2016 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -173,7 +173,8 @@ static const int eint[] = { REG_BADPAT, /* group name must start with a non-digit */ /* 85 */ REG_BADPAT, /* parentheses too deeply nested (stack check) */ - REG_BADPAT /* missing digits in \x{} or \o{} */ + REG_BADPAT, /* missing digits in \x{} or \o{} */ + REG_BADPAT /* pattern too complicated */ }; /* Table of texts corresponding to POSIX error codes */ @@ -364,6 +365,7 @@ start location rather than being passed as a PCRE "starting offset". */ if ((eflags & REG_STARTEND) != 0) { + if (pmatch == NULL) return REG_INVARG; so = pmatch[0].rm_so; eo = pmatch[0].rm_eo; } diff --git a/pcre/pcretest.c b/pcre/pcretest.c index 488e419462e50..78ef5177df753 100644 --- a/pcre/pcretest.c +++ b/pcre/pcretest.c @@ -2250,7 +2250,7 @@ data is not zero. */ static int callout(pcre_callout_block *cb) { FILE *f = (first_callout | callout_extra)? outfile : NULL; -int i, pre_start, post_start, subject_length; +int i, current_position, pre_start, post_start, subject_length; if (callout_extra) { @@ -2280,14 +2280,19 @@ printed lengths of the substrings. */ if (f != NULL) fprintf(f, "--->"); +/* If a lookbehind is involved, the current position may be earlier than the +match start. If so, use the match start instead. */ + +current_position = (cb->current_position >= cb->start_match)? + cb->current_position : cb->start_match; + PCHARS(pre_start, cb->subject, 0, cb->start_match, f); PCHARS(post_start, cb->subject, cb->start_match, - cb->current_position - cb->start_match, f); + current_position - cb->start_match, f); PCHARS(subject_length, cb->subject, 0, cb->subject_length, NULL); -PCHARSV(cb->subject, cb->current_position, - cb->subject_length - cb->current_position, f); +PCHARSV(cb->subject, current_position, cb->subject_length - current_position, f); if (f != NULL) fprintf(f, "\n"); @@ -5612,6 +5617,12 @@ while (!done) break; } + if (use_size_offsets < 2) + { + fprintf(outfile, "Cannot do global matching with an ovector size < 2\n"); + break; + } + /* If we have matched an empty string, first check to see if we are at the end of the subject. If so, the /g loop is over. Otherwise, mimic what Perl's /g options does. This turns out to be rather cunning. First we set @@ -5740,3 +5751,4 @@ return yield; } /* End of pcretest.c */ + diff --git a/pcre/sljit/sljitConfigInternal.h b/pcre/sljit/sljitConfigInternal.h index 16e3547c938f0..9275b1499260b 100644 --- a/pcre/sljit/sljitConfigInternal.h +++ b/pcre/sljit/sljitConfigInternal.h @@ -31,14 +31,14 @@ SLJIT defines the following architecture dependent types and macros: Types: - sljit_sb, sljit_ub : signed and unsigned 8 bit byte - sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type - sljit_si, sljit_ui : signed and unsigned 32 bit integer type - sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer - sljit_p : unsgined pointer value (usually the same as sljit_uw, but - some 64 bit ABIs may use 32 bit pointers) - sljit_s : single precision floating point value - sljit_d : double precision floating point value + sljit_s8, sljit_u8 : signed and unsigned 8 bit integer type + sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type + sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type + sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer + sljit_p : unsgined pointer value (usually the same as sljit_uw, but + some 64 bit ABIs may use 32 bit pointers) + sljit_f32 : 32 bit single precision floating point value + sljit_f64 : 64 bit double precision floating point value Macros for feature detection (boolean): SLJIT_32BIT_ARCHITECTURE : 32 bit architecture @@ -56,10 +56,10 @@ SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index - SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing - a double precision floating point array by index - SLJIT_SINGLE_SHIFT : the shift required to apply when accessing - a single precision floating point array by index + SLJIT_F32_SHIFT : the shift required to apply when accessing + a single precision floating point array by index + SLJIT_F64_SHIFT : the shift required to apply when accessing + a double precision floating point array by index SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET) SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address @@ -252,11 +252,6 @@ #endif #endif /* !SLJIT_INLINE */ -#ifndef SLJIT_CONST -/* Const variables. */ -#define SLJIT_CONST const -#endif - #ifndef SLJIT_UNUSED_ARG /* Unused arguments. */ #define SLJIT_UNUSED_ARG(arg) (void)arg @@ -284,6 +279,15 @@ /* Instruction cache flush. */ /****************************/ +#if (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) +#if __has_builtin(__builtin___clear_cache) + +#define SLJIT_CACHE_FLUSH(from, to) \ + __builtin___clear_cache((char*)from, (char*)to) + +#endif /* __has_builtin(__builtin___clear_cache) */ +#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */ + #ifndef SLJIT_CACHE_FLUSH #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) @@ -300,6 +304,11 @@ #define SLJIT_CACHE_FLUSH(from, to) \ sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from)) +#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) + +#define SLJIT_CACHE_FLUSH(from, to) \ + __builtin___clear_cache((char*)from, (char*)to) + #elif defined __ANDROID__ /* Android lacks __clear_cache; instead, cacheflush should be used. */ @@ -312,12 +321,14 @@ /* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */ #define SLJIT_CACHE_FLUSH(from, to) \ ppc_cache_flush((from), (to)) +#define SLJIT_CACHE_FLUSH_OWN_IMPL 1 #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) /* The __clear_cache() implementation of GCC is a dummy function on Sparc. */ #define SLJIT_CACHE_FLUSH(from, to) \ sparc_cache_flush((from), (to)) +#define SLJIT_CACHE_FLUSH_OWN_IMPL 1 #else @@ -330,20 +341,20 @@ #endif /* !SLJIT_CACHE_FLUSH */ /******************************************************/ -/* Byte/half/int/word/single/double type definitions. */ +/* Integer and floating point type definitions. */ /******************************************************/ /* 8 bit byte type. */ -typedef unsigned char sljit_ub; -typedef signed char sljit_sb; +typedef unsigned char sljit_u8; +typedef signed char sljit_s8; /* 16 bit half-word type. */ -typedef unsigned short int sljit_uh; -typedef signed short int sljit_sh; +typedef unsigned short int sljit_u16; +typedef signed short int sljit_s16; /* 32 bit integer type. */ -typedef unsigned int sljit_ui; -typedef signed int sljit_si; +typedef unsigned int sljit_u32; +typedef signed int sljit_s32; /* Machine word type. Enough for storing a pointer. 32 bit for 32 bit machines. @@ -377,15 +388,15 @@ typedef long int sljit_sw; typedef sljit_uw sljit_p; /* Floating point types. */ -typedef float sljit_s; -typedef double sljit_d; +typedef float sljit_f32; +typedef double sljit_f64; /* Shift for pointer sized data. */ #define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT /* Shift for double precision sized data. */ -#define SLJIT_DOUBLE_SHIFT 3 -#define SLJIT_SINGLE_SHIFT 2 +#define SLJIT_F32_SHIFT 2 +#define SLJIT_F64_SHIFT 3 #ifndef SLJIT_W diff --git a/pcre/sljit/sljitExecAllocator.c b/pcre/sljit/sljitExecAllocator.c index f24ed337973e7..54f05f5dd70f9 100644 --- a/pcre/sljit/sljitExecAllocator.c +++ b/pcre/sljit/sljitExecAllocator.c @@ -137,10 +137,10 @@ struct free_block { }; #define AS_BLOCK_HEADER(base, offset) \ - ((struct block_header*)(((sljit_ub*)base) + offset)) + ((struct block_header*)(((sljit_u8*)base) + offset)) #define AS_FREE_BLOCK(base, offset) \ - ((struct free_block*)(((sljit_ub*)base) + offset)) -#define MEM_START(base) ((void*)(((sljit_ub*)base) + sizeof(struct block_header))) + ((struct free_block*)(((sljit_u8*)base) + offset)) +#define MEM_START(base) ((void*)(((sljit_u8*)base) + sizeof(struct block_header))) #define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7) & ~7) static struct free_block* free_blocks; @@ -153,7 +153,7 @@ static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, free_block->size = size; free_block->next = free_blocks; - free_block->prev = 0; + free_block->prev = NULL; if (free_blocks) free_blocks->prev = free_block; free_blocks = free_block; diff --git a/pcre/sljit/sljitLir.c b/pcre/sljit/sljitLir.c index 0f1b1c9ccee1e..ec1781e4c7f74 100644 --- a/pcre/sljit/sljitLir.c +++ b/pcre/sljit/sljitLir.c @@ -77,16 +77,16 @@ #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) #define GET_OPCODE(op) \ - ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + ((op) & ~(SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define GET_FLAGS(op) \ ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) #define GET_ALL_FLAGS(op) \ - ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) + ((op) & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define TYPE_CAST_NEEDED(op) \ - (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) + (((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16)) #define BUF_SIZE 4096 @@ -257,7 +257,7 @@ return 1; \ } while (0) -#define CHECK_RETURN_TYPE sljit_si +#define CHECK_RETURN_TYPE sljit_s32 #define CHECK_RETURN_OK return 0 #define CHECK(x) \ @@ -320,7 +320,7 @@ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) #define SLJIT_NEEDS_COMPILER_INIT 1 -static sljit_si compiler_initialized = 0; +static sljit_s32 compiler_initialized = 0; /* A thread safe initialization. */ static void init_compiler(void); #endif @@ -333,17 +333,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); SLJIT_COMPILE_ASSERT( - sizeof(sljit_sb) == 1 && sizeof(sljit_ub) == 1 - && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2 - && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4 + sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1 + && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2 + && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4 && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) && sizeof(sljit_p) <= sizeof(sljit_sw) && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), invalid_integer_types); - SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP, + SLJIT_COMPILE_ASSERT(SLJIT_I32_OP == SLJIT_F32_OP, int_op_and_single_op_must_be_the_same); - SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP, + SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_F32_OP, rewritable_jump_and_single_op_must_not_be_the_same); /* Only the non-zero members must be set. */ @@ -379,14 +379,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) - + CPOOL_SIZE * sizeof(sljit_ub), allocator_data); + + CPOOL_SIZE * sizeof(sljit_u8), allocator_data); if (!compiler->cpool) { SLJIT_FREE(compiler->buf, allocator_data); SLJIT_FREE(compiler->abuf, allocator_data); SLJIT_FREE(compiler, allocator_data); return NULL; } - compiler->cpool_unique = (sljit_ub*)(compiler->cpool + CPOOL_SIZE); + compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE); compiler->cpool_diff = 0xffffffff; #endif @@ -485,7 +485,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) { - sljit_ub *ret; + sljit_u8 *ret; struct sljit_memory_fragment *new_frag; SLJIT_ASSERT(size <= 256); @@ -504,7 +504,7 @@ static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) { - sljit_ub *ret; + sljit_u8 *ret; struct sljit_memory_fragment *new_frag; SLJIT_ASSERT(size <= 256); @@ -521,7 +521,7 @@ static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) return new_frag->memory; } -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) { CHECK_ERROR_PTR(); @@ -554,8 +554,8 @@ static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler) } static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(local_size); @@ -571,8 +571,8 @@ static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler, } static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(args); SLJIT_UNUSED_ARG(local_size); @@ -598,7 +598,7 @@ static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compi compiler->last_label = label; } -static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_si flags) +static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_s32 flags) { jump->next = NULL; jump->flags = flags; @@ -654,19 +654,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp break; \ case SLJIT_BREAKPOINT: \ case SLJIT_NOP: \ - case SLJIT_LUMUL: \ - case SLJIT_LSMUL: \ + case SLJIT_LMUL_UW: \ + case SLJIT_LMUL_SW: \ case SLJIT_MOV: \ - case SLJIT_MOV_UI: \ + case SLJIT_MOV_U32: \ case SLJIT_MOV_P: \ case SLJIT_MOVU: \ - case SLJIT_MOVU_UI: \ + case SLJIT_MOVU_U32: \ case SLJIT_MOVU_P: \ /* Nothing allowed */ \ - CHECK_ARGUMENT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ } @@ -674,12 +674,12 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp #define FUNCTION_CHECK_FOP() \ CHECK_ARGUMENT(!GET_FLAGS(op) || !(op & SLJIT_KEEP_FLAGS)); \ switch (GET_OPCODE(op)) { \ - case SLJIT_DCMP: \ + case SLJIT_CMP_F64: \ CHECK_ARGUMENT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ break; \ default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ + /* Only SLJIT_I32_OP or SLJIT_F32_OP is allowed. */ \ CHECK_ARGUMENT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ } @@ -844,38 +844,38 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \ } -static SLJIT_CONST char* op0_names[] = { - (char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul", - (char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi" +static const char* op0_names[] = { + (char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw", + (char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s" }; -static SLJIT_CONST char* op1_names[] = { - (char*)"mov", (char*)"mov_ub", (char*)"mov_sb", (char*)"mov_uh", - (char*)"mov_sh", (char*)"mov_ui", (char*)"mov_si", (char*)"mov_p", - (char*)"movu", (char*)"movu_ub", (char*)"movu_sb", (char*)"movu_uh", - (char*)"movu_sh", (char*)"movu_ui", (char*)"movu_si", (char*)"movu_p", +static const char* op1_names[] = { + (char*)"", (char*)".u8", (char*)".s8", (char*)".u16", + (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p", + (char*)"", (char*)".u8", (char*)".s8", (char*)".u16", + (char*)".s16", (char*)".u32", (char*)".s32", (char*)".p", (char*)"not", (char*)"neg", (char*)"clz", }; -static SLJIT_CONST char* op2_names[] = { +static const char* op2_names[] = { (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", (char*)"shl", (char*)"lshr", (char*)"ashr", }; -static SLJIT_CONST char* fop1_names[] = { +static const char* fop1_names[] = { (char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg", (char*)"abs", }; -static SLJIT_CONST char* fop2_names[] = { +static const char* fop2_names[] = { (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" }; -#define JUMP_PREFIX(type) \ - ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_INT_OP) ? "i_" : "") \ - : ((type & 0xff) <= SLJIT_D_ORDERED ? ((type & SLJIT_SINGLE_OP) ? "s_" : "d_") : "")) +#define JUMP_POSTFIX(type) \ + ((type & 0xff) <= SLJIT_MUL_NOT_OVERFLOW ? ((type & SLJIT_I32_OP) ? "32" : "") \ + : ((type & 0xff) <= SLJIT_ORDERED_F64 ? ((type & SLJIT_F32_OP) ? ".f32" : ".f64") : "")) static char* jump_names[] = { (char*)"equal", (char*)"not_equal", @@ -923,8 +923,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(compiler); @@ -949,8 +949,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -977,7 +977,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(compiler->scratches >= 0); @@ -993,7 +993,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi if (op == SLJIT_UNUSED) fprintf(compiler->verbose, " return\n"); else { - fprintf(compiler->verbose, " return.%s ", op1_names[op - SLJIT_OP1_BASE]); + fprintf(compiler->verbose, " return%s ", op1_names[op - SLJIT_OP1_BASE]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } @@ -1002,7 +1002,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_DST(dst, dstw); @@ -1017,7 +1017,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_c CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) FUNCTION_CHECK_SRC(src, srcw); @@ -1032,23 +1032,29 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_ CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL) - || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI)); - CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2); + CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW) + || ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)); + CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); + { + fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]); + if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) { + fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w"); + } + fprintf(compiler->verbose, "\n"); + } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1064,9 +1070,18 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", - !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + if (GET_OPCODE(op) <= SLJIT_MOVU_P) + { + fprintf(compiler->verbose, " mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "", + !(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ""); + } + else + { + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_I32_OP) ? "" : "32", + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", + !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + } + sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); @@ -1076,10 +1091,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1095,7 +1110,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], + fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_I32_OP) ? "" : "32", !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); sljit_verbose_param(compiler, dst, dstw); @@ -1109,7 +1124,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_si reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg) { SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1118,7 +1133,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_si re CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_si reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg) { SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1128,7 +1143,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) + void *instruction, sljit_s32 size) { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) int i; @@ -1152,16 +1167,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " op_custom"); for (i = 0; i < size; i++) - fprintf(compiler->verbose, " 0x%x", ((sljit_ub*)instruction)[i]); + fprintf(compiler->verbose, " 0x%x", ((sljit_u8*)instruction)[i]); fprintf(compiler->verbose, "\n"); } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1170,19 +1185,19 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DMOV && GET_OPCODE(op) <= SLJIT_DABS); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src, srcw); FUNCTION_FCHECK(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONVD_FROMS - SLJIT_FOP1_BASE], - (op & SLJIT_SINGLE_OP) ? "s.fromd" : "d.froms"); + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + fprintf(compiler->verbose, " %s%s ", fop1_names[SLJIT_CONV_F64_FROM_F32 - SLJIT_FOP1_BASE], + (op & SLJIT_F32_OP) ? ".f32.from.f64" : ".f64.from.f32"); else - fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", - fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE]); + fprintf(compiler->verbose, " %s%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], + (op & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); @@ -1193,9 +1208,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1204,14 +1219,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_DCMP); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_CMP_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop1_names[SLJIT_DCMP - SLJIT_FOP1_BASE], + fprintf(compiler->verbose, " %s%s%s%s ", fop1_names[SLJIT_CMP_F64 - SLJIT_FOP1_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64", (op & SLJIT_SET_E) ? ".e" : "", (op & SLJIT_SET_S) ? ".s" : ""); sljit_verbose_fparam(compiler, src1, src1w); fprintf(compiler->verbose, ", "); @@ -1222,9 +1237,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1233,7 +1248,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct s #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_CONVI_FROMD); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src, srcw); FUNCTION_CHECK_DST(dst, dstw); @@ -1241,8 +1256,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? "i" : "w", - (op & SLJIT_SINGLE_OP) ? "s" : "d"); + (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw", + (op & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(compiler, src, srcw); @@ -1252,9 +1267,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convw_fromd(struct s CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1263,7 +1278,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct s #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONVD_FROMW && GET_OPCODE(op) <= SLJIT_CONVD_FROMI); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32); FUNCTION_CHECK_FOP(); FUNCTION_CHECK_SRC(src, srcw); FUNCTION_FCHECK(dst, dstw); @@ -1271,8 +1286,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (op & SLJIT_SINGLE_OP) ? "s" : "d", - (GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? "i" : "w"); + (op & SLJIT_F32_OP) ? ".f32" : ".f64", + (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw"); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); @@ -1282,14 +1297,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_convd_fromw(struct s CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_DADD && GET_OPCODE(op) <= SLJIT_DDIV); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); FUNCTION_CHECK_FOP(); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); @@ -1297,7 +1312,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s ", (op & SLJIT_SINGLE_OP) ? "s" : "d", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE]); + fprintf(compiler->verbose, " %s%s ", fop2_names[GET_OPCODE(op) - SLJIT_FOP2_BASE], (op & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(compiler, src1, src1w); @@ -1320,7 +1335,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1328,33 +1343,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP))); CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3); - CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_INT_OP)); + CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP)); CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " jump%s.%s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - JUMP_PREFIX(type), jump_names[type & 0xff]); + fprintf(compiler->verbose, " jump%s %s%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + jump_names[type & 0xff], JUMP_POSTFIX(type)); #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP))); CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL); FUNCTION_CHECK_SRC(src1, src1w); FUNCTION_CHECK_SRC(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " cmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - (type & SLJIT_INT_OP) ? "i_" : "", jump_names[type & 0xff]); + fprintf(compiler->verbose, " cmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + jump_names[type & 0xff], (type & SLJIT_I32_OP) ? "32" : ""); sljit_verbose_param(compiler, src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src2, src2w); @@ -1364,21 +1379,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_is_fpu_available()); - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_D_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_F32_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL_F64 && (type & 0xff) <= SLJIT_ORDERED_F64); FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fcmp%s.%s%s ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", - (type & SLJIT_SINGLE_OP) ? "s_" : "d_", jump_names[type & 0xff]); + fprintf(compiler->verbose, " fcmp%s %s%s, ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", + jump_names[type & 0xff], (type & SLJIT_F32_OP) ? ".f32" : ".f64"); sljit_verbose_fparam(compiler, src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(compiler, src2, src2w); @@ -1388,7 +1403,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; @@ -1410,15 +1425,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compil CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64); + CHECK_ARGUMENT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_U32 || GET_OPCODE(op) == SLJIT_MOV_S32 || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); CHECK_ARGUMENT((op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0); CHECK_ARGUMENT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); @@ -1431,21 +1446,22 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " flags.%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", - GET_OPCODE(op) >= SLJIT_OP2_BASE ? op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE] : op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + fprintf(compiler->verbose, " flags %s%s%s%s, ", + !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k", + GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], + GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_I32_OP) ? "32" : "")); sljit_verbose_param(compiler, dst, dstw); if (src != SLJIT_UNUSED) { fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); } - fprintf(compiler->verbose, ", %s%s\n", JUMP_PREFIX(type), jump_names[type & 0xff]); + fprintf(compiler->verbose, ", %s%s\n", jump_names[type & 0xff], JUMP_POSTFIX(type)); } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { SLJIT_UNUSED_ARG(offset); @@ -1462,7 +1478,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { SLJIT_UNUSED_ARG(init_value); @@ -1482,31 +1498,31 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ - SLJIT_COMPILE_ASSERT(!(SLJIT_CONVW_FROMD & 0x1) && !(SLJIT_CONVD_FROMW & 0x1), \ + SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \ invalid_float_opcodes); \ - if (GET_OPCODE(op) >= SLJIT_CONVW_FROMD && GET_OPCODE(op) <= SLJIT_DCMP) { \ - if (GET_OPCODE(op) == SLJIT_DCMP) { \ + if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \ + if (GET_OPCODE(op) == SLJIT_CMP_F64) { \ CHECK(check_sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ return sljit_emit_fop1_cmp(compiler, op, dst, dstw, src, srcw); \ } \ - if ((GET_OPCODE(op) | 0x1) == SLJIT_CONVI_FROMD) { \ - CHECK(check_sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw)); \ + if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_S32_FROM_F64) { \ + CHECK(check_sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_convw_fromd(compiler, op, dst, dstw, src, srcw); \ + return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \ } \ - CHECK(check_sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw)); \ + CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_convd_fromw(compiler, op, dst, dstw, src, srcw); \ + return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ } \ CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); -static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { /* Return if don't need to do anything. */ if (op == SLJIT_UNUSED) @@ -1517,7 +1533,7 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; #else - if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P)) + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P)) return SLJIT_SUCCESS; #endif @@ -1576,12 +1592,12 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* Default compare for most architectures. */ - sljit_si flags, tmp_src, condition; + sljit_s32 flags, tmp_src, condition; sljit_sw tmp_srcw; CHECK_ERROR_PTR(); @@ -1629,7 +1645,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler condition = SLJIT_SIG_GREATER_EQUAL; break; } - type = condition | (type & (SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP)); + type = condition | (type & (SLJIT_I32_OP | SLJIT_REWRITABLE_JUMP)); tmp_src = src1; src1 = src2; src2 = tmp_src; @@ -1649,7 +1665,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->skip_checks = 1; #endif - PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_INT_OP), + PTR_FAIL_IF(sljit_emit_op2(compiler, SLJIT_SUB | flags | (type & SLJIT_I32_OP), SLJIT_UNUSED, 0, src1, src1w, src2, src2w)); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1658,25 +1674,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si flags, condition; + sljit_s32 flags, condition; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); condition = type & 0xff; - flags = (condition <= SLJIT_D_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S; - if (type & SLJIT_SINGLE_OP) - flags |= SLJIT_SINGLE_OP; + flags = (condition <= SLJIT_NOT_EQUAL_F64) ? SLJIT_SET_E : SLJIT_SET_S; + if (type & SLJIT_F32_OP) + flags |= SLJIT_F32_OP; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->skip_checks = 1; #endif - sljit_emit_fop1(compiler, SLJIT_DCMP | flags, src1, src1w, src2, src2w); + sljit_emit_fop1(compiler, SLJIT_CMP_F64 | flags, src1, src1w, src2, src2w); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1689,7 +1705,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { CHECK_ERROR(); CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); @@ -1710,7 +1726,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co /* Empty function bodies for those machines, which are not (yet) supported. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "unsupported"; } @@ -1727,7 +1743,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(size); @@ -1757,9 +1773,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(options); @@ -1773,9 +1789,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(options); @@ -1789,7 +1805,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1799,7 +1815,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -1808,7 +1824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(src); @@ -1817,7 +1833,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1825,9 +1841,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1839,10 +1855,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1856,14 +1872,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { SLJIT_ASSERT_STOP(); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(instruction); @@ -1872,15 +1888,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { SLJIT_ASSERT_STOP(); return 0; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1892,10 +1908,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1916,7 +1932,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1924,9 +1940,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1938,9 +1954,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1966,7 +1982,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1976,10 +1992,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1992,7 +2008,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -2002,7 +2018,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); diff --git a/pcre/sljit/sljitLir.h b/pcre/sljit/sljitLir.h index 2e2e9ac09cd66..df69b8656f8a2 100644 --- a/pcre/sljit/sljitLir.h +++ b/pcre/sljit/sljitLir.h @@ -226,7 +226,7 @@ of sljitConfigInternal.h */ /* Floating point registers */ /* --------------------------------------------------------------------- */ -/* Each floating point register can store a double or single precision +/* Each floating point register can store a 32 or a 64 bit precision value. The FR and FS register sets are overlap in the same way as R and S register sets. See above. */ @@ -271,7 +271,7 @@ struct sljit_memory_fragment { struct sljit_memory_fragment *next; sljit_uw used_size; /* Must be aligned to sljit_sw. */ - sljit_ub memory[1]; + sljit_u8 memory[1]; }; struct sljit_label { @@ -297,8 +297,8 @@ struct sljit_const { }; struct sljit_compiler { - sljit_si error; - sljit_si options; + sljit_s32 error; + sljit_s32 options; struct sljit_label *labels; struct sljit_jump *jumps; @@ -312,36 +312,36 @@ struct sljit_compiler { struct sljit_memory_fragment *abuf; /* Used scratch registers. */ - sljit_si scratches; + sljit_s32 scratches; /* Used saved registers. */ - sljit_si saveds; + sljit_s32 saveds; /* Used float scratch registers. */ - sljit_si fscratches; + sljit_s32 fscratches; /* Used float saved registers. */ - sljit_si fsaveds; + sljit_s32 fsaveds; /* Local stack size. */ - sljit_si local_size; + sljit_s32 local_size; /* Code size. */ sljit_uw size; /* For statistical purposes. */ sljit_uw executable_size; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si args; + sljit_s32 args; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si mode32; + sljit_s32 mode32; #endif #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) - sljit_si flags_saved; + sljit_s32 flags_saved; #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) /* Constant pool handling. */ sljit_uw *cpool; - sljit_ub *cpool_unique; + sljit_u8 *cpool_unique; sljit_uw cpool_diff; sljit_uw cpool_fill; /* Other members. */ @@ -352,40 +352,40 @@ struct sljit_compiler { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Temporary fields. */ sljit_uw shift_imm; - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) sljit_sw imm; - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) - sljit_si delay_slot; - sljit_si cache_arg; + sljit_s32 delay_slot; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - sljit_si delay_slot; - sljit_si cache_arg; + sljit_s32 delay_slot; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif #if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) - sljit_si cache_arg; + sljit_s32 cache_arg; sljit_sw cache_argw; #endif @@ -396,13 +396,13 @@ struct sljit_compiler { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Local size passed to the functions. */ - sljit_si logical_local_size; + sljit_s32 logical_local_size; #endif #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) \ || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - sljit_si skip_checks; + sljit_s32 skip_checks; #endif }; @@ -427,7 +427,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile error code. Thus there is no need for checking the error after every call, it is enough to do it before the code is compiled. Removing these checks increases the performance of the compiling process. */ -static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } +static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } /* Sets the compiler error code to SLJIT_ERR_ALLOC_FAILED except if an error was detected before. After the error code is set @@ -448,7 +448,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi indicate that there is no more memory (does not set the current error code of the compiler to out-of-memory status). */ -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size); +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ @@ -518,9 +518,9 @@ offset 0 is aligned to sljit_d. Otherwise it is aligned to sljit_uw. */ /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ #define SLJIT_MAX_LOCAL_SIZE 65536 -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); /* The machine code has a context (which contains the local stack space size, number of used registers, etc.) which initialized by sljit_emit_enter. Several @@ -532,9 +532,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil Note: every call of sljit_emit_enter and sljit_set_context overwrites the previous context. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size); /* Return from machine code. The op argument can be SLJIT_UNUSED which means the function does not return with anything or any opcode between SLJIT_MOV and @@ -542,8 +542,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi is SLJIT_UNUSED, otherwise see below the description about source and destination arguments. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw); /* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and even the stack frame is passed to the callee. The return address is preserved in @@ -560,8 +560,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested, since many architectures do clever branch prediction on call / return instruction pairs. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw); /* Source and destination values for arithmetical instructions @@ -624,31 +624,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * #define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8)) #define SLJIT_IMM 0x40 -/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on - 32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the - lower 32 bit of the input register(s), and set the CPU status flags according - to the 32 bit result. The higher 32 bits are undefined for both the input and - output. However, the CPU might not ignore those higher 32 bits, like MIPS, which - expects it to be the sign extension of the lower 32 bit. All 32 bit operations - are undefined, if this condition is not fulfilled. Therefore, when SLJIT_INT_OP - is specified, all register arguments must be the result of other operations with - the same SLJIT_INT_OP flag. In other words, although a register can hold either - a 64 or 32 bit value, these values cannot be mixed. The only exceptions are - SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOVU_SI with SLJIT_INT_OP flag) - which can convert any source argument to SLJIT_INT_OP compatible result. This - conversion might be unnecessary on some CPUs like x86-64, since the upper 32 - bit is always ignored. In this case SLJIT is clever enough to not generate any - instructions if the source and destination operands are the same registers. - Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */ -#define SLJIT_INT_OP 0x100 - -/* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just +/* Set 32 bit operation mode (I) on 64 bit CPUs. This flag is ignored on 32 + bit CPUs. When this flag is set for an arithmetic operation, only the + lower 32 bit of the input register(s) are used, and the CPU status flags + are set according to the 32 bit result. Although the higher 32 bit of + the input and the result registers are not defined by SLJIT, it might be + defined by the CPU architecture (e.g. MIPS). To satisfy these requirements + all source registers must be computed by operations where this flag is + also set. In other words 32 and 64 bit arithmetic operations cannot be + mixed. The only exception is SLJIT_IMOV and SLJIT_IMOVU whose source + register can hold any 32 or 64 bit value. This source register is + converted to a 32 bit compatible format. SLJIT does not generate any + instructions on certain CPUs (e.g. on x86 and ARM) if the source and + destination operands are the same registers. Affects sljit_emit_op0, + sljit_emit_op1 and sljit_emit_op2. */ +#define SLJIT_I32_OP 0x100 + +/* F32 precision mode (SP). This flag is similar to SLJIT_I32_OP, just it applies to floating point registers (it is even the same bit). When - this flag is passed, the CPU performs single precision floating point - operations. Similar to SLJIT_INT_OP, all register arguments must be the - result of other floating point operations with this flag. Affects + this flag is passed, the CPU performs 32 bit floating point operations. + Similar to SLJIT_I32_OP, all register arguments must be computed by + floating point operations where this flag is also set. Affects sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */ -#define SLJIT_SINGLE_OP 0x100 +#define SLJIT_F32_OP 0x100 /* Common CPU status flags for all architectures (x86, ARM, PPC) - carry flag @@ -697,43 +695,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Flags: - (may destroy flags) Unsigned multiplication of SLJIT_R0 and SLJIT_R1. Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */ -#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2) +#define SLJIT_LMUL_UW (SLJIT_OP0_BASE + 2) /* Flags: - (may destroy flags) Signed multiplication of SLJIT_R0 and SLJIT_R1. Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */ -#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3) +#define SLJIT_LMUL_SW (SLJIT_OP0_BASE + 3) /* Flags: I - (may destroy flags) Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0 and the remainder into SLJIT_R1. Note: if SLJIT_R1 is 0, the behaviour is undefined. */ -#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4) -#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP) +#define SLJIT_DIVMOD_UW (SLJIT_OP0_BASE + 4) +#define SLJIT_DIVMOD_U32 (SLJIT_DIVMOD_UW | SLJIT_I32_OP) /* Flags: I - (may destroy flags) Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0 and the remainder into SLJIT_R1. Note: if SLJIT_R1 is 0, the behaviour is undefined. Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00), the behaviour is undefined. */ -#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5) -#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP) +#define SLJIT_DIVMOD_SW (SLJIT_OP0_BASE + 5) +#define SLJIT_DIVMOD_S32 (SLJIT_DIVMOD_SW | SLJIT_I32_OP) /* Flags: I - (may destroy flags) Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0. SLJIT_R1 preserves its value. - Note: if SLJIT_R1 is 0, the behaviour is undefined. - Note: SLJIT_SDIV is single precision divide. */ -#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6) -#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP) + Note: if SLJIT_R1 is 0, the behaviour is undefined. */ +#define SLJIT_DIV_UW (SLJIT_OP0_BASE + 6) +#define SLJIT_DIV_U32 (SLJIT_DIV_UW | SLJIT_I32_OP) /* Flags: I - (may destroy flags) Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1. The result is placed into SLJIT_R0. SLJIT_R1 preserves its value. Note: if SLJIT_R1 is 0, the behaviour is undefined. Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00), - the behaviour is undefined. - Note: SLJIT_SDIV is single precision divide. */ -#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7) -#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP) + the behaviour is undefined. */ +#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7) +#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op); /* Starting index of opcodes for sljit_emit_op1. */ #define SLJIT_OP1_BASE 32 @@ -752,188 +748,188 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler /* Flags: - (never set any flags) */ #define SLJIT_MOV (SLJIT_OP1_BASE + 0) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_UB (SLJIT_OP1_BASE + 1) -#define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP) +#define SLJIT_MOV_U8 (SLJIT_OP1_BASE + 1) +#define SLJIT_MOV32_U8 (SLJIT_MOV_U8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_SB (SLJIT_OP1_BASE + 2) -#define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP) +#define SLJIT_MOV_S8 (SLJIT_OP1_BASE + 2) +#define SLJIT_MOV32_S8 (SLJIT_MOV_S8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_UH (SLJIT_OP1_BASE + 3) -#define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP) +#define SLJIT_MOV_U16 (SLJIT_OP1_BASE + 3) +#define SLJIT_MOV32_U16 (SLJIT_MOV_U16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOV_SH (SLJIT_OP1_BASE + 4) -#define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP) +#define SLJIT_MOV_S16 (SLJIT_OP1_BASE + 4) +#define SLJIT_MOV32_S16 (SLJIT_MOV_S16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOV_UI (SLJIT_OP1_BASE + 5) -/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */ + Note: no SLJIT_MOV32_U32 form, since it is the same as SLJIT_MOV32 */ +#define SLJIT_MOV_U32 (SLJIT_OP1_BASE + 5) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOV_SI (SLJIT_OP1_BASE + 6) -#define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP) + Note: no SLJIT_MOV32_S32 form, since it is the same as SLJIT_MOV32 */ +#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6) +/* Flags: I - (never set any flags) */ +#define SLJIT_MOV32 (SLJIT_MOV_S32 | SLJIT_I32_OP) /* Flags: - (never set any flags) */ #define SLJIT_MOV_P (SLJIT_OP1_BASE + 7) /* Flags: - (never set any flags) */ #define SLJIT_MOVU (SLJIT_OP1_BASE + 8) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_UB (SLJIT_OP1_BASE + 9) -#define SLJIT_IMOVU_UB (SLJIT_MOVU_UB | SLJIT_INT_OP) +#define SLJIT_MOVU_U8 (SLJIT_OP1_BASE + 9) +#define SLJIT_MOVU32_U8 (SLJIT_MOVU_U8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_SB (SLJIT_OP1_BASE + 10) -#define SLJIT_IMOVU_SB (SLJIT_MOVU_SB | SLJIT_INT_OP) +#define SLJIT_MOVU_S8 (SLJIT_OP1_BASE + 10) +#define SLJIT_MOVU32_S8 (SLJIT_MOVU_S8 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_UH (SLJIT_OP1_BASE + 11) -#define SLJIT_IMOVU_UH (SLJIT_MOVU_UH | SLJIT_INT_OP) +#define SLJIT_MOVU_U16 (SLJIT_OP1_BASE + 11) +#define SLJIT_MOVU32_U16 (SLJIT_MOVU_U16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) */ -#define SLJIT_MOVU_SH (SLJIT_OP1_BASE + 12) -#define SLJIT_IMOVU_SH (SLJIT_MOVU_SH | SLJIT_INT_OP) +#define SLJIT_MOVU_S16 (SLJIT_OP1_BASE + 12) +#define SLJIT_MOVU32_S16 (SLJIT_MOVU_S16 | SLJIT_I32_OP) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOVU_UI (SLJIT_OP1_BASE + 13) -/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */ + Note: no SLJIT_MOVU32_U32 form, since it is the same as SLJIT_MOVU32 */ +#define SLJIT_MOVU_U32 (SLJIT_OP1_BASE + 13) /* Flags: I - (never set any flags) - Note: see SLJIT_INT_OP for further details. */ -#define SLJIT_MOVU_SI (SLJIT_OP1_BASE + 14) -#define SLJIT_IMOVU (SLJIT_MOVU_SI | SLJIT_INT_OP) + Note: no SLJIT_MOVU32_S32 form, since it is the same as SLJIT_MOVU32 */ +#define SLJIT_MOVU_S32 (SLJIT_OP1_BASE + 14) +/* Flags: I - (never set any flags) */ +#define SLJIT_MOVU32 (SLJIT_MOVU_S32 | SLJIT_I32_OP) /* Flags: - (never set any flags) */ #define SLJIT_MOVU_P (SLJIT_OP1_BASE + 15) /* Flags: I | E | K */ #define SLJIT_NOT (SLJIT_OP1_BASE + 16) -#define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP) +#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_I32_OP) /* Flags: I | E | O | K */ #define SLJIT_NEG (SLJIT_OP1_BASE + 17) -#define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP) +#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_I32_OP) /* Count leading zeroes Flags: I | E | K Important note! Sparc 32 does not support K flag, since the required popc instruction is introduced only in sparc 64. */ #define SLJIT_CLZ (SLJIT_OP1_BASE + 18) -#define SLJIT_ICLZ (SLJIT_CLZ | SLJIT_INT_OP) +#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_I32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_op2. */ #define SLJIT_OP2_BASE 96 /* Flags: I | E | O | C | K */ #define SLJIT_ADD (SLJIT_OP2_BASE + 0) -#define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP) +#define SLJIT_ADD32 (SLJIT_ADD | SLJIT_I32_OP) /* Flags: I | C | K */ #define SLJIT_ADDC (SLJIT_OP2_BASE + 1) -#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP) +#define SLJIT_ADDC32 (SLJIT_ADDC | SLJIT_I32_OP) /* Flags: I | E | U | S | O | C | K */ #define SLJIT_SUB (SLJIT_OP2_BASE + 2) -#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP) +#define SLJIT_SUB32 (SLJIT_SUB | SLJIT_I32_OP) /* Flags: I | C | K */ #define SLJIT_SUBC (SLJIT_OP2_BASE + 3) -#define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP) +#define SLJIT_SUBC32 (SLJIT_SUBC | SLJIT_I32_OP) /* Note: integer mul Flags: I | O (see SLJIT_C_MUL_*) | K */ #define SLJIT_MUL (SLJIT_OP2_BASE + 4) -#define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP) +#define SLJIT_MUL32 (SLJIT_MUL | SLJIT_I32_OP) /* Flags: I | E | K */ #define SLJIT_AND (SLJIT_OP2_BASE + 5) -#define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP) +#define SLJIT_AND32 (SLJIT_AND | SLJIT_I32_OP) /* Flags: I | E | K */ #define SLJIT_OR (SLJIT_OP2_BASE + 6) -#define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP) +#define SLJIT_OR32 (SLJIT_OR | SLJIT_I32_OP) /* Flags: I | E | K */ #define SLJIT_XOR (SLJIT_OP2_BASE + 7) -#define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP) +#define SLJIT_XOR32 (SLJIT_XOR | SLJIT_I32_OP) /* Flags: I | E | K Let bit_length be the length of the shift operation: 32 or 64. If src2 is immediate, src2w is masked by (bit_length - 1). Otherwise, if the content of src2 is outside the range from 0 to bit_length - 1, the result is undefined. */ #define SLJIT_SHL (SLJIT_OP2_BASE + 8) -#define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP) +#define SLJIT_SHL32 (SLJIT_SHL | SLJIT_I32_OP) /* Flags: I | E | K Let bit_length be the length of the shift operation: 32 or 64. If src2 is immediate, src2w is masked by (bit_length - 1). Otherwise, if the content of src2 is outside the range from 0 to bit_length - 1, the result is undefined. */ #define SLJIT_LSHR (SLJIT_OP2_BASE + 9) -#define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP) +#define SLJIT_LSHR32 (SLJIT_LSHR | SLJIT_I32_OP) /* Flags: I | E | K Let bit_length be the length of the shift operation: 32 or 64. If src2 is immediate, src2w is masked by (bit_length - 1). Otherwise, if the content of src2 is outside the range from 0 to bit_length - 1, the result is undefined. */ #define SLJIT_ASHR (SLJIT_OP2_BASE + 10) -#define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP) +#define SLJIT_ASHR32 (SLJIT_ASHR | SLJIT_I32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Returns with non-zero if fpu is available. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void); /* Starting index of opcodes for sljit_emit_fop1. */ #define SLJIT_FOP1_BASE 128 /* Flags: SP - (never set any flags) */ -#define SLJIT_DMOV (SLJIT_FOP1_BASE + 0) -#define SLJIT_SMOV (SLJIT_DMOV | SLJIT_SINGLE_OP) +#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0) +#define SLJIT_MOV_F32 (SLJIT_MOV_F64 | SLJIT_F32_OP) /* Convert opcodes: CONV[DST_TYPE].FROM[SRC_TYPE] SRC/DST TYPE can be: D - double, S - single, W - signed word, I - signed int Rounding mode when the destination is W or I: round towards zero. */ /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVD_FROMS (SLJIT_FOP1_BASE + 1) -#define SLJIT_CONVS_FROMD (SLJIT_CONVD_FROMS | SLJIT_SINGLE_OP) +#define SLJIT_CONV_F64_FROM_F32 (SLJIT_FOP1_BASE + 1) +#define SLJIT_CONV_F32_FROM_F64 (SLJIT_CONV_F64_FROM_F32 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVW_FROMD (SLJIT_FOP1_BASE + 2) -#define SLJIT_CONVW_FROMS (SLJIT_CONVW_FROMD | SLJIT_SINGLE_OP) +#define SLJIT_CONV_SW_FROM_F64 (SLJIT_FOP1_BASE + 2) +#define SLJIT_CONV_SW_FROM_F32 (SLJIT_CONV_SW_FROM_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVI_FROMD (SLJIT_FOP1_BASE + 3) -#define SLJIT_CONVI_FROMS (SLJIT_CONVI_FROMD | SLJIT_SINGLE_OP) +#define SLJIT_CONV_S32_FROM_F64 (SLJIT_FOP1_BASE + 3) +#define SLJIT_CONV_S32_FROM_F32 (SLJIT_CONV_S32_FROM_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVD_FROMW (SLJIT_FOP1_BASE + 4) -#define SLJIT_CONVS_FROMW (SLJIT_CONVD_FROMW | SLJIT_SINGLE_OP) +#define SLJIT_CONV_F64_FROM_SW (SLJIT_FOP1_BASE + 4) +#define SLJIT_CONV_F32_FROM_SW (SLJIT_CONV_F64_FROM_SW | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_CONVD_FROMI (SLJIT_FOP1_BASE + 5) -#define SLJIT_CONVS_FROMI (SLJIT_CONVD_FROMI | SLJIT_SINGLE_OP) +#define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5) +#define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_F32_OP) /* Note: dst is the left and src is the right operand for SLJIT_CMPD. Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED flag is set, the comparison result is unpredictable. Flags: SP | E | S (see SLJIT_C_FLOAT_*) */ -#define SLJIT_DCMP (SLJIT_FOP1_BASE + 6) -#define SLJIT_SCMP (SLJIT_DCMP | SLJIT_SINGLE_OP) +#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6) +#define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DNEG (SLJIT_FOP1_BASE + 7) -#define SLJIT_SNEG (SLJIT_DNEG | SLJIT_SINGLE_OP) +#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7) +#define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DABS (SLJIT_FOP1_BASE + 8) -#define SLJIT_SABS (SLJIT_DABS | SLJIT_SINGLE_OP) +#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8) +#define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_F32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_fop2. */ #define SLJIT_FOP2_BASE 160 /* Flags: SP - (never set any flags) */ -#define SLJIT_DADD (SLJIT_FOP2_BASE + 0) -#define SLJIT_SADD (SLJIT_DADD | SLJIT_SINGLE_OP) +#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0) +#define SLJIT_ADD_F32 (SLJIT_ADD_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DSUB (SLJIT_FOP2_BASE + 1) -#define SLJIT_SSUB (SLJIT_DSUB | SLJIT_SINGLE_OP) +#define SLJIT_SUB_F64 (SLJIT_FOP2_BASE + 1) +#define SLJIT_SUB_F32 (SLJIT_SUB_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DMUL (SLJIT_FOP2_BASE + 2) -#define SLJIT_SMUL (SLJIT_DMUL | SLJIT_SINGLE_OP) +#define SLJIT_MUL_F64 (SLJIT_FOP2_BASE + 2) +#define SLJIT_MUL_F32 (SLJIT_MUL_F64 | SLJIT_F32_OP) /* Flags: SP - (never set any flags) */ -#define SLJIT_DDIV (SLJIT_FOP2_BASE + 3) -#define SLJIT_SDIV (SLJIT_DDIV | SLJIT_SINGLE_OP) +#define SLJIT_DIV_F64 (SLJIT_FOP2_BASE + 3) +#define SLJIT_DIV_F32 (SLJIT_DIV_F64 | SLJIT_F32_OP) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Label and jump instructions. */ @@ -943,58 +939,58 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi /* Integer comparison types. */ #define SLJIT_EQUAL 0 -#define SLJIT_I_EQUAL (SLJIT_EQUAL | SLJIT_INT_OP) +#define SLJIT_EQUAL32 (SLJIT_EQUAL | SLJIT_I32_OP) #define SLJIT_ZERO 0 -#define SLJIT_I_ZERO (SLJIT_ZERO | SLJIT_INT_OP) +#define SLJIT_ZERO32 (SLJIT_ZERO | SLJIT_I32_OP) #define SLJIT_NOT_EQUAL 1 -#define SLJIT_I_NOT_EQUAL (SLJIT_NOT_EQUAL | SLJIT_INT_OP) +#define SLJIT_NOT_EQUAL32 (SLJIT_NOT_EQUAL | SLJIT_I32_OP) #define SLJIT_NOT_ZERO 1 -#define SLJIT_I_NOT_ZERO (SLJIT_NOT_ZERO | SLJIT_INT_OP) +#define SLJIT_NOT_ZERO32 (SLJIT_NOT_ZERO | SLJIT_I32_OP) #define SLJIT_LESS 2 -#define SLJIT_I_LESS (SLJIT_LESS | SLJIT_INT_OP) +#define SLJIT_LESS32 (SLJIT_LESS | SLJIT_I32_OP) #define SLJIT_GREATER_EQUAL 3 -#define SLJIT_I_GREATER_EQUAL (SLJIT_GREATER_EQUAL | SLJIT_INT_OP) +#define SLJIT_GREATER_EQUAL32 (SLJIT_GREATER_EQUAL | SLJIT_I32_OP) #define SLJIT_GREATER 4 -#define SLJIT_I_GREATER (SLJIT_GREATER | SLJIT_INT_OP) +#define SLJIT_GREATER32 (SLJIT_GREATER | SLJIT_I32_OP) #define SLJIT_LESS_EQUAL 5 -#define SLJIT_I_LESS_EQUAL (SLJIT_LESS_EQUAL | SLJIT_INT_OP) +#define SLJIT_LESS_EQUAL32 (SLJIT_LESS_EQUAL | SLJIT_I32_OP) #define SLJIT_SIG_LESS 6 -#define SLJIT_I_SIG_LESS (SLJIT_SIG_LESS | SLJIT_INT_OP) +#define SLJIT_SIG_LESS32 (SLJIT_SIG_LESS | SLJIT_I32_OP) #define SLJIT_SIG_GREATER_EQUAL 7 -#define SLJIT_I_SIG_GREATER_EQUAL (SLJIT_SIG_GREATER_EQUAL | SLJIT_INT_OP) +#define SLJIT_SIG_GREATER_EQUAL32 (SLJIT_SIG_GREATER_EQUAL | SLJIT_I32_OP) #define SLJIT_SIG_GREATER 8 -#define SLJIT_I_SIG_GREATER (SLJIT_SIG_GREATER | SLJIT_INT_OP) +#define SLJIT_SIG_GREATER32 (SLJIT_SIG_GREATER | SLJIT_I32_OP) #define SLJIT_SIG_LESS_EQUAL 9 -#define SLJIT_I_SIG_LESS_EQUAL (SLJIT_SIG_LESS_EQUAL | SLJIT_INT_OP) +#define SLJIT_SIG_LESS_EQUAL32 (SLJIT_SIG_LESS_EQUAL | SLJIT_I32_OP) #define SLJIT_OVERFLOW 10 -#define SLJIT_I_OVERFLOW (SLJIT_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_OVERFLOW32 (SLJIT_OVERFLOW | SLJIT_I32_OP) #define SLJIT_NOT_OVERFLOW 11 -#define SLJIT_I_NOT_OVERFLOW (SLJIT_NOT_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_NOT_OVERFLOW32 (SLJIT_NOT_OVERFLOW | SLJIT_I32_OP) #define SLJIT_MUL_OVERFLOW 12 -#define SLJIT_I_MUL_OVERFLOW (SLJIT_MUL_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_MUL_OVERFLOW32 (SLJIT_MUL_OVERFLOW | SLJIT_I32_OP) #define SLJIT_MUL_NOT_OVERFLOW 13 -#define SLJIT_I_MUL_NOT_OVERFLOW (SLJIT_MUL_NOT_OVERFLOW | SLJIT_INT_OP) +#define SLJIT_MUL_NOT_OVERFLOW32 (SLJIT_MUL_NOT_OVERFLOW | SLJIT_I32_OP) /* Floating point comparison types. */ -#define SLJIT_D_EQUAL 14 -#define SLJIT_S_EQUAL (SLJIT_D_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_NOT_EQUAL 15 -#define SLJIT_S_NOT_EQUAL (SLJIT_D_NOT_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_LESS 16 -#define SLJIT_S_LESS (SLJIT_D_LESS | SLJIT_SINGLE_OP) -#define SLJIT_D_GREATER_EQUAL 17 -#define SLJIT_S_GREATER_EQUAL (SLJIT_D_GREATER_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_GREATER 18 -#define SLJIT_S_GREATER (SLJIT_D_GREATER | SLJIT_SINGLE_OP) -#define SLJIT_D_LESS_EQUAL 19 -#define SLJIT_S_LESS_EQUAL (SLJIT_D_LESS_EQUAL | SLJIT_SINGLE_OP) -#define SLJIT_D_UNORDERED 20 -#define SLJIT_S_UNORDERED (SLJIT_D_UNORDERED | SLJIT_SINGLE_OP) -#define SLJIT_D_ORDERED 21 -#define SLJIT_S_ORDERED (SLJIT_D_ORDERED | SLJIT_SINGLE_OP) +#define SLJIT_EQUAL_F64 14 +#define SLJIT_EQUAL_F32 (SLJIT_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_NOT_EQUAL_F64 15 +#define SLJIT_NOT_EQUAL_F32 (SLJIT_NOT_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_LESS_F64 16 +#define SLJIT_LESS_F32 (SLJIT_LESS_F64 | SLJIT_F32_OP) +#define SLJIT_GREATER_EQUAL_F64 17 +#define SLJIT_GREATER_EQUAL_F32 (SLJIT_GREATER_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_GREATER_F64 18 +#define SLJIT_GREATER_F32 (SLJIT_GREATER_F64 | SLJIT_F32_OP) +#define SLJIT_LESS_EQUAL_F64 19 +#define SLJIT_LESS_EQUAL_F32 (SLJIT_LESS_EQUAL_F64 | SLJIT_F32_OP) +#define SLJIT_UNORDERED_F64 20 +#define SLJIT_UNORDERED_F32 (SLJIT_UNORDERED_F64 | SLJIT_F32_OP) +#define SLJIT_ORDERED_F64 21 +#define SLJIT_ORDERED_F32 (SLJIT_ORDERED_F64 | SLJIT_F32_OP) /* Unconditional jump types. */ #define SLJIT_JUMP 22 @@ -1014,7 +1010,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP Flags: - (never set any flags) for both conditional and unconditional jumps. Flags: destroy all flags for calls. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type); /* Basic arithmetic comparison. In most architectures it is implemented as an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting @@ -1024,23 +1020,23 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP Flags: destroy flags. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Basic floating point comparison. In most architectures it is implemented as an SLJIT_FCMP operation (setting appropriate flags) followed by a sljit_emit_jump. However some architectures (i.e: MIPS) may employ special optimizations here. It is suggested to use this comparison form when appropriate. - type must be between SLJIT_D_EQUAL and SLJIT_S_ORDERED + type must be between SLJIT_EQUAL_F64 and SLJIT_ORDERED_F32 type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP Flags: destroy flags. Note: if either operand is NaN, the behaviour is undefined for types up to SLJIT_S_LESS_EQUAL. */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); /* Set the destination of the jump to this label. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label); @@ -1053,14 +1049,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw Indirect form: any other valid addressing mode Flags: - (never set any flags) for unconditional jumps. Flags: destroy all flags for calls. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw); /* Perform the operation using the conditional flags as the second argument. Type must always be between SLJIT_EQUAL and SLJIT_S_ORDERED. The value represented by the type is 1, if the condition represented by the type is fulfilled, and 0 otherwise. - If op == SLJIT_MOV, SLJIT_MOV_SI, SLJIT_MOV_UI: + If op == SLJIT_MOV, SLJIT_MOV_S32, SLJIT_MOV_U32: Set dst to the value represented by the type (0 or 1). Src must be SLJIT_UNUSED, and srcw must be 0 Flags: - (never set any flags) @@ -1070,18 +1066,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil Important note: only dst=src and dstw=srcw is supported at the moment! Flags: I | E | K Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type); /* Copies the base address of SLJIT_SP + offset to dst. Flags: - (never set any flags) */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset); /* The constant can be changed runtime (see: sljit_set_const) Flags: - (never set any flags) */ -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value); +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value); /* After the code generation the address for label, jump and const instructions are computed. Since these structures are freed by sljit_free_compiler, the @@ -1104,7 +1100,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta /* Get the human readable name of the platform. Can be useful on platforms like ARM, where ARM and Thumb2 functions can be mixed, and it is useful to know the type of the code generator. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void); /* Portable helper function to get an offset of a member. */ #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) @@ -1196,14 +1192,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct Note: it returns with -1 for virtual registers (only on x86-32). */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg); /* The following function is a helper function for sljit_emit_op_custom. It returns with the real machine register index of any SLJIT_FLOAT register. Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg); /* Any instruction can be inserted into the instruction stream by sljit_emit_op_custom. It has a similar purpose as inline assembly. @@ -1215,18 +1211,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); if size == 4, the instruction argument must be 4 byte aligned. Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size); #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) /* Returns with non-zero if sse2 is available. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void); /* Returns with non-zero if cmov instruction is available. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void); /* Emit a conditional mov instruction on x86 CPUs. This instruction moves src to destination, if the condition is satisfied. Unlike @@ -1235,14 +1231,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); checked by sljit_x86_is_cmov_available function. type must be between SLJIT_EQUAL and SLJIT_S_ORDERED dst_reg must be a valid register and it can be combined - with SLJIT_INT_OP to perform 32 bit arithmetic + with SLJIT_I32_OP to perform 32 bit arithmetic Flags: I - (never set any flags) */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, - sljit_si type, - sljit_si dst_reg, - sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw); #endif diff --git a/pcre/sljit/sljitNativeARM_32.c b/pcre/sljit/sljitNativeARM_32.c index 5cd4c71a298f6..b92808f5268fe 100644 --- a/pcre/sljit/sljitNativeARM_32.c +++ b/pcre/sljit/sljitNativeARM_32.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return "ARMv7" SLJIT_CPUINFO; @@ -52,10 +52,10 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) #define ALIGN_INSTRUCTION(ptr) \ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) #define MAX_DIFFERENCE(max_diff) \ - (((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + (((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 0, 0, 1, 2, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 12, 14, 15 }; @@ -126,13 +126,13 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si push_cpool(struct sljit_compiler *compiler) +static sljit_s32 push_cpool(struct sljit_compiler *compiler) { /* Pushing the constant pool into the instruction stream. */ sljit_uw* inst; sljit_uw* cpool_ptr; sljit_uw* cpool_end; - sljit_si i; + sljit_s32 i; /* The label could point the address after the constant pool. */ if (compiler->last_label && compiler->last_label->size == compiler->size) @@ -164,7 +164,7 @@ static sljit_si push_cpool(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; @@ -178,13 +178,13 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) return SLJIT_SUCCESS; } -static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; sljit_uw cpool_index = CPOOL_SIZE; sljit_uw* cpool_ptr; sljit_uw* cpool_end; - sljit_ub* cpool_unique_ptr; + sljit_u8* cpool_unique_ptr; if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) FAIL_IF(push_cpool(compiler)); @@ -228,7 +228,7 @@ static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw return SLJIT_SUCCESS; } -static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) @@ -248,7 +248,7 @@ static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, s return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) +static SLJIT_INLINE sljit_s32 prepare_blx(struct sljit_compiler *compiler) { /* Place for at least two instruction (doesn't matter whether the first has a literal). */ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) @@ -256,7 +256,7 @@ static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_blx(struct sljit_compiler *compiler) +static SLJIT_INLINE sljit_s32 emit_blx(struct sljit_compiler *compiler) { /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); @@ -286,7 +286,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ /* Must be a load instruction with immediate offset. */ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); - if ((sljit_si)const_pool[ind] < 0) { + if ((sljit_s32)const_pool[ind] < 0) { const_pool[ind] = counter; ind = counter; counter++; @@ -311,26 +311,26 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ /* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ struct future_patch { struct future_patch* next; - sljit_si index; - sljit_si value; + sljit_s32 index; + sljit_s32 value; }; -static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) { - sljit_si value; + sljit_s32 value; struct future_patch *curr_patch, *prev_patch; SLJIT_UNUSED_ARG(compiler); /* Using the values generated by patch_pc_relative_loads. */ if (!*first_patch) - value = (sljit_si)cpool_start_address[cpool_current_index]; + value = (sljit_s32)cpool_start_address[cpool_current_index]; else { curr_patch = *first_patch; - prev_patch = 0; + prev_patch = NULL; while (1) { if (!curr_patch) { - value = (sljit_si)cpool_start_address[cpool_current_index]; + value = (sljit_s32)cpool_start_address[cpool_current_index]; break; } if ((sljit_uw)curr_patch->index == cpool_current_index) { @@ -370,7 +370,7 @@ static sljit_si resolve_const_pool_index(struct sljit_compiler *compiler, struct #else -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; @@ -381,7 +381,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static SLJIT_INLINE sljit_s32 emit_imm(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); @@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si #endif -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) { sljit_sw diff; @@ -446,13 +446,13 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw return 0; } -static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush) +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_s32 flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; sljit_uw *inst = (sljit_uw*)ptr[0]; sljit_uw mov_pc = ptr[1]; - sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC); sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2); if (diff <= 0x7fffff && diff >= -0x800000) { @@ -504,7 +504,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, static sljit_uw get_imm(sljit_uw imm); -static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si flush) +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_s32 flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; @@ -789,7 +789,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } #endif - SLJIT_ASSERT(code_ptr - code <= (sljit_si)size); + SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size); compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw); @@ -820,16 +820,16 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size, i, tmp; + sljit_s32 size, i, tmp; sljit_uw push; CHECK_ERROR(); @@ -866,11 +866,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size; + sljit_s32 size; CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -881,9 +881,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp; + sljit_s32 i, tmp; sljit_uw pop; CHECK_ERROR(); @@ -983,8 +983,8 @@ static sljit_sw data_transfer_insts[16] = { } \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_s32 src2) { sljit_sw mul_inst; @@ -1001,17 +1001,17 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (op == SLJIT_MOV_UB) + if (op == SLJIT_MOV_U8) return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2]))); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | reg_map[dst])); #else - return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); + return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2)); #endif } else if (dst != src2) { @@ -1022,15 +1022,15 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2]))); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | reg_map[dst])); #else - return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); + return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2)); #endif } else if (dst != src2) { @@ -1139,7 +1139,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj Returns with 0 if not possible. */ static sljit_uw get_imm(sljit_uw imm) { - sljit_si rol; + sljit_s32 rol; if (imm <= 0xff) return SRC2_IMM | imm; @@ -1175,12 +1175,12 @@ static sljit_uw get_imm(sljit_uw imm) } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) +static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive) { sljit_uw mask; sljit_uw imm1; sljit_uw imm2; - sljit_si rol; + sljit_s32 rol; /* Step1: Search a zero byte (8 continous zero bit). */ mask = 0xff000000; @@ -1286,7 +1286,7 @@ static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, slji } #endif -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm) { sljit_uw tmp; @@ -1317,7 +1317,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl } /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) { if (value >= 0) { value = get_imm(value); @@ -1333,7 +1333,7 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_uw imm; @@ -1408,7 +1408,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { /* Immediate caching is not supported as it would be an operation on constant arguments. */ if (arg & SLJIT_IMM) @@ -1456,9 +1456,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_r; + sljit_s32 tmp_r; sljit_sw max_delta; sljit_sw sign; sljit_uw imm; @@ -1583,7 +1583,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return push_inst(compiler, EMIT_DATA_TRANSFER(inp_flags, 1, inp_flags & WRITE_BACK, reg, arg & REG_MASK, reg_map[tmp_r] | (max_delta & 0xf00 ? SRC2_IMM : 0))); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1592,17 +1592,17 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 inp_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg @@ -1610,25 +1610,25 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ /* We prefers register and simple consts. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + sljit_s32 dst_r; + sljit_s32 src1_r; + sljit_s32 src2_r = 0; + sljit_s32 sugg_src2_r = TMP_REG2; + sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0; compiler->cache_arg = 0; compiler->cache_argw = 0; /* Destination check. */ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; dst_r = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else { @@ -1695,7 +1695,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else do { /* do { } while(0) is used because of breaks. */ @@ -1804,7 +1804,7 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -1817,58 +1817,58 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_NOP: FAIL_IF(push_inst(compiler, NOP)); break; - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL) | (reg_map[SLJIT_R1] << 16) | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 8) | reg_map[SLJIT_R1]); #else FAIL_IF(push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_R1)))); - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL) | (reg_map[SLJIT_R1] << 16) | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 8) | reg_map[TMP_REG1]); #endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping); - if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { + if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) { FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */)); FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */)); } - else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) - FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); + else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3)) + FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */)); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, - ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); + ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else #error "Software divmod functions are needed" #endif - if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) { + if ((op >= SLJIT_DIV_UW) && (compiler->scratches >= 3)) { FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */)); FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */)); } - else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3)) - return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); + else if ((op >= SLJIT_DIV_UW) || (compiler->scratches >= 3)) + return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_DIV_UW ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */); return SLJIT_SUCCESS; } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1877,40 +1877,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler switch (GET_OPCODE(op)) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1929,10 +1929,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1971,20 +1971,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -2000,7 +2000,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* 0 - no fpu 1 - vfp */ -static sljit_si arm_fpu_type = -1; +static sljit_s32 arm_fpu_type = -1; static void init_compiler(void) { @@ -2011,7 +2011,7 @@ static void init_compiler(void) arm_fpu_type = 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -2026,7 +2026,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define arm_fpu_type 1 -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { /* Always available. */ return 1; @@ -2040,11 +2040,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_sw tmp; sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { @@ -2104,16 +2104,16 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); src = TMP_FREG1; } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_SINGLE_OP, TMP_FREG1, src, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_S32_F32, op & SLJIT_F32_OP, TMP_FREG1, src, 0))); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; @@ -2125,11 +2125,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, VMOV | RD(src) | (TMP_FREG1 << 16))); @@ -2142,85 +2142,85 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | (TMP_FREG1 << 16))); } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_SINGLE_OP, dst_r, TMP_FREG1, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_F32_OP, dst_r, TMP_FREG1, 0))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, src1, src2, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_F32_OP, src1, src2, 0))); return push_inst(compiler, VMRS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw)); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_F32_OP, dst_r, src, 0))); else dst_r = src; } break; - case SLJIT_DNEG: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + case SLJIT_NEG_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_F32_OP, dst_r, src, 0))); break; - case SLJIT_DABS: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); + case SLJIT_ABS_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_F32_OP, dst_r, src, 0))); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_SINGLE_OP, dst_r, src, 0))); - op ^= SLJIT_SINGLE_OP; + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F64_F32, op & SLJIT_F32_OP, dst_r, src, 0))); + op ^= SLJIT_F32_OP; break; } if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2230,40 +2230,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src2 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } if (src1 & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_ADD_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; - case SLJIT_DSUB: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_SUB_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; - case SLJIT_DMUL: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_MUL_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; - case SLJIT_DDIV: - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_r, src2, src1))); + case SLJIT_DIV_F64: + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_F32_OP, dst_r, src2, src1))); break; } if (dst_r == TMP_FREG1) - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw)); return SLJIT_SUCCESS; } @@ -2276,7 +2276,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -2299,7 +2299,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -2326,33 +2326,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x00000000; case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x10000000; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x30000000; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x20000000; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x80000000; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x90000000; case SLJIT_SIG_LESS: @@ -2368,11 +2368,11 @@ static sljit_uw get_cc(sljit_si type) return 0xd0000000; case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x60000000; case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x70000000; default: @@ -2397,7 +2397,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -2438,7 +2438,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; @@ -2475,12 +2475,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags = GET_ALL_FLAGS(op); sljit_uw cc, ins; CHECK_ERROR(); @@ -2528,10 +2528,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre/sljit/sljitNativeARM_64.c b/pcre/sljit/sljitNativeARM_64.c index 044a675eee79e..d9958512c80dd 100644 --- a/pcre/sljit/sljitNativeARM_64.c +++ b/pcre/sljit/sljitNativeARM_64.c @@ -24,13 +24,13 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "ARM-64" SLJIT_CPUINFO; } /* Length of an instruction word */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; #define TMP_ZERO (0) @@ -43,7 +43,7 @@ typedef sljit_ui sljit_ins; #define TMP_FREG1 (0) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { 31, 0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, 8, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 29, 9, 10, 11, 30, 31 }; @@ -124,7 +124,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 8] = { /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -133,7 +133,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) { FAIL_IF(push_inst(compiler, MOVZ | RD(dst) | ((imm & 0xffff) << 5))); FAIL_IF(push_inst(compiler, MOVK | RD(dst) | (((imm >> 16) & 0xffff) << 5) | (1 << 21))); @@ -143,7 +143,7 @@ static SLJIT_INLINE sljit_si emit_imm64_const(struct sljit_compiler *compiler, s static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) { - sljit_si dst = inst[0] & 0x1f; + sljit_s32 dst = inst[0] & 0x1f; SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21))); inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5); inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21); @@ -151,7 +151,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm) inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21); } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; @@ -212,7 +212,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil sljit_ins *buf_end; sljit_uw word_count; sljit_uw addr; - sljit_si dst; + sljit_s32 dst; struct sljit_label *label; struct sljit_jump *jump; @@ -346,9 +346,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define LOGICAL_IMM_CHECK 0x100 -static sljit_ins logical_imm(sljit_sw imm, sljit_si len) +static sljit_ins logical_imm(sljit_sw imm, sljit_s32 len) { - sljit_si negated, ones, right; + sljit_s32 negated, ones, right; sljit_uw mask, uimm; sljit_ins ins; @@ -356,12 +356,12 @@ static sljit_ins logical_imm(sljit_sw imm, sljit_si len) len &= ~LOGICAL_IMM_CHECK; if (len == 32 && (imm == 0 || imm == -1)) return 0; - if (len == 16 && ((sljit_si)imm == 0 || (sljit_si)imm == -1)) + if (len == 16 && ((sljit_s32)imm == 0 || (sljit_s32)imm == -1)) return 0; } SLJIT_ASSERT((len == 32 && imm != 0 && imm != -1) - || (len == 16 && (sljit_si)imm != 0 && (sljit_si)imm != -1)); + || (len == 16 && (sljit_s32)imm != 0 && (sljit_s32)imm != -1)); uimm = (sljit_uw)imm; while (1) { if (len <= 0) { @@ -410,10 +410,10 @@ static sljit_ins logical_imm(sljit_sw imm, sljit_si len) #undef COUNT_TRAILING_ZERO -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw simm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw simm) { sljit_uw imm = (sljit_uw)simm; - sljit_si i, zeros, ones, first; + sljit_s32 i, zeros, ones, first; sljit_ins bitmask; if (imm <= 0xffff) @@ -512,15 +512,15 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl dst = TMP_ZERO; \ } -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_sw arg1, sljit_sw arg2) +static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_sw arg1, sljit_sw arg2) { /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; sljit_ins inst_bits; - sljit_si op = (flags & 0xffff); - sljit_si reg; + sljit_s32 op = (flags & 0xffff); + sljit_s32 reg; sljit_sw imm, nimm; if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { @@ -667,34 +667,34 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj if (dst == arg2) return SLJIT_SUCCESS; return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_MOV_UB: - case SLJIT_MOVU_UB: + case SLJIT_MOV_U8: + case SLJIT_MOVU_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); - case SLJIT_MOV_SB: - case SLJIT_MOVU_SB: + case SLJIT_MOV_S8: + case SLJIT_MOVU_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (!(flags & INT_OP)) inv_bits |= 1 << 22; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); - case SLJIT_MOV_UH: - case SLJIT_MOVU_UH: + case SLJIT_MOV_U16: + case SLJIT_MOVU_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); - case SLJIT_MOV_SH: - case SLJIT_MOVU_SH: + case SLJIT_MOV_S16: + case SLJIT_MOVU_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (!(flags & INT_OP)) inv_bits |= 1 << 22; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); - case SLJIT_MOV_UI: - case SLJIT_MOVU_UI: + case SLJIT_MOV_U32: + case SLJIT_MOVU_U32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if ((flags & INT_OP) && dst == arg2) return SLJIT_SUCCESS; return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); - case SLJIT_MOV_SI: - case SLJIT_MOVU_SI: + case SLJIT_MOV_S32: + case SLJIT_MOVU_S32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if ((flags & INT_OP) && dst == arg2) return SLJIT_SUCCESS; @@ -777,28 +777,28 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj #define MEM_SIZE_SHIFT(flags) ((flags) >> 8) -static SLJIT_CONST sljit_ins sljit_mem_imm[4] = { +static const sljit_ins sljit_mem_imm[4] = { /* u l */ 0x39400000 /* ldrb [reg,imm] */, /* u s */ 0x39000000 /* strb [reg,imm] */, /* s l */ 0x39800000 /* ldrsb [reg,imm] */, /* s s */ 0x39000000 /* strb [reg,imm] */, }; -static SLJIT_CONST sljit_ins sljit_mem_simm[4] = { +static const sljit_ins sljit_mem_simm[4] = { /* u l */ 0x38400000 /* ldurb [reg,imm] */, /* u s */ 0x38000000 /* sturb [reg,imm] */, /* s l */ 0x38800000 /* ldursb [reg,imm] */, /* s s */ 0x38000000 /* sturb [reg,imm] */, }; -static SLJIT_CONST sljit_ins sljit_mem_pre_simm[4] = { +static const sljit_ins sljit_mem_pre_simm[4] = { /* u l */ 0x38400c00 /* ldrb [reg,imm]! */, /* u s */ 0x38000c00 /* strb [reg,imm]! */, /* s l */ 0x38800c00 /* ldrsb [reg,imm]! */, /* s s */ 0x38000c00 /* strb [reg,imm]! */, }; -static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { +static const sljit_ins sljit_mem_reg[4] = { /* u l */ 0x38606800 /* ldrb [reg,reg] */, /* u s */ 0x38206800 /* strb [reg,reg] */, /* s l */ 0x38a06800 /* ldrsb [reg,reg] */, @@ -806,7 +806,7 @@ static SLJIT_CONST sljit_ins sljit_mem_reg[4] = { }; /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) { if (value >= 0) { if (value <= 0xfff) @@ -825,9 +825,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { - sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_u32 shift = MEM_SIZE_SHIFT(flags); SLJIT_ASSERT(arg & SLJIT_MEM); @@ -882,7 +882,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* see getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { sljit_sw diff; if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) @@ -906,11 +906,11 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, - sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, + sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_ui shift = MEM_SIZE_SHIFT(flags); - sljit_si tmp_r, other_r; + sljit_u32 shift = MEM_SIZE_SHIFT(flags); + sljit_s32 tmp_r, other_r; sljit_sw diff; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1040,7 +1040,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst(compiler, sljit_mem_imm[flags & 0x3] | (shift << 30) | RT(reg) | RN(TMP_REG3)); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1049,7 +1049,7 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; @@ -1060,11 +1060,11 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit /* Entry, exit */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si i, tmp, offs, prev, saved_regs_size; + sljit_s32 i, tmp, offs, prev, saved_regs_size; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1148,9 +1148,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1162,10 +1162,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si local_size; - sljit_si i, tmp, offs, prev, saved_regs_size; + sljit_s32 local_size; + sljit_s32 i, tmp, offs, prev, saved_regs_size; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -1243,9 +1243,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { - sljit_ins inv_bits = (op & SLJIT_INT_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (op & SLJIT_I32_OP) ? (1 << 31) : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -1256,31 +1256,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, BRK); case SLJIT_NOP: return push_inst(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); - return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: + return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); - FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); + FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); - case SLJIT_UDIVI: - case SLJIT_SDIVI: - return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r, flags, mem_flags; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags, mem_flags; + sljit_s32 op_flags = GET_ALL_FLAGS(op); CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1299,69 +1299,69 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: flags = WORD_SIZE; break; - case SLJIT_MOV_UB: + case SLJIT_MOV_U8: flags = BYTE_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOV_SB: + case SLJIT_MOV_S8: flags = BYTE_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOV_UH: + case SLJIT_MOV_U16: flags = HALF_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOV_SH: + case SLJIT_MOV_S16: flags = HALF_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; - case SLJIT_MOV_UI: + case SLJIT_MOV_U32: flags = INT_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ui)srcw; + srcw = (sljit_u32)srcw; break; - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: flags = INT_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; break; case SLJIT_MOVU: case SLJIT_MOVU_P: flags = WORD_SIZE | UPDATE; break; - case SLJIT_MOVU_UB: + case SLJIT_MOVU_U8: flags = BYTE_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOVU_SB: + case SLJIT_MOVU_S8: flags = BYTE_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOVU_UH: + case SLJIT_MOVU_U16: flags = HALF_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOVU_SH: + case SLJIT_MOVU_S16: flags = HALF_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; - case SLJIT_MOVU_UI: + case SLJIT_MOVU_U32: flags = INT_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ui)srcw; + srcw = (sljit_u32)srcw; break; - case SLJIT_MOVU_SI: + case SLJIT_MOVU_S32: flags = INT_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; break; default: SLJIT_ASSERT_STOP(); @@ -1378,7 +1378,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); } else { if (dst_r != TMP_REG1) - return emit_op_imm(compiler, op | ((op_flags & SLJIT_INT_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); + return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src); dst_r = src; } @@ -1393,7 +1393,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0; mem_flags = WORD_SIZE; - if (op_flags & SLJIT_INT_OP) { + if (op_flags & SLJIT_I32_OP) { flags |= INT_OP; mem_flags = INT_SIZE; } @@ -1411,8 +1411,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (src & SLJIT_IMM) { flags |= ARG2_IMM; - if (op_flags & SLJIT_INT_OP) - srcw = (sljit_si)srcw; + if (op_flags & SLJIT_I32_OP) + srcw = (sljit_s32)srcw; } else srcw = src; @@ -1427,12 +1427,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags, mem_flags; + sljit_s32 dst_r, flags, mem_flags; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1446,7 +1446,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; flags = GET_FLAGS(op) ? SET_FLAGS : 0; mem_flags = WORD_SIZE; - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { flags |= INT_OP; mem_flags = INT_SIZE; } @@ -1512,20 +1512,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1537,7 +1537,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1547,11 +1547,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { - sljit_ui shift = MEM_SIZE_SHIFT(flags); + sljit_u32 shift = MEM_SIZE_SHIFT(flags); sljit_ins ins_bits = (shift << 30); - sljit_si other_r; + sljit_s32 other_r; sljit_sw diff; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1600,45 +1600,45 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst(compiler, STR_FI | ins_bits | VT(reg) | RN(TMP_REG3)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; - if (GET_OPCODE(op) == SLJIT_CONVI_FROMD) + if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) inv_bits |= (1 << 31); if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); src = TMP_FREG1; } FAIL_IF(push_inst(compiler, (FCVTZS ^ inv_bits) | RD(dst_r) | VN(src))); if (dst_r == TMP_REG1 && dst != SLJIT_UNUSED) - return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVI_FROMD) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); + return emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? INT_SIZE : WORD_SIZE) | STORE, TMP_REG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) inv_bits |= (1 << 31); if (src & SLJIT_MEM) { - emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONVD_FROMI) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); + emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw); src = TMP_REG1; } else if (src & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; @@ -1647,16 +1647,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, ((op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, ((op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; if (src1 & SLJIT_MEM) { emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); @@ -1671,11 +1671,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; + sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; sljit_ins inv_bits; CHECK_ERROR(); @@ -1685,16 +1685,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile SLJIT_COMPILE_ASSERT((INT_SIZE ^ 0x100) == WORD_SIZE, must_be_one_bit_difference); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONVD_FROMS) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); + emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x100) : mem_flags, dst_r, src, srcw); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src))); @@ -1702,14 +1702,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(src))); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src))); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_SINGLE_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst(compiler, FCVT | ((op & SLJIT_F32_OP) ? (1 << 22) : (1 << 15)) | VD(dst_r) | VN(src))); break; } @@ -1718,13 +1718,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, mem_flags = (op & SLJIT_SINGLE_OP) ? INT_SIZE : WORD_SIZE; - sljit_ins inv_bits = (op & SLJIT_SINGLE_OP) ? (1 << 22) : 0; + sljit_s32 dst_r, mem_flags = (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE; + sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1746,16 +1746,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile } switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, (FADD ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, (FSUB ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, (FMUL ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; } @@ -1769,7 +1769,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1786,7 +1786,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1806,33 +1806,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x1; case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x0; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x2; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x3; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x9; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x8; case SLJIT_SIG_LESS: @@ -1848,11 +1848,11 @@ static sljit_uw get_cc(sljit_si type) return 0xc; case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x7; case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x6; default: @@ -1877,7 +1877,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -1903,11 +1903,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_si type, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; - sljit_ins inv_bits = (type & SLJIT_INT_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (type & SLJIT_I32_OP) ? (1 << 31) : 0; SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL); ADJUST_LOCAL_OFFSET(src, srcw); @@ -1937,7 +1937,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; @@ -1964,12 +1964,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si dst_r, flags, mem_flags; + sljit_s32 dst_r, flags, mem_flags; sljit_ins cc; CHECK_ERROR(); @@ -1994,7 +1994,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com compiler->cache_argw = 0; flags = GET_FLAGS(op) ? SET_FLAGS : 0; mem_flags = WORD_SIZE; - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { flags |= INT_OP; mem_flags = INT_SIZE; } @@ -2014,10 +2014,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return emit_op_mem2(compiler, mem_flags | STORE, TMP_REG1, dst, dstw, 0, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre/sljit/sljitNativeARM_T2_32.c b/pcre/sljit/sljitNativeARM_T2_32.c index f9803f5d44f7b..1ed44a8130388 100644 --- a/pcre/sljit/sljitNativeARM_T2_32.c +++ b/pcre/sljit/sljitNativeARM_T2_32.c @@ -24,13 +24,13 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "ARM-Thumb2" SLJIT_CPUINFO; } /* Length of an instruction word. */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; /* Last register + 1. */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) @@ -42,7 +42,7 @@ typedef sljit_ui sljit_ins; #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 13, 3, 4, 14, 15 }; @@ -181,21 +181,21 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 -static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst) +static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uh *ptr; + sljit_u16 *ptr; SLJIT_ASSERT(!(inst & 0xffff0000)); - ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_uh)); + ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16)); FAIL_IF(!ptr); *ptr = inst; compiler->size++; return SLJIT_SUCCESS; } -static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) +static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); + sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr++ = inst >> 16; *ptr = inst; @@ -203,7 +203,7 @@ static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) { FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff))); @@ -211,9 +211,9 @@ static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, s COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16)); } -static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm) +static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm) { - sljit_si dst = inst[1] & 0x0f00; + sljit_s32 dst = inst[1] & 0x0f00; SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); @@ -221,7 +221,7 @@ static SLJIT_INLINE void modify_imm32_const(sljit_uh *inst, sljit_uw new_imm) inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code) { sljit_sw diff; @@ -278,13 +278,13 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) { - sljit_si type = (jump->flags >> 4) & 0xf; + sljit_s32 type = (jump->flags >> 4) & 0xf; sljit_sw diff; - sljit_uh *jump_inst; - sljit_si s, j1, j2; + sljit_u16 *jump_inst; + sljit_s32 s, j1, j2; if (SLJIT_UNLIKELY(type == 0)) { - modify_imm32_const((sljit_uh*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); + modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); return; } @@ -294,7 +294,7 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) } else diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1; - jump_inst = (sljit_uh*)jump->addr; + jump_inst = (sljit_u16*)jump->addr; switch (type) { case 1: @@ -342,10 +342,10 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; - sljit_uh *code; - sljit_uh *code_ptr; - sljit_uh *buf_ptr; - sljit_uh *buf_end; + sljit_u16 *code; + sljit_u16 *code_ptr; + sljit_u16 *buf_ptr; + sljit_u16 *buf_end; sljit_uw half_count; struct sljit_label *label; @@ -356,7 +356,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil CHECK_PTR(check_sljit_generate_code(compiler)); reverse_buf(compiler); - code = (sljit_uh*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_uh)); + code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16)); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -367,7 +367,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil const_ = compiler->consts; do { - buf_ptr = (sljit_uh*)buf->memory; + buf_ptr = (sljit_u16*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 1); do { *code_ptr = *buf_ptr++; @@ -414,7 +414,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } compiler->error = SLJIT_ERR_COMPILED; - compiler->executable_size = (code_ptr - code) * sizeof(sljit_uh); + compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16); SLJIT_CACHE_FLUSH(code, code_ptr); /* Set thumb mode flag. */ return (void*)((sljit_uw)code | 0x1); @@ -428,7 +428,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil static sljit_uw get_imm(sljit_uw imm) { /* Thumb immediate form. */ - sljit_si counter; + sljit_s32 counter; if (imm <= 0xff) return imm; @@ -474,7 +474,7 @@ static sljit_uw get_imm(sljit_uw imm) return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); } -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm) { sljit_uw tmp; @@ -508,12 +508,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl #define SLOW_SRC1 0x0800000 #define SLOW_SRC2 0x1000000 -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_uw arg1, sljit_uw arg2) +static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2) { /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ - sljit_si reg; + sljit_s32 reg; sljit_uw imm, nimm; if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { @@ -677,37 +677,37 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj /* Both arguments are registers. */ switch (flags & 0xffff) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: case SLJIT_MOVU_P: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (dst == arg2) return SLJIT_SUCCESS; return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); - case SLJIT_MOV_UB: - case SLJIT_MOVU_UB: + case SLJIT_MOV_U8: + case SLJIT_MOVU_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2)); return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_SB: - case SLJIT_MOVU_SB: + case SLJIT_MOV_S8: + case SLJIT_MOVU_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_UH: - case SLJIT_MOVU_UH: + case SLJIT_MOV_U16: + case SLJIT_MOVU_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2)); return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2)); - case SLJIT_MOV_SH: - case SLJIT_MOVU_SH: + case SLJIT_MOV_S16: + case SLJIT_MOVU_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); @@ -813,7 +813,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj s = store */ -static SLJIT_CONST sljit_ins sljit_mem16[12] = { +static const sljit_ins sljit_mem16[12] = { /* w u l */ 0x5800 /* ldr */, /* w u s */ 0x5000 /* str */, /* w s l */ 0x5800 /* ldr */, @@ -830,7 +830,7 @@ static SLJIT_CONST sljit_ins sljit_mem16[12] = { /* h s s */ 0x5200 /* strh */, }; -static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = { +static const sljit_ins sljit_mem16_imm5[12] = { /* w u l */ 0x6800 /* ldr imm5 */, /* w u s */ 0x6000 /* str imm5 */, /* w s l */ 0x6800 /* ldr imm5 */, @@ -849,7 +849,7 @@ static SLJIT_CONST sljit_ins sljit_mem16_imm5[12] = { #define MEM_IMM8 0xc00 #define MEM_IMM12 0x800000 -static SLJIT_CONST sljit_ins sljit_mem32[12] = { +static const sljit_ins sljit_mem32[12] = { /* w u l */ 0xf8500000 /* ldr.w */, /* w u s */ 0xf8400000 /* str.w */, /* w s l */ 0xf8500000 /* ldr.w */, @@ -867,7 +867,7 @@ static SLJIT_CONST sljit_ins sljit_mem32[12] = { }; /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static sljit_s32 emit_set_delta(struct sljit_compiler *compiler, sljit_s32 dst, sljit_s32 reg, sljit_sw value) { if (value >= 0) { if (value <= 0xfff) @@ -888,9 +888,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { - sljit_si other_r, shift; + sljit_s32 other_r, shift; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -975,7 +975,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* see getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { sljit_sw diff; if ((arg & OFFS_REG_MASK) || !(next_arg & SLJIT_MEM)) @@ -999,10 +999,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, - sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, + sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_r, other_r; + sljit_s32 tmp_r, other_r; sljit_sw diff; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1107,7 +1107,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1116,7 +1116,7 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; @@ -1127,11 +1127,11 @@ static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit /* Entry, exit */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size, i, tmp; + sljit_s32 size, i, tmp; sljit_ins push; CHECK_ERROR(); @@ -1172,11 +1172,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size; + sljit_s32 size; CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1187,9 +1187,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp; + sljit_s32 i, tmp; sljit_ins pop; CHECK_ERROR(); @@ -1237,7 +1237,7 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { sljit_sw saved_reg_list[3]; sljit_sw saved_reg_count; @@ -1251,18 +1251,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst16(compiler, BKPT); case SLJIT_NOP: return push_inst16(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - return push_inst32(compiler, (op == SLJIT_LUMUL ? UMULL : SMULL) + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: + return push_inst32(compiler, (op == SLJIT_LMUL_UW ? UMULL : SMULL) | (reg_map[SLJIT_R1] << 8) | (reg_map[SLJIT_R0] << 12) | (reg_map[SLJIT_R0] << 16) | reg_map[SLJIT_R1]); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping); saved_reg_count = 0; @@ -1270,7 +1270,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler saved_reg_list[saved_reg_count++] = 12; if (compiler->scratches >= 3) saved_reg_list[saved_reg_count++] = 2; - if (op >= SLJIT_UDIVI) + if (op >= SLJIT_DIV_UW) saved_reg_list[saved_reg_count++] = 1; if (saved_reg_count > 0) { @@ -1288,7 +1288,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, - ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); + ((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod)))); #else #error "Software divmod functions are needed" #endif @@ -1311,12 +1311,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r, flags; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags; + sljit_s32 op_flags = GET_ALL_FLAGS(op); CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1332,56 +1332,56 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { switch (op) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: flags = WORD_SIZE; break; - case SLJIT_MOV_UB: + case SLJIT_MOV_U8: flags = BYTE_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOV_SB: + case SLJIT_MOV_S8: flags = BYTE_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOV_UH: + case SLJIT_MOV_U16: flags = HALF_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOV_SH: + case SLJIT_MOV_S16: flags = HALF_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; case SLJIT_MOVU: - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: case SLJIT_MOVU_P: flags = WORD_SIZE | UPDATE; break; - case SLJIT_MOVU_UB: + case SLJIT_MOVU_U8: flags = BYTE_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (sljit_u8)srcw; break; - case SLJIT_MOVU_SB: + case SLJIT_MOVU_S8: flags = BYTE_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (sljit_s8)srcw; break; - case SLJIT_MOVU_UH: + case SLJIT_MOVU_U16: flags = HALF_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (sljit_u16)srcw; break; - case SLJIT_MOVU_SH: + case SLJIT_MOVU_S16: flags = HALF_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (sljit_s16)srcw; break; default: SLJIT_ASSERT_STOP(); @@ -1444,12 +1444,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags; + sljit_s32 dst_r, flags; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1523,26 +1523,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); if (size == 2) - return push_inst16(compiler, *(sljit_uh*)instruction); + return push_inst16(compiler, *(sljit_u16*)instruction); return push_inst32(compiler, *(sljit_ins*)instruction); } @@ -1550,7 +1550,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1562,11 +1562,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define FPU_LOAD (1 << 20) -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_sw tmp; sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + sljit_sw inst = VSTR_F32 | (flags & (SLJIT_F32_OP | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1626,16 +1626,16 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src, srcw)); src = TMP_FREG1; } - FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_SINGLE_OP) | DD4(TMP_FREG1) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_F32_OP) | DD4(TMP_FREG1) | DM4(src))); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; @@ -1647,11 +1647,11 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (FAST_IS_REG(src)) FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1))); @@ -1664,85 +1664,85 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1))); } - FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(TMP_FREG1))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); src2 = TMP_FREG2; } - FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_F32_OP) | DD4(src1) | DM4(src2))); return push_inst32(compiler, VMRS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - if (GET_OPCODE(op) != SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) != SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, dst_r, src, srcw); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); else dst_r = src; } break; - case SLJIT_DNEG: - FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + case SLJIT_NEG_F64: + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); break; - case SLJIT_DABS: - FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + case SLJIT_ABS_F64: + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); - op ^= SLJIT_SINGLE_OP; + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DM4(src))); + op ^= SLJIT_F32_OP; break; } if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_r, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), dst_r, dst, dstw); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1752,36 +1752,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + emit_fop_mem(compiler, (op & SLJIT_F32_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); src2 = TMP_FREG2; } switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_ADD_F64: + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DSUB: - FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_SUB_F64: + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DMUL: - FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_MUL_F64: + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DDIV: - FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_DIV_F64: + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_F32_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); break; } if (!(dst & SLJIT_MEM)) return SLJIT_SUCCESS; - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (op & SLJIT_F32_OP), TMP_FREG1, dst, dstw); } #undef FPU_LOAD @@ -1790,7 +1790,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1813,7 +1813,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1840,33 +1840,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x0; case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x1; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x3; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x2; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x8; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x9; case SLJIT_SIG_LESS: @@ -1882,11 +1882,11 @@ static sljit_uw get_cc(sljit_si type) return 0xd; case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x6; case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x7; default: /* SLJIT_JUMP */ @@ -1911,7 +1911,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins cc; @@ -1944,7 +1944,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; @@ -1972,12 +1972,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si dst_r, flags = GET_ALL_FLAGS(op); + sljit_s32 dst_r, flags = GET_ALL_FLAGS(op); sljit_ins cc, ins; CHECK_ERROR(); @@ -2054,10 +2054,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); @@ -2077,14 +2077,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { - sljit_uh *inst = (sljit_uh*)addr; + sljit_u16 *inst = (sljit_u16*)addr; modify_imm32_const(inst, new_addr); SLJIT_CACHE_FLUSH(inst, inst + 4); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) { - sljit_uh *inst = (sljit_uh*)addr; + sljit_u16 *inst = (sljit_u16*)addr; modify_imm32_const(inst, new_constant); SLJIT_CACHE_FLUSH(inst, inst + 4); } diff --git a/pcre/sljit/sljitNativeMIPS_32.c b/pcre/sljit/sljitNativeMIPS_32.c index b2b60d7a4c9d5..5096e4f55eab3 100644 --- a/pcre/sljit/sljitNativeMIPS_32.c +++ b/pcre/sljit/sljitNativeMIPS_32.c @@ -26,7 +26,7 @@ /* mips 32-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { if (!(imm & ~0xffff)) return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); @@ -66,24 +66,24 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | D(dst), DR(dst))); \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { switch (GET_OPCODE(op)) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if (dst != src2) return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { + if (op == SLJIT_MOV_S8) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); #else @@ -97,11 +97,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { + if (op == SLJIT_MOV_S16) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); #else @@ -341,7 +341,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) { FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst))); return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); diff --git a/pcre/sljit/sljitNativeMIPS_64.c b/pcre/sljit/sljitNativeMIPS_64.c index 185fb5768e2a6..c7ee8c9c2e613 100644 --- a/pcre/sljit/sljitNativeMIPS_64.c +++ b/pcre/sljit/sljitNativeMIPS_64.c @@ -26,11 +26,11 @@ /* mips 64-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { - sljit_si shift = 32; - sljit_si shift2; - sljit_si inv = 0; + sljit_s32 shift = 32; + sljit_s32 shift2; + sljit_s32 inv = 0; sljit_ins ins; sljit_uw uimm; @@ -119,7 +119,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, } #define SELECT_OP(a, b) \ - (!(op & SLJIT_INT_OP) ? a : b) + (!(op & SLJIT_I32_OP) ? a : b) #define EMIT_LOGICAL(op_imm, op_norm) \ if (flags & SRC2_IMM) { \ @@ -138,27 +138,27 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, #define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \ if (flags & SRC2_IMM) { \ if (src2 >= 32) { \ - SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \ + SLJIT_ASSERT(!(op & SLJIT_I32_OP)); \ ins = op_dimm32; \ src2 -= 32; \ } \ else \ - ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \ + ins = (op & SLJIT_I32_OP) ? op_imm : op_dimm; \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \ } \ else { \ - ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \ + ins = (op & SLJIT_I32_OP) ? op_v : op_dv; \ if (op & SLJIT_SET_E) \ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \ if (CHECK_FLAGS(SLJIT_SET_E)) \ FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | D(dst), DR(dst))); \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { sljit_ins ins; @@ -170,11 +170,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(dst), DR(dst)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { + if (op == SLJIT_MOV_S8) { FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); } @@ -184,11 +184,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { + if (op == SLJIT_MOV_S16) { FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); } @@ -198,12 +198,12 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UI: - SLJIT_ASSERT(!(op & SLJIT_INT_OP)); + case SLJIT_MOV_U32: + SLJIT_ASSERT(!(op & SLJIT_I32_OP)); FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst)); @@ -231,7 +231,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); /* Check zero. */ FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM((op & SLJIT_I32_OP) ? 32 : 64), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst))); /* Loop for searching the highest bit. */ FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst))); @@ -392,7 +392,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT(!(flags & SRC2_IMM)); if (!(op & SLJIT_SET_O)) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); @@ -436,7 +436,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) { FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst))); FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst))); diff --git a/pcre/sljit/sljitNativeMIPS_common.c b/pcre/sljit/sljitNativeMIPS_common.c index cf3535f81a77c..c2c251b1ff469 100644 --- a/pcre/sljit/sljitNativeMIPS_common.c +++ b/pcre/sljit/sljitNativeMIPS_common.c @@ -27,7 +27,7 @@ /* Latest MIPS architecture. */ /* Automatically detect SLJIT_MIPS_R1 */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { #if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -42,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) /* Length of an instruction word Both for mips-32 and mips-64 */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) @@ -68,7 +68,7 @@ typedef sljit_ui sljit_ins; #define TMP_FREG1 (0) #define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 2, 5, 6, 7, 8, 9, 10, 11, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4 }; @@ -201,7 +201,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) { SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); @@ -213,7 +213,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_ return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins invert_branch(sljit_si flags) +static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags) { return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); } @@ -538,12 +538,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #include "sljitNativeMIPS_64.c" #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_ins base; - sljit_si i, tmp, offs; + sljit_s32 i, tmp, offs; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -575,12 +575,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; for (i = SLJIT_S0; i >= tmp; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); } for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS)); } @@ -594,9 +594,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -611,9 +611,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si local_size, i, tmp, offs; + sljit_s32 local_size, i, tmp, offs; sljit_ins base; CHECK_ERROR(); @@ -631,19 +631,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi local_size = 0; } - FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_si)sizeof(sljit_sw)), RETURN_ADDR_REG)); - offs = local_size - (sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - (sljit_s32)sizeof(sljit_sw)), RETURN_ADDR_REG)); + offs = local_size - (sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); tmp = compiler->scratches; for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; for (i = tmp; i <= SLJIT_S0; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(i) | IMM(offs), DR(i))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } SLJIT_ASSERT(offs == local_size - (sljit_sw)(sizeof(sljit_sw))); @@ -668,7 +668,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #define ARCH_32_64(a, b) b #endif -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +static const sljit_ins data_transfer_insts[16 + 4] = { /* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), /* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), /* u b s */ HI(40) /* sb */, @@ -698,7 +698,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { /* reg_ar is an absoulute register! */ /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { SLJIT_ASSERT(arg & SLJIT_MEM); @@ -716,7 +716,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); @@ -739,9 +739,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_ar, base, delay_slot; + sljit_s32 tmp_ar, base, delay_slot; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -878,7 +878,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; @@ -887,26 +887,26 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; + sljit_s32 dst_r = TMP_REG2; + sljit_s32 src1_r; sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + sljit_s32 sugg_src2_r = TMP_REG2; if (!(flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -914,7 +914,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; @@ -922,7 +922,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) @@ -976,7 +976,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { @@ -987,7 +987,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } else { src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) dst_r = 0; } } @@ -1029,10 +1029,10 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - sljit_si int_op = op & SLJIT_INT_OP; + sljit_s32 int_op = op & SLJIT_I32_OP; #endif CHECK_ERROR(); @@ -1044,20 +1044,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, BREAK, UNMOVABLE_INS); case SLJIT_NOP: return push_inst(compiler, NOP, UNMOVABLE_INS); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #else - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #endif FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); #if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); @@ -1065,28 +1065,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if (int_op) - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); else - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #else - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); #endif FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0))); - return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); + return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = 0; + sljit_s32 flags = 0; #endif CHECK_ERROR(); @@ -1095,10 +1095,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src, srcw); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if ((op & SLJIT_INT_OP) && GET_OPCODE(op) >= SLJIT_NOT) { + if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT) { flags |= INT_DATA | SIGNED_DATA; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; } #endif @@ -1107,61 +1107,61 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UI: + case SLJIT_MOV_U32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); #endif - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UI: + case SLJIT_MOVU_U32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); #endif - case SLJIT_MOVU_SI: + case SLJIT_MOVU_S32: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1180,15 +1180,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = 0; + sljit_s32 flags = 0; #endif CHECK_ERROR(); @@ -1198,12 +1198,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(src2, src2w); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { flags |= INT_DATA | SIGNED_DATA; if (src1 & SLJIT_IMM) - src1w = (sljit_si)src1w; + src1w = (sljit_s32)src1w; if (src2 & SLJIT_IMM) - src2w = (sljit_si)src2w; + src2w = (sljit_s32)src2w; } #endif @@ -1232,7 +1232,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler src2w &= 0x1f; #else if (src2 & SLJIT_IMM) { - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) src2w &= 0x1f; else src2w &= 0x3f; @@ -1248,20 +1248,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1273,7 +1273,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1286,17 +1286,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define FMT(op) (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) << (21 - 8)) +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7)) +#define FMT(op) (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) << (21 - 8)) -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVW_FROMD) << 21; + sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) << 21; #endif if (src & SLJIT_MEM) { @@ -1322,17 +1322,17 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * #endif } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define flags 0 #else - sljit_si flags = (GET_OPCODE(op) == SLJIT_CONVD_FROMW) << 21; + sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21; #endif - sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); @@ -1342,14 +1342,14 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); } - FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); @@ -1360,9 +1360,9 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * #endif } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); @@ -1399,21 +1399,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, C_UN_S | FMT(op) | FT(src2) | FS(src1), FCSR_FCC); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; @@ -1425,7 +1425,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile src <<= 1; switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); @@ -1433,15 +1433,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, NEG_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, ABS_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_CONVD_FROMS: - FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_SINGLE_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS)); - op ^= SLJIT_SINGLE_OP; + case SLJIT_CONV_F64_FROM_F32: + FAIL_IF(push_inst(compiler, CVT_S_S | ((op & SLJIT_F32_OP) ? 1 : (1 << 21)) | FS(src) | FD(dst_r), MOVABLE_INS)); + op ^= SLJIT_F32_OP; break; } @@ -1450,12 +1450,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags = 0; + sljit_s32 dst_r, flags = 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1509,19 +1509,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile src2 = TMP_FREG2; switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; } @@ -1536,7 +1536,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1553,7 +1553,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1617,12 +1617,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins inst; - sljit_si flags = 0; - sljit_si delay_check = UNMOVABLE_INS; + sljit_s32 flags = 0; + sljit_s32 delay_check = UNMOVABLE_INS; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_jump(compiler, type)); @@ -1634,27 +1634,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile switch (type) { case SLJIT_EQUAL: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: BR_NZ(EQUAL_FLAG); break; case SLJIT_NOT_EQUAL: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: BR_Z(EQUAL_FLAG); break; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: BR_Z(ULESS_FLAG); break; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: BR_NZ(ULESS_FLAG); break; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: BR_Z(UGREATER_FLAG); break; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: BR_NZ(UGREATER_FLAG); break; case SLJIT_SIG_LESS: @@ -1677,10 +1677,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_MUL_NOT_OVERFLOW: BR_NZ(OVERFLOW_FLAG); break; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: BR_F(); break; - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: BR_T(); break; default: @@ -1733,12 +1733,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile src2 = 0; \ } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { struct sljit_jump *jump; - sljit_si flags; + sljit_s32 flags; sljit_ins inst; CHECK_ERROR_PTR(); @@ -1748,7 +1748,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler compiler->cache_arg = 0; compiler->cache_argw = 0; - flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; + flags = ((type & SLJIT_I32_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; if (src1 & SLJIT_MEM) { PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); src1 = TMP_REG1; @@ -1854,13 +1854,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #undef RESOLVE_IMM1 #undef RESOLVE_IMM2 -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { struct sljit_jump *jump; sljit_ins inst; - sljit_si if_true; + sljit_s32 if_true; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); @@ -1888,37 +1888,37 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile jump->flags |= IS_BIT16_COND; switch (type & 0xff) { - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: inst = C_UEQ_S; if_true = 1; break; - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: inst = C_UEQ_S; if_true = 0; break; - case SLJIT_D_LESS: + case SLJIT_LESS_F64: inst = C_ULT_S; if_true = 1; break; - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: inst = C_ULT_S; if_true = 0; break; - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: inst = C_ULE_S; if_true = 0; break; - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: inst = C_ULE_S; if_true = 1; break; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: inst = C_UN_S; if_true = 1; break; default: /* Make compilers happy. */ SLJIT_ASSERT_STOP(); - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: inst = C_UN_S; if_true = 0; break; @@ -1943,9 +1943,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile #undef FLOAT_DATA #undef FMT -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { - sljit_si src_r = TMP_REG2; + sljit_s32 src_r = TMP_REG2; struct sljit_jump *jump = NULL; CHECK_ERROR(); @@ -2001,17 +2001,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); + sljit_s32 sugg_dst_ar, dst_ar; + sljit_s32 flags = GET_ALL_FLAGS(op); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) # define mem_type WORD_DATA #else - sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; + sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; #endif CHECK_ERROR(); @@ -2023,7 +2023,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com op = GET_OPCODE(op); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32) mem_type = INT_DATA | SIGNED_DATA; #endif sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2); @@ -2045,14 +2045,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com break; case SLJIT_LESS: case SLJIT_GREATER_EQUAL: - case SLJIT_D_LESS: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_LESS_F64: + case SLJIT_GREATER_EQUAL_F64: dst_ar = ULESS_FLAG; break; case SLJIT_GREATER: case SLJIT_LESS_EQUAL: - case SLJIT_D_GREATER: - case SLJIT_D_LESS_EQUAL: + case SLJIT_GREATER_F64: + case SLJIT_LESS_EQUAL_F64: dst_ar = UGREATER_FLAG; break; case SLJIT_SIG_LESS: @@ -2073,13 +2073,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com dst_ar = sugg_dst_ar; type ^= 0x1; /* Flip type bit for the XORI below. */ break; - case SLJIT_D_EQUAL: - case SLJIT_D_NOT_EQUAL: + case SLJIT_EQUAL_F64: + case SLJIT_NOT_EQUAL_F64: dst_ar = EQUAL_FLAG; break; - case SLJIT_D_UNORDERED: - case SLJIT_D_ORDERED: + case SLJIT_UNORDERED_F64: + case SLJIT_ORDERED_F64: FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); @@ -2115,10 +2115,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre/sljit/sljitNativePPC_32.c b/pcre/sljit/sljitNativePPC_32.c index b14b75ceb51c5..0f23cf86ddc04 100644 --- a/pcre/sljit/sljitNativePPC_32.c +++ b/pcre/sljit/sljitNativePPC_32.c @@ -26,7 +26,7 @@ /* ppc 32-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); @@ -41,39 +41,39 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl #define INS_CLEAR_LEFT(dst, src, from) \ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_s32 src2) { switch (op) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: SLJIT_ASSERT(src1 == TMP_REG1); if (dst != src2) return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) + if (op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + else if ((flags & REG_DEST) && op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); else { SLJIT_ASSERT(dst == src2); } return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) + if (op == SLJIT_MOV_S16) return push_inst(compiler, EXTSH | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); } @@ -244,7 +244,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); diff --git a/pcre/sljit/sljitNativePPC_64.c b/pcre/sljit/sljitNativePPC_64.c index 182ac7b3da55b..8e3223f725198 100644 --- a/pcre/sljit/sljitNativePPC_64.c +++ b/pcre/sljit/sljitNativePPC_64.c @@ -41,7 +41,7 @@ #define PUSH_RLDICR(reg, shift) \ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { sljit_uw tmp; sljit_uw shift; @@ -145,8 +145,8 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl src1 = TMP_REG1; \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_s32 src2) { switch (op) { case SLJIT_MOV: @@ -156,11 +156,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); return SLJIT_SUCCESS; - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) + if (op == SLJIT_MOV_S32) return push_inst(compiler, EXTSW | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); } @@ -169,26 +169,26 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj } return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) + if (op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + else if ((flags & REG_DEST) && op == SLJIT_MOV_S8) return push_inst(compiler, EXTSB | S(src2) | A(dst)); else { SLJIT_ASSERT(dst == src2); } return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) + if (op == SLJIT_MOV_S16) return push_inst(compiler, EXTSH | S(src2) | A(dst)); return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); } @@ -389,7 +389,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); diff --git a/pcre/sljit/sljitNativePPC_common.c b/pcre/sljit/sljitNativePPC_common.c index b6a043f4e48f2..a3647327bfed6 100644 --- a/pcre/sljit/sljitNativePPC_common.c +++ b/pcre/sljit/sljitNativePPC_common.c @@ -24,14 +24,14 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "PowerPC" SLJIT_CPUINFO; } /* Length of an instruction word. Both for ppc-32 and ppc-64. */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; #if ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && (defined _AIX)) \ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -46,6 +46,8 @@ typedef sljit_ui sljit_ins; #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 #endif +#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) + static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) { #ifdef _AIX @@ -87,6 +89,8 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) #endif /* _AIX */ } +#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */ + #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) #define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4) @@ -101,7 +105,7 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) #define TMP_FREG1 (0) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { 0, 3, 4, 5, 6, 7, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 1, 8, 9, 10, 31, 12 }; @@ -236,7 +240,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct } #endif -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -245,7 +249,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { sljit_sw diff; sljit_uw target_addr; @@ -571,32 +575,32 @@ ALT_FORM6 0x200000 */ #define STACK_LOAD LD #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si i, tmp, offs; + sljit_s32 i, tmp, offs; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size); FAIL_IF(push_inst(compiler, MFLR | D(0))); - offs = -(sljit_si)(sizeof(sljit_sw)); + offs = -(sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | S(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; for (i = SLJIT_S0; i >= tmp; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); } for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { - offs -= (sljit_si)(sizeof(sljit_sw)); + offs -= (sljit_s32)(sizeof(sljit_sw)); FAIL_IF(push_inst(compiler, STACK_STORE | S(i) | A(SLJIT_SP) | IMM(offs))); } - SLJIT_ASSERT(offs == -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); + SLJIT_ASSERT(offs == -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1)); #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_SP) | IMM(2 * sizeof(sljit_sw)))); @@ -635,9 +639,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -648,9 +652,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp, offs; + sljit_s32 i, tmp, offs; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -670,18 +674,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_SP) | IMM(sizeof(sljit_sw)))); #endif - offs = -(sljit_si)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); + offs = -(sljit_s32)GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1); tmp = compiler->scratches; for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; for (i = tmp; i <= SLJIT_S0; i++) { FAIL_IF(push_inst(compiler, STACK_LOAD | D(i) | A(SLJIT_SP) | IMM(offs))); - offs += (sljit_si)(sizeof(sljit_sw)); + offs += (sljit_s32)(sizeof(sljit_sw)); } FAIL_IF(push_inst(compiler, STACK_LOAD | D(TMP_ZERO) | A(SLJIT_SP) | IMM(offs))); @@ -722,7 +726,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi (((inst) & ~(INT_ALIGNED | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) #endif -static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { +static const sljit_ins data_transfer_insts[64 + 8] = { /* -------- Unsigned -------- */ @@ -841,7 +845,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { #undef ARCH_32_64 /* Simple cases, (no caching is required). */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_ins inst; @@ -891,7 +895,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl /* See getput_arg below. Note: can_cache is called only for binary operators. Those operator always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { sljit_sw high_short, next_high_short; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -940,9 +944,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ #endif /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_r; + sljit_s32 tmp_r; sljit_ins inst; sljit_sw high_short, next_high_short; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -992,7 +996,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, #endif arg &= REG_MASK; - high_short = (sljit_si)(argw + ((argw & 0x8000) << 1)) & ~0xffff; + high_short = (sljit_s32)(argw + ((argw & 0x8000) << 1)) & ~0xffff; /* The getput_arg_fast should handle this otherwise. */ #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) SLJIT_ASSERT(high_short && high_short <= 0x7fffffffl && high_short >= -0x80000000l); @@ -1010,7 +1014,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, } else if (compiler->cache_arg != (SLJIT_MEM | arg) || high_short != compiler->cache_argw) { if ((next_arg & SLJIT_MEM) && !(next_arg & OFFS_REG_MASK)) { - next_high_short = (sljit_si)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; + next_high_short = (sljit_s32)(next_argw + ((next_argw & 0x8000) << 1)) & ~0xffff; if (high_short == next_high_short) { compiler->cache_arg = SLJIT_MEM | arg; compiler->cache_argw = high_short; @@ -1107,27 +1111,27 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, #endif } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 input_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); + sljit_s32 dst_r; + sljit_s32 src1_r; + sljit_s32 src2_r; + sljit_s32 sugg_src2_r = TMP_REG2; + sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); if (!(input_flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -1136,14 +1140,14 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i /* Destination check. */ if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; dst_r = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else { @@ -1178,7 +1182,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { @@ -1243,10 +1247,10 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si int_op = op & SLJIT_INT_OP; + sljit_s32 int_op = op & SLJIT_I32_OP; #endif CHECK_ERROR(); @@ -1257,33 +1261,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_BREAKPOINT: case SLJIT_NOP: return push_inst(compiler, NOP); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); - return push_inst(compiler, (op == SLJIT_LUMUL ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); + return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHDU : MULHD) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); #else FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1))); - return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); + return push_inst(compiler, (op == SLJIT_LMUL_UW ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1)); #endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); + FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) : (op == SLJIT_DIVMOD_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); #else - FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); + FAIL_IF(push_inst(compiler, (op == SLJIT_DIVMOD_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1))); FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1))); #endif return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1)); - case SLJIT_UDIVI: - case SLJIT_SDIVI: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); + return push_inst(compiler, (int_op ? (op == SLJIT_DIV_UW ? DIVWU : DIVW) : (op == SLJIT_DIV_UW ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #else - return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); + return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)); #endif } @@ -1293,12 +1297,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #define EMIT_MOV(type, type_flags, type_cast) \ emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + sljit_s32 op_flags = GET_ALL_FLAGS(op); CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1312,21 +1316,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (op_flags & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); - if (op_flags & SLJIT_INT_OP) { + if (op_flags & SLJIT_I32_OP) { if (op < SLJIT_NOT) { if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; + if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOV_U32; + if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOVU_U32; + if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOV_S32; + if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOVU_S32; #endif } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -1334,7 +1338,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler /* Most operations expect sign extended arguments. */ flags |= INT_DATA | SIGNED_DATA; if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; + srcw = (sljit_s32)srcw; } #endif } @@ -1343,58 +1347,58 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV: case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: #endif return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - case SLJIT_MOV_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui)); + case SLJIT_MOV_U32: + return EMIT_MOV(SLJIT_MOV_U32, INT_DATA, (sljit_u32)); - case SLJIT_MOV_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si)); + case SLJIT_MOV_S32: + return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, (sljit_s32)); #endif - case SLJIT_MOV_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub)); + case SLJIT_MOV_U8: + return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA, (sljit_u8)); - case SLJIT_MOV_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb)); + case SLJIT_MOV_S8: + return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, (sljit_s8)); - case SLJIT_MOV_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh)); + case SLJIT_MOV_U16: + return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA, (sljit_u16)); - case SLJIT_MOV_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh)); + case SLJIT_MOV_S16: + return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16)); case SLJIT_MOVU: case SLJIT_MOVU_P: #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: + case SLJIT_MOVU_U32: + case SLJIT_MOVU_S32: #endif return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - case SLJIT_MOVU_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui)); + case SLJIT_MOVU_U32: + return EMIT_MOV(SLJIT_MOV_U32, INT_DATA | WRITE_BACK, (sljit_u32)); - case SLJIT_MOVU_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si)); + case SLJIT_MOVU_S32: + return EMIT_MOV(SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s32)); #endif - case SLJIT_MOVU_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub)); + case SLJIT_MOVU_U8: + return EMIT_MOV(SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, (sljit_u8)); - case SLJIT_MOVU_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb)); + case SLJIT_MOVU_S8: + return EMIT_MOV(SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s8)); - case SLJIT_MOVU_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh)); + case SLJIT_MOVU_U16: + return EMIT_MOV(SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, (sljit_u16)); - case SLJIT_MOVU_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh)); + case SLJIT_MOVU_S16: + return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_s16)); case SLJIT_NOT: return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1404,7 +1408,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_CLZ: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_I32_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); #else return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); #endif @@ -1448,12 +1452,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ((src) & SLJIT_IMM) #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + sljit_s32 flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1467,13 +1471,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler src2 = TMP_ZERO; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) { + if (op & SLJIT_I32_OP) { /* Most operations expect sign extended arguments. */ flags |= INT_DATA | SIGNED_DATA; if (src1 & SLJIT_IMM) - src1w = (sljit_si)(src1w); + src1w = (sljit_s32)(src1w); if (src2 & SLJIT_IMM) - src2w = (sljit_si)(src2w); + src2w = (sljit_s32)(src2w); if (GET_FLAGS(op)) flags |= ALT_SIGN_EXT; } @@ -1549,7 +1553,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler } if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { if (!(op & SLJIT_SET_U)) { - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1560,7 +1564,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler } } if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ if (TEST_UL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1579,7 +1583,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } } - /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ + /* We know ALT_SIGN_EXT is set if it is an SLJIT_I32_OP on 64 bit systems. */ return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: @@ -1587,7 +1591,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler case SLJIT_MUL: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) flags |= ALT_FORM2; #endif if (!GET_FLAGS(op)) { @@ -1643,7 +1647,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler case SLJIT_SHL: case SLJIT_LSHR: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) flags |= ALT_FORM2; #endif if (src2 & SLJIT_IMM) { @@ -1656,20 +1660,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1681,7 +1685,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -1691,8 +1695,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 6)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) @@ -1709,9 +1713,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif /* SLJIT_CONFIG_PPC_64 */ -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { /* We can ignore the temporary data store on the stack from caching point of view. */ @@ -1721,12 +1725,12 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) op = GET_OPCODE(op); - FAIL_IF(push_inst(compiler, (op == SLJIT_CONVI_FROMD ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); + FAIL_IF(push_inst(compiler, (op == SLJIT_CONV_S32_FROM_F64 ? FCTIWZ : FCTIDZ) | FD(TMP_FREG1) | FB(src))); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - if (op == SLJIT_CONVW_FROMD) { + if (op == SLJIT_CONV_SW_FROM_F64) { if (FAST_IS_REG(dst)) { FAIL_IF(emit_op_mem2(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0)); return emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, 0, 0); @@ -1777,21 +1781,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; } - else if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) { + else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); else @@ -1810,14 +1814,14 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - if (op & SLJIT_SINGLE_OP) + if (op & SLJIT_F32_OP) return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); return SLJIT_SUCCESS; #else - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_si invert_sign = 1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 invert_sign = 1; if (src & SLJIT_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ 0x80000000)); @@ -1848,16 +1852,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - if (op & SLJIT_SINGLE_OP) + if (op & SLJIT_F32_OP) return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); return SLJIT_SUCCESS; #endif } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); @@ -1872,21 +1876,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, FCMPU | CRD(4) | FA(src1) | FB(src2)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; @@ -1896,14 +1900,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile } switch (GET_OPCODE(op)) { - case SLJIT_CONVD_FROMS: - op ^= SLJIT_SINGLE_OP; - if (op & SLJIT_SINGLE_OP) { + case SLJIT_CONV_F64_FROM_F32: + op ^= SLJIT_F32_OP; + if (op & SLJIT_F32_OP) { FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src))); break; } /* Fall through. */ - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src))); @@ -1911,10 +1915,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, FNEG | FD(dst_r) | FB(src))); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src))); break; } @@ -1924,12 +1928,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags = 0; + sljit_s32 dst_r, flags = 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1979,19 +1983,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile src2 = TMP_FREG2; switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); break; } @@ -2009,7 +2013,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -2027,7 +2031,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -2065,7 +2069,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -static sljit_ins get_bo_bi_flags(sljit_si type) +static sljit_ins get_bo_bi_flags(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: @@ -2075,19 +2079,19 @@ static sljit_ins get_bo_bi_flags(sljit_si type) return (4 << 21) | (2 << 16); case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return (12 << 21) | ((4 + 0) << 16); case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return (4 << 21) | ((4 + 0) << 16); case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return (12 << 21) | ((4 + 1) << 16); case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return (4 << 21) | ((4 + 1) << 16); case SLJIT_SIG_LESS: @@ -2110,16 +2114,16 @@ static sljit_ins get_bo_bi_flags(sljit_si type) case SLJIT_MUL_NOT_OVERFLOW: return (4 << 21) | (3 << 16); - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return (12 << 21) | ((4 + 2) << 16); - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return (4 << 21) | ((4 + 2) << 16); - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return (12 << 21) | ((4 + 3) << 16); - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return (4 << 21) | ((4 + 3) << 16); default: @@ -2128,7 +2132,7 @@ static sljit_ins get_bo_bi_flags(sljit_si type) } } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins bo_bi_flags; @@ -2160,10 +2164,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump = NULL; - sljit_si src_r; + sljit_s32 src_r; CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); @@ -2211,13 +2215,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil #define INVERT_BIT(dst) \ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si reg, input_flags; - sljit_si flags = GET_ALL_FLAGS(op); + sljit_s32 reg, input_flags; + sljit_s32 flags = GET_ALL_FLAGS(op); sljit_sw original_dstw = dstw; CHECK_ERROR(); @@ -2235,7 +2239,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { ADJUST_LOCAL_OFFSET(src, srcw); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; + input_flags = (flags & SLJIT_I32_OP) ? INT_DATA : WORD_DATA; #else input_flags = WORD_DATA; #endif @@ -2255,23 +2259,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com break; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: GET_CR_BIT(4 + 0, reg); break; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: GET_CR_BIT(4 + 0, reg); INVERT_BIT(reg); break; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: GET_CR_BIT(4 + 1, reg); break; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: GET_CR_BIT(4 + 1, reg); INVERT_BIT(reg); break; @@ -2305,20 +2309,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com INVERT_BIT(reg); break; - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: GET_CR_BIT(4 + 2, reg); break; - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: GET_CR_BIT(4 + 2, reg); INVERT_BIT(reg); break; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: GET_CR_BIT(4 + 3, reg); break; - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: GET_CR_BIT(4 + 3, reg); INVERT_BIT(reg); break; @@ -2333,7 +2337,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (op == SLJIT_MOV) input_flags = WORD_DATA; else { - op = SLJIT_MOV_UI; + op = SLJIT_MOV_U32; input_flags = INT_DATA; } #else @@ -2352,10 +2356,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value)); diff --git a/pcre/sljit/sljitNativeSPARC_32.c b/pcre/sljit/sljitNativeSPARC_32.c index 4a2e6293de579..7e589a17c2553 100644 --- a/pcre/sljit/sljitNativeSPARC_32.c +++ b/pcre/sljit/sljitNativeSPARC_32.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw imm) { if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, OR | D(dst) | S1(0) | IMM(imm), DR(dst)); @@ -35,26 +35,26 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl #define ARG2(flags, src2) ((flags & SRC2_IMM) ? IMM(src2) : S2(src2)) -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { SLJIT_COMPILE_ASSERT(ICC_IS_SET == SET_FLAGS, icc_is_set_and_set_flags_must_be_the_same); switch (op) { case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: case SLJIT_MOV_P: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if (dst != src2) return push_inst(compiler, OR | D(dst) | S1(0) | S2(src2), DR(dst)); return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_UB) + if (op == SLJIT_MOV_U8) return push_inst(compiler, AND | D(dst) | S1(src2) | IMM(0xff), DR(dst)); FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(24), DR(dst))); return push_inst(compiler, SRA | D(dst) | S1(dst) | IMM(24), DR(dst)); @@ -63,12 +63,12 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { FAIL_IF(push_inst(compiler, SLL | D(dst) | S1(src2) | IMM(16), DR(dst))); - return push_inst(compiler, (op == SLJIT_MOV_SH ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); + return push_inst(compiler, (op == SLJIT_MOV_S16 ? SRA : SRL) | D(dst) | S1(dst) | IMM(16), DR(dst)); } else if (dst != src2) SLJIT_ASSERT_STOP(); @@ -139,7 +139,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value) { FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst))); return push_inst(compiler, OR | D(dst) | S1(dst) | IMM_ARG | (init_value & 0x3ff), DR(dst)); diff --git a/pcre/sljit/sljitNativeSPARC_common.c b/pcre/sljit/sljitNativeSPARC_common.c index 327c4267be439..f3a33a1097edf 100644 --- a/pcre/sljit/sljitNativeSPARC_common.c +++ b/pcre/sljit/sljitNativeSPARC_common.c @@ -24,14 +24,16 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "SPARC" SLJIT_CPUINFO; } /* Length of an instruction word Both for sparc-32 and sparc-64 */ -typedef sljit_ui sljit_ins; +typedef sljit_u32 sljit_ins; + +#if (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) { @@ -82,6 +84,8 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) #endif } +#endif /* (defined SLJIT_CACHE_FLUSH_OWN_IMPL && SLJIT_CACHE_FLUSH_OWN_IMPL) */ + /* TMP_REG2 is not used by getput_arg */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) @@ -91,7 +95,7 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to) #define TMP_FREG1 (0) #define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15 }; @@ -181,7 +185,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) { sljit_ins *ptr; SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS @@ -340,7 +344,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_si)compiler->size); + SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size); jump = compiler->jumps; while (jump) { @@ -418,9 +422,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #include "sljitNativeSPARC_64.c" #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -442,9 +446,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -454,7 +458,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -478,7 +482,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #define ARCH_32_64(a, b) b #endif -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { +static const sljit_ins data_transfer_insts[16 + 4] = { /* u w s */ ARCH_32_64(OPC1(3) | OPC3(0x04) /* stw */, OPC1(3) | OPC3(0x0e) /* stx */), /* u w l */ ARCH_32_64(OPC1(3) | OPC3(0x00) /* lduw */, OPC1(3) | OPC3(0x0b) /* ldx */), /* u b s */ OPC1(3) | OPC3(0x05) /* stb */, @@ -506,7 +510,7 @@ static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { #undef ARCH_32_64 /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { SLJIT_ASSERT(arg & SLJIT_MEM); @@ -529,7 +533,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); @@ -549,9 +553,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si base, arg2, delay_slot; + sljit_s32 base, arg2, delay_slot; sljit_ins dest; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -613,7 +617,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base)); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -622,26 +626,26 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; + sljit_s32 dst_r = TMP_REG2; + sljit_s32 src1_r; sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + sljit_s32 sugg_src2_r = TMP_REG2; if (!(flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -649,13 +653,13 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw)) @@ -705,7 +709,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { @@ -716,7 +720,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } else { src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) dst_r = 0; } } @@ -758,7 +762,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -769,30 +773,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, TA, UNMOVABLE_INS); case SLJIT_NOP: return push_inst(compiler, NOP, UNMOVABLE_INS); - case SLJIT_LUMUL: - case SLJIT_LSMUL: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - FAIL_IF(push_inst(compiler, (op == SLJIT_LUMUL ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? UMUL : SMUL) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); return push_inst(compiler, RDY | D(SLJIT_R1), DR(SLJIT_R1)); #else #error "Implementation required" #endif - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - if ((op | 0x2) == SLJIT_UDIVI) + if ((op | 0x2) == SLJIT_DIV_UW) FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS)); else { FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1))); FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS)); } - if (op <= SLJIT_SDIVMOD) + if (op <= SLJIT_DIVMOD_SW) FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); - if (op >= SLJIT_UDIVI) + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0))); + if (op >= SLJIT_DIV_UW) return SLJIT_SUCCESS; FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1))); return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)); @@ -804,11 +808,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -821,45 +825,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_U32: + return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_S32: + return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_U32: + return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_S32: + return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_NOT: case SLJIT_CLZ: @@ -872,12 +876,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + sljit_s32 flags = GET_FLAGS(op) ? SET_FLAGS : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -914,20 +918,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg << 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -939,7 +943,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -949,13 +953,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_F32_OP) >> 7)) +#define SELECT_FOP(op, single, double) ((op & SLJIT_F32_OP) ? single : double) #define FLOAT_TMP_MEM_OFFSET (22 * sizeof(sljit_sw)) -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw)); @@ -978,16 +982,16 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; + sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; if (src & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; @@ -1008,9 +1012,9 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); @@ -1029,21 +1033,21 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); compiler->cache_arg = 0; compiler->cache_argw = 0; - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); + SLJIT_COMPILE_ASSERT((SLJIT_F32_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) - op ^= SLJIT_SINGLE_OP; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) + op ^= SLJIT_F32_OP; dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1; @@ -1055,30 +1059,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile src <<= 1; switch (GET_OPCODE(op)) { - case SLJIT_DMOV: + case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) { FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (!(op & SLJIT_SINGLE_OP)) + if (!(op & SLJIT_F32_OP)) FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); } else dst_r = src; } break; - case SLJIT_DNEG: + case SLJIT_NEG_F64: FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (dst_r != src && !(op & SLJIT_SINGLE_OP)) + if (dst_r != src && !(op & SLJIT_F32_OP)) FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); break; - case SLJIT_DABS: + case SLJIT_ABS_F64: FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS)); - if (dst_r != src && !(op & SLJIT_SINGLE_OP)) + if (dst_r != src && !(op & SLJIT_F32_OP)) FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS)); break; - case SLJIT_CONVD_FROMS: + case SLJIT_CONV_F64_FROM_F32: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS)); - op ^= SLJIT_SINGLE_OP; + op ^= SLJIT_F32_OP; break; } @@ -1087,12 +1091,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r, flags = 0; + sljit_s32 dst_r, flags = 0; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -1146,19 +1150,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile src2 = TMP_FREG2; switch (GET_OPCODE(op)) { - case SLJIT_DADD: + case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; - case SLJIT_DSUB: + case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; - case SLJIT_DMUL: + case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; - case SLJIT_DDIV: + case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS)); break; } @@ -1176,7 +1180,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1193,7 +1197,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1231,33 +1235,33 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -static sljit_ins get_cc(sljit_si type) +static sljit_ins get_cc(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: case SLJIT_MUL_NOT_OVERFLOW: - case SLJIT_D_NOT_EQUAL: /* Unordered. */ + case SLJIT_NOT_EQUAL_F64: /* Unordered. */ return DA(0x1); case SLJIT_NOT_EQUAL: case SLJIT_MUL_OVERFLOW: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return DA(0x9); case SLJIT_LESS: - case SLJIT_D_GREATER: /* Unordered. */ + case SLJIT_GREATER_F64: /* Unordered. */ return DA(0x5); case SLJIT_GREATER_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return DA(0xd); case SLJIT_GREATER: - case SLJIT_D_GREATER_EQUAL: /* Unordered. */ + case SLJIT_GREATER_EQUAL_F64: /* Unordered. */ return DA(0xc); case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return DA(0x4); case SLJIT_SIG_LESS: @@ -1273,11 +1277,11 @@ static sljit_ins get_cc(sljit_si type) return DA(0x2); case SLJIT_OVERFLOW: - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return DA(0x7); case SLJIT_NOT_OVERFLOW: - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return DA(0xf); default: @@ -1286,7 +1290,7 @@ static sljit_ins get_cc(sljit_si type) } } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -1298,7 +1302,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; - if (type < SLJIT_D_EQUAL) { + if (type < SLJIT_EQUAL_F64) { jump->flags |= IS_COND; if (((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS) && !(compiler->delay_slot & ICC_IS_SET)) jump->flags |= IS_MOVABLE; @@ -1332,10 +1336,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump = NULL; - sljit_si src_r; + sljit_s32 src_r; CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); @@ -1367,12 +1371,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return push_inst(compiler, NOP, UNMOVABLE_INS); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_si reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); + sljit_s32 reg, flags = (GET_FLAGS(op) ? SET_FLAGS : 0); CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); @@ -1395,7 +1399,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com } type &= 0xff; - if (type < SLJIT_D_EQUAL) + if (type < SLJIT_EQUAL_F64) FAIL_IF(push_inst(compiler, BICC | get_cc(type) | 3, UNMOVABLE_INS)); else FAIL_IF(push_inst(compiler, FBFCC | get_cc(type) | 3, UNMOVABLE_INS)); @@ -1412,9 +1416,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { - sljit_si reg; + sljit_s32 reg; struct sljit_const *const_; CHECK_ERROR_PTR(); diff --git a/pcre/sljit/sljitNativeTILEGX_64.c b/pcre/sljit/sljitNativeTILEGX_64.c index 4d40392fa82f0..462a8b9cd953f 100644 --- a/pcre/sljit/sljitNativeTILEGX_64.c +++ b/pcre/sljit/sljitNativeTILEGX_64.c @@ -49,7 +49,7 @@ #define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5) #define PIC_ADDR_REG TMP_REG2 -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7 }; @@ -106,7 +106,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = { */ #define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char *sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void) { return "TileGX" SLJIT_CPUINFO; } @@ -307,7 +307,7 @@ struct jit_instr { #define JOFF_X1(x) create_JumpOff_X1(x) #define BOFF_X1(x) create_BrOff_X1(x) -static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { +static const tilegx_mnemonic data_transfer_insts[16] = { /* u w s */ TILEGX_OPC_ST /* st */, /* u w l */ TILEGX_OPC_LD /* ld */, /* u b s */ TILEGX_OPC_ST1 /* st1 */, @@ -327,7 +327,7 @@ static SLJIT_CONST tilegx_mnemonic data_transfer_insts[16] = { }; #ifdef TILEGX_JIT_DEBUG -static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) +static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line) { sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -338,7 +338,7 @@ static sljit_si push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, return SLJIT_SUCCESS; } -static sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -349,7 +349,7 @@ static sljit_si push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins #define push_inst(a, b) push_inst_debug(a, b, __LINE__) #else -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -557,7 +557,7 @@ const struct Format* compute_format() return match; } -sljit_si assign_pipes() +sljit_s32 assign_pipes() { unsigned long output_registers = 0; unsigned int i = 0; @@ -621,7 +621,7 @@ tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst) return bits; } -static sljit_si update_buffer(struct sljit_compiler *compiler) +static sljit_s32 update_buffer(struct sljit_compiler *compiler) { int i; int orig_index = inst_buf_index; @@ -733,7 +733,7 @@ static sljit_si update_buffer(struct sljit_compiler *compiler) SLJIT_ASSERT_STOP(); } -static sljit_si flush_buffer(struct sljit_compiler *compiler) +static sljit_s32 flush_buffer(struct sljit_compiler *compiler) { while (inst_buf_index != 0) { FAIL_IF(update_buffer(compiler)); @@ -741,7 +741,7 @@ static sljit_si flush_buffer(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) +static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -761,7 +761,7 @@ static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) +static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -822,7 +822,7 @@ static sljit_si push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) +static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -867,7 +867,7 @@ static sljit_si push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) +static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -883,7 +883,7 @@ static sljit_si push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic o return SLJIT_SUCCESS; } -static sljit_si push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) +static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line) { if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE) FAIL_IF(update_buffer(compiler)); @@ -1117,7 +1117,7 @@ SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compi return code; } -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN) @@ -1140,7 +1140,7 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, return SHL16INSLI(dst_ar, dst_ar, imm); } -static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush) { /* Should *not* be optimized as load_immediate, as pcre relocation mechanism will match this fixed 4-instruction pattern. */ @@ -1155,7 +1155,7 @@ static sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst_ar, slj return SHL16INSLI(dst_ar, dst_ar, imm); } -static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm, int flush) +static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush) { /* Should *not* be optimized as load_immediate, as pcre relocation mechanism will match this fixed 4-instruction pattern. */ @@ -1172,12 +1172,12 @@ static sljit_si emit_const_64(struct sljit_compiler *compiler, sljit_si dst_ar, return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { sljit_ins base; - sljit_si i, tmp; + sljit_s32 i, tmp; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1222,9 +1222,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -1236,12 +1236,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si local_size; + sljit_s32 local_size; sljit_ins base; - sljit_si i, tmp; - sljit_si saveds; + sljit_s32 i, tmp; + sljit_s32 saveds; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -1285,7 +1285,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* reg_ar is an absoulute register! */ /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1311,7 +1311,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); @@ -1337,9 +1337,9 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw) { - sljit_si tmp_ar, base; + sljit_s32 tmp_ar, base; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -1530,7 +1530,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw) { if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; @@ -1540,14 +1540,14 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w) { if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) return compiler->error; return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -1564,7 +1564,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -1582,9 +1582,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * return JR(RA); } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { - sljit_si overflow_ra = 0; + sljit_s32 overflow_ra = 0; switch (GET_OPCODE(op)) { case SLJIT_MOV: @@ -1594,11 +1594,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return ADD(reg_map[dst], reg_map[src2], ZERO); return SLJIT_SUCCESS; - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) + if (op == SLJIT_MOV_S32) return BFEXTS(reg_map[dst], reg_map[src2], 0, 31); return BFEXTU(reg_map[dst], reg_map[src2], 0, 31); @@ -1609,11 +1609,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: + case SLJIT_MOV_U8: + case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) + if (op == SLJIT_MOV_S8) return BFEXTS(reg_map[dst], reg_map[src2], 0, 7); return BFEXTU(reg_map[dst], reg_map[src2], 0, 7); @@ -1624,11 +1624,11 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: + case SLJIT_MOV_U16: + case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) + if (op == SLJIT_MOV_S16) return BFEXTS(reg_map[dst], reg_map[src2], 0, 15); return BFEXTU(reg_map[dst], reg_map[src2], 0, 15); @@ -1956,16 +1956,16 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { /* arg1 goes to TMP_REG1 or src reg. arg2 goes to TMP_REG2, imm or src reg. TMP_REG3 can be used for caching. result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; + sljit_s32 dst_r = TMP_REG2; + sljit_s32 src1_r; sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + sljit_s32 sugg_src2_r = TMP_REG2; if (!(flags & ALT_KEEP_CACHE)) { compiler->cache_arg = 0; @@ -1973,14 +1973,14 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; } else if (FAST_IS_REG(dst)) { dst_r = dst; flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) sugg_src2_r = dst_r; } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw)) flags |= SLOW_DEST; @@ -2033,7 +2033,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f if (FAST_IS_REG(src2)) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { if (!(flags & SRC2_IMM)) { @@ -2042,7 +2042,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f src2_r = sugg_src2_r; } else { src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) + if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM)) dst_r = 0; } } @@ -2082,11 +2082,11 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw, sljit_s32 type) { - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); - sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; + sljit_s32 sugg_dst_ar, dst_ar; + sljit_s32 flags = GET_ALL_FLAGS(op); + sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA; CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type)); @@ -2096,7 +2096,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; op = GET_OPCODE(op); - if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI) + if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32) mem_type = INT_DATA | SIGNED_DATA; sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2]; @@ -2168,7 +2168,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) { +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -2180,17 +2180,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_BREAKPOINT: return PI(BPT); - case SLJIT_LUMUL: - case SLJIT_LSMUL: - case SLJIT_UDIVI: - case SLJIT_SDIVI: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: SLJIT_ASSERT_STOP(); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -2202,45 +2204,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_U32: + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOV_S32: + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + case SLJIT_MOV_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw); - case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + case SLJIT_MOV_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw); - case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + case SLJIT_MOV_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw); - case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + case SLJIT_MOV_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_U32: + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + case SLJIT_MOVU_S32: + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub) srcw : srcw); + case SLJIT_MOVU_U8: + return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw); - case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb) srcw : srcw); + case SLJIT_MOVU_S8: + return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw); - case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh) srcw : srcw); + case SLJIT_MOVU_U16: + return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw); - case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh) srcw : srcw); + case SLJIT_MOVU_S16: + return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); @@ -2249,13 +2251,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); case SLJIT_CLZ: - return emit_op(compiler, op, (op & SLJIT_INT_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2285,7 +2287,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler case SLJIT_ASHR: if (src2 & SLJIT_IMM) src2w &= 0x3f; - if (op & SLJIT_INT_OP) + if (op & SLJIT_I32_OP) src2w &= 0x1f; return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w); @@ -2312,9 +2314,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_comp return label; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { - sljit_si src_r = TMP_REG2; + sljit_s32 src_r = TMP_REG2; struct sljit_jump *jump = NULL; flush_buffer(compiler); @@ -2401,11 +2403,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil inst = BNEZ_X1 | SRCA_X1(src); \ flags = IS_COND; -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; sljit_ins inst; - sljit_si flags = 0; + sljit_s32 flags = 0; flush_buffer(compiler); @@ -2485,25 +2487,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { return 0; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; - sljit_si reg; + sljit_s32 reg; flush_buffer(compiler); @@ -2545,14 +2547,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta SLJIT_CACHE_FLUSH(inst, inst + 4); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); diff --git a/pcre/sljit/sljitNativeX86_32.c b/pcre/sljit/sljitNativeX86_32.c index d7129c8e26dfc..cd3c656c66443 100644 --- a/pcre/sljit/sljitNativeX86_32.c +++ b/pcre/sljit/sljitNativeX86_32.c @@ -26,11 +26,11 @@ /* x86 32-bit arch dependent functions. */ -static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm) +static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, sljit_sw imm) { - sljit_ub *inst; + sljit_u8 *inst; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); FAIL_IF(!inst); INC_SIZE(1 + sizeof(sljit_sw)); *inst++ = opcode; @@ -38,7 +38,7 @@ static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sl return SLJIT_SUCCESS; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type) { if (type == SLJIT_JUMP) { *code_ptr++ = JMP_i32; @@ -63,12 +63,12 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si size; - sljit_ub *inst; + sljit_s32 size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -83,7 +83,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #else size += (args > 0 ? (2 + args * 3) : 0); #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -143,7 +143,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (options & SLJIT_DOUBLE_ALIGNMENT) { local_size = SLJIT_LOCALS_OFFSET + ((local_size + 7) & ~7); - inst = (sljit_ub*)ensure_buf(compiler, 1 + 17); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 17); FAIL_IF(!inst); INC_SIZE(17); @@ -183,9 +183,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -205,10 +205,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si size; - sljit_ub *inst; + sljit_s32 size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -223,7 +223,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #if !defined(__APPLE__) if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); FAIL_IF(!inst); INC_SIZE(3); @@ -242,7 +242,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi if (compiler->args > 0) size += 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -271,16 +271,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* --------------------------------------------------------------------- */ /* Size contains the flags as well. */ -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, +static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size, /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, + sljit_s32 a, sljit_sw imma, /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) + sljit_s32 b, sljit_sw immb) { - sljit_ub *inst; - sljit_ub *buf_ptr; - sljit_si flags = size & ~0xf; - sljit_si inst_size; + sljit_u8 *inst; + sljit_u8 *buf_ptr; + sljit_s32 flags = size & ~0xf; + sljit_s32 inst_size; /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); @@ -310,7 +310,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (immb != 0 && !(b & OFFS_REG_MASK)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_s8); else inst_size += sizeof(sljit_sw); } @@ -347,7 +347,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!inst); /* Encoding the byte. */ @@ -438,12 +438,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si /* Call / return instructions */ /* --------------------------------------------------------------------- */ -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); FAIL_IF(!inst); INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); @@ -452,7 +452,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj *inst++ = MOV_r_rm; *inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0]; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); FAIL_IF(!inst); INC_SIZE(4 * (type - SLJIT_CALL0)); @@ -476,9 +476,9 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -492,7 +492,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (FAST_IS_REG(dst)) { /* Unused dest is possible here. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); @@ -507,9 +507,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -518,7 +518,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * CHECK_EXTRA_REGS(src, srcw, (void)0); if (FAST_IS_REG(src)) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); INC_SIZE(1 + 1); @@ -530,13 +530,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * *inst++ = GROUP_FF; *inst |= PUSH_rm; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); } else { /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1); FAIL_IF(!inst); INC_SIZE(5 + 1); diff --git a/pcre/sljit/sljitNativeX86_64.c b/pcre/sljit/sljitNativeX86_64.c index 1790d8a4d0a60..6ea27e5513114 100644 --- a/pcre/sljit/sljitNativeX86_64.c +++ b/pcre/sljit/sljitNativeX86_64.c @@ -26,11 +26,11 @@ /* x86 64-bit arch dependent functions. */ -static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw imm) { - sljit_ub *inst; + sljit_u8 *inst; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); FAIL_IF(!inst); INC_SIZE(2 + sizeof(sljit_sw)); *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); @@ -39,7 +39,7 @@ static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, s return SLJIT_SUCCESS; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type) { if (type < SLJIT_JUMP) { /* Invert type. */ @@ -65,9 +65,9 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ return code_ptr; } -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type) +static sljit_u8* generate_fixed_jump(sljit_u8 *code_ptr, sljit_sw addr, sljit_s32 type) { - sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); + sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_s32)); if (delta <= HALFWORD_MAX && delta >= HALFWORD_MIN) { *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; @@ -87,12 +87,12 @@ static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si i, tmp, size, saved_register_size; - sljit_ub *inst; + sljit_s32 i, tmp, size, saved_register_size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -106,7 +106,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG; for (i = SLJIT_S0; i >= tmp; i--) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -116,7 +116,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -126,7 +126,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (args > 0) { size = args * 3; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -172,9 +172,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #ifdef _WIN64 if (local_size > 1024) { /* Allocate stack for the callback, which grows the stack. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si))); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_s32))); FAIL_IF(!inst); - INC_SIZE(4 + (3 + sizeof(sljit_si))); + INC_SIZE(4 + (3 + sizeof(sljit_s32))); *inst++ = REX_W; *inst++ = GROUP_BINARY_83; *inst++ = MOD_REG | SUB | 4; @@ -193,7 +193,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil *inst++ = REX_W; *inst++ = MOV_rm_i32; *inst++ = MOD_REG | reg_lmap[SLJIT_R0]; - *(sljit_si*)inst = local_size; + *(sljit_s32*)inst = local_size; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) compiler->skip_checks = 1; @@ -204,7 +204,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil SLJIT_ASSERT(local_size > 0); if (local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); *inst++ = REX_W; @@ -213,35 +213,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil *inst++ = local_size; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 7); FAIL_IF(!inst); INC_SIZE(7); *inst++ = REX_W; *inst++ = GROUP_BINARY_81; *inst++ = MOD_REG | SUB | 4; - *(sljit_si*)inst = local_size; - inst += sizeof(sljit_si); + *(sljit_s32*)inst = local_size; + inst += sizeof(sljit_s32); } #ifdef _WIN64 /* Save xmm6 register: movaps [rsp + 0x20], xmm6 */ if (fscratches >= 6 || fsaveds >= 1) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247429; + *(sljit_s32*)inst = 0x20247429; } #endif return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler, - sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds, - sljit_si fscratches, sljit_si fsaveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, + sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds, + sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) { - sljit_si saved_register_size; + sljit_s32 saved_register_size; CHECK_ERROR(); CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size)); @@ -253,10 +253,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compi return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { - sljit_si i, tmp, size; - sljit_ub *inst; + sljit_s32 i, tmp, size; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_return(compiler, op, src, srcw)); @@ -267,17 +267,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #ifdef _WIN64 /* Restore xmm6 register: movaps xmm6, [rsp + 0x20] */ if (compiler->fscratches >= 6 || compiler->fsaveds >= 1) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247428; + *(sljit_s32*)inst = 0x20247428; } #endif SLJIT_ASSERT(compiler->local_size > 0); if (compiler->local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); *inst++ = REX_W; @@ -286,19 +286,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi *inst = compiler->local_size; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 7); FAIL_IF(!inst); INC_SIZE(7); *inst++ = REX_W; *inst++ = GROUP_BINARY_81; *inst++ = MOD_REG | ADD | 4; - *(sljit_si*)inst = compiler->local_size; + *(sljit_s32*)inst = compiler->local_size; } tmp = compiler->scratches; for (i = SLJIT_FIRST_SAVED_REG; i <= tmp; i++) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -309,7 +309,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG; for (i = tmp; i <= SLJIT_S0; i++) { size = reg_map[i] >= 8 ? 2 : 1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); if (reg_map[i] >= 8) @@ -317,7 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi POP_REG(reg_lmap[i]); } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); RET(); @@ -328,32 +328,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Operators */ /* --------------------------------------------------------------------- */ -static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm) +static sljit_s32 emit_do_imm32(struct sljit_compiler *compiler, sljit_u8 rex, sljit_u8 opcode, sljit_sw imm) { - sljit_ub *inst; - sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si); + sljit_u8 *inst; + sljit_s32 length = 1 + (rex ? 1 : 0) + sizeof(sljit_s32); - inst = (sljit_ub*)ensure_buf(compiler, 1 + length); + inst = (sljit_u8*)ensure_buf(compiler, 1 + length); FAIL_IF(!inst); INC_SIZE(length); if (rex) *inst++ = rex; *inst++ = opcode; - *(sljit_si*)inst = imm; + *(sljit_s32*)inst = imm; return SLJIT_SUCCESS; } -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, +static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32 size, /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, + sljit_s32 a, sljit_sw imma, /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) + sljit_s32 b, sljit_sw immb) { - sljit_ub *inst; - sljit_ub *buf_ptr; - sljit_ub rex = 0; - sljit_si flags = size & ~0xf; - sljit_si inst_size; + sljit_u8 *inst; + sljit_u8 *buf_ptr; + sljit_u8 rex = 0; + sljit_s32 flags = size & ~0xf; + sljit_s32 inst_size; /* The immediate operand must be 32 bit. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); @@ -400,7 +400,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } if ((b & REG_MASK) == SLJIT_UNUSED) - inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */ + inst_size += 1 + sizeof(sljit_s32); /* SIB byte required to avoid RIP based addressing. */ else { if (reg_map[b & REG_MASK] >= 8) rex |= REX_B; @@ -408,12 +408,12 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb != 0 && (!(b & OFFS_REG_MASK) || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP))) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_s8); else - inst_size += sizeof(sljit_si); + inst_size += sizeof(sljit_s32); } else if (reg_lmap[b & REG_MASK] == 5) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_s8); if ((b & OFFS_REG_MASK) != SLJIT_UNUSED) { inst_size += 1; /* SIB byte. */ @@ -444,7 +444,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) inst_size += sizeof(short); else - inst_size += sizeof(sljit_si); + inst_size += sizeof(sljit_s32); } else { SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); @@ -456,7 +456,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (rex) inst_size++; - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!inst); /* Encoding the byte. */ @@ -516,8 +516,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); + *(sljit_s32*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_s32); } } } @@ -533,8 +533,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else { *buf_ptr++ |= 0x04; *buf_ptr++ = 0x25; - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); + *(sljit_s32*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_s32); } if (a & SLJIT_IMM) { @@ -543,7 +543,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) *(short*)buf_ptr = imma; else if (!(flags & EX86_SHIFT_INS)) - *(sljit_si*)buf_ptr = imma; + *(sljit_s32*)buf_ptr = imma; } return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); @@ -553,14 +553,14 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si /* Call / return instructions */ /* --------------------------------------------------------------------- */ -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type) { - sljit_ub *inst; + sljit_u8 *inst; #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!inst); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { @@ -574,7 +574,7 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8, args_registers); - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); FAIL_IF(!inst); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { @@ -589,9 +589,9 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); @@ -603,14 +603,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (FAST_IS_REG(dst)) { if (reg_map[dst] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); POP_REG(reg_lmap[dst]); return SLJIT_SUCCESS; } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); *inst++ = REX_B; @@ -626,9 +626,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_fast_return(compiler, src, srcw)); @@ -641,14 +641,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * if (FAST_IS_REG(src)) { if (reg_map[src] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1); FAIL_IF(!inst); INC_SIZE(1 + 1); PUSH_REG(reg_lmap[src]); } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1); FAIL_IF(!inst); INC_SIZE(2 + 1); @@ -664,20 +664,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * *inst++ = GROUP_FF; *inst |= PUSH_rm; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); } else { SLJIT_ASSERT(IS_HALFWORD(srcw)); /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1); FAIL_IF(!inst); INC_SIZE(5 + 1); *inst++ = PUSH_i32; - *(sljit_si*)inst = srcw; - inst += sizeof(sljit_si); + *(sljit_s32*)inst = srcw; + inst += sizeof(sljit_s32); } RET(); @@ -689,12 +689,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Extend input */ /* --------------------------------------------------------------------- */ -static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; compiler->mode32 = 0; @@ -704,7 +704,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, if (src & SLJIT_IMM) { if (FAST_IS_REG(dst)) { if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_i32; return SLJIT_SUCCESS; @@ -712,7 +712,7 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return emit_load_imm64(compiler, dst, srcw); } compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm_i32; compiler->mode32 = 0; diff --git a/pcre/sljit/sljitNativeX86_common.c b/pcre/sljit/sljitNativeX86_common.c index 416c15afafa6a..54c3ac7814b91 100644 --- a/pcre/sljit/sljitNativeX86_common.c +++ b/pcre/sljit/sljitNativeX86_common.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "x86" SLJIT_CPUINFO; } @@ -66,7 +66,7 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) /* Last register + 1. */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { 0, 0, 2, 1, 0, 0, 0, 0, 7, 6, 3, 4, 5 }; @@ -89,20 +89,20 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { therefore r12 is better for SAVED_EREG than SAVED_REG. */ #ifndef _WIN64 /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 6, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 7, 9 }; /* low-map. reg_map & 0x7. */ -static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 6, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 7, 1 }; #else /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ -static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 2, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 10, 8, 9 }; /* low-map. reg_map & 0x7. */ -static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { +static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 2, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 2, 0, 1 }; #endif @@ -269,9 +269,9 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 5] = { built-in CPU features. Therefore they can be overwritten by different threads if they detect the CPU features in the same time. */ #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) -static sljit_si cpu_has_sse2 = -1; +static sljit_s32 cpu_has_sse2 = -1; #endif -static sljit_si cpu_has_cmov = -1; +static sljit_s32 cpu_has_cmov = -1; #ifdef _WIN32_WCE #include @@ -281,13 +281,13 @@ static sljit_si cpu_has_cmov = -1; static void get_cpu_features(void) { - sljit_ui features; + sljit_u32 features; #if defined(_MSC_VER) && _MSC_VER >= 1400 int CPUInfo[4]; __cpuid(CPUInfo, 1); - features = (sljit_ui)CPUInfo[3]; + features = (sljit_u32)CPUInfo[3]; #elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) @@ -330,31 +330,31 @@ static void get_cpu_features(void) cpu_has_cmov = (features >> 15) & 0x1; } -static sljit_ub get_jump_code(sljit_si type) +static sljit_u8 get_jump_code(sljit_s32 type) { switch (type) { case SLJIT_EQUAL: - case SLJIT_D_EQUAL: + case SLJIT_EQUAL_F64: return 0x84 /* je */; case SLJIT_NOT_EQUAL: - case SLJIT_D_NOT_EQUAL: + case SLJIT_NOT_EQUAL_F64: return 0x85 /* jne */; case SLJIT_LESS: - case SLJIT_D_LESS: + case SLJIT_LESS_F64: return 0x82 /* jc */; case SLJIT_GREATER_EQUAL: - case SLJIT_D_GREATER_EQUAL: + case SLJIT_GREATER_EQUAL_F64: return 0x83 /* jae */; case SLJIT_GREATER: - case SLJIT_D_GREATER: + case SLJIT_GREATER_F64: return 0x87 /* jnbe */; case SLJIT_LESS_EQUAL: - case SLJIT_D_LESS_EQUAL: + case SLJIT_LESS_EQUAL_F64: return 0x86 /* jbe */; case SLJIT_SIG_LESS: @@ -377,24 +377,24 @@ static sljit_ub get_jump_code(sljit_si type) case SLJIT_MUL_NOT_OVERFLOW: return 0x81 /* jno */; - case SLJIT_D_UNORDERED: + case SLJIT_UNORDERED_F64: return 0x8a /* jp */; - case SLJIT_D_ORDERED: + case SLJIT_ORDERED_F64: return 0x8b /* jpo */; } return 0; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type); +static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type); +static sljit_u8* generate_fixed_jump(sljit_u8 *code_ptr, sljit_sw addr, sljit_s32 type); #endif -static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, sljit_si type) +static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type) { - sljit_si short_jump; + sljit_s32 short_jump; sljit_uw label_addr; if (jump->flags & JUMP_LABEL) @@ -432,13 +432,13 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code if (short_jump) { jump->flags |= PATCH_MB; - code_ptr += sizeof(sljit_sb); + code_ptr += sizeof(sljit_s8); } else { jump->flags |= PATCH_MW; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) code_ptr += sizeof(sljit_sw); #else - code_ptr += sizeof(sljit_si); + code_ptr += sizeof(sljit_s32); #endif } @@ -448,11 +448,11 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; - sljit_ub *code; - sljit_ub *code_ptr; - sljit_ub *buf_ptr; - sljit_ub *buf_end; - sljit_ub len; + sljit_u8 *code; + sljit_u8 *code_ptr; + sljit_u8 *buf_ptr; + sljit_u8 *buf_end; + sljit_u8 len; struct sljit_label *label; struct sljit_jump *jump; @@ -463,7 +463,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); /* Second code generation pass. */ - code = (sljit_ub*)SLJIT_MALLOC_EXEC(compiler->size); + code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; @@ -526,23 +526,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { if (jump->flags & PATCH_MB) { - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) <= 127); - *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))); + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))) <= 127); + *(sljit_u8*)jump->addr = (sljit_u8)(jump->u.label->addr - (jump->addr + sizeof(sljit_s8))); } else if (jump->flags & PATCH_MW) { if (jump->flags & JUMP_LABEL) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); + SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))) <= HALFWORD_MAX); + *(sljit_s32*)jump->addr = (sljit_s32)(jump->u.label->addr - (jump->addr + sizeof(sljit_s32))); #endif } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= HALFWORD_MAX); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); + SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_s32))) >= HALFWORD_MIN && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_s32))) <= HALFWORD_MAX); + *(sljit_s32*)jump->addr = (sljit_s32)(jump->u.target - (jump->addr + sizeof(sljit_s32))); #endif } } @@ -565,32 +565,32 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* Operators */ /* --------------------------------------------------------------------- */ -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +static sljit_s32 emit_mov(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw); -static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) +static SLJIT_INLINE sljit_s32 emit_save_flags(struct sljit_compiler *compiler) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 6); FAIL_IF(!inst); INC_SIZE(6); *inst++ = REX_W; @@ -598,23 +598,23 @@ static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */ *inst++ = 0x64; *inst++ = 0x24; - *inst++ = (sljit_ub)sizeof(sljit_sw); + *inst++ = (sljit_u8)sizeof(sljit_sw); *inst++ = PUSHF; compiler->flags_saved = 1; return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, sljit_si keep_flags) +static SLJIT_INLINE sljit_s32 emit_restore_flags(struct sljit_compiler *compiler, sljit_s32 keep_flags) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); *inst++ = POPF; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 6); FAIL_IF(!inst); INC_SIZE(6); *inst++ = POPF; @@ -623,7 +623,7 @@ static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */ *inst++ = 0x64; *inst++ = 0x24; - *inst++ = (sljit_ub)-(sljit_sb)sizeof(sljit_sw); + *inst++ = (sljit_u8)(-(sljit_s8)sizeof(sljit_sw)); compiler->flags_saved = keep_flags; return SLJIT_SUCCESS; } @@ -640,7 +640,7 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) CPU cycles if the stack is large enough. However, you don't know it in advance, so it must always be called. I think this is a bad design in general even if it has some reasons. */ - *(volatile sljit_si*)alloca(local_size) = 0; + *(volatile sljit_s32*)alloca(local_size) = 0; } #endif @@ -651,11 +651,11 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) #include "sljitNativeX86_64.c" #endif -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { /* No destination, doesn't need to setup flags. */ @@ -719,11 +719,11 @@ static sljit_si emit_mov(struct sljit_compiler *compiler, #define EMIT_MOV(compiler, dst, dstw, src, srcw) \ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { - sljit_ub *inst; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si size; + sljit_s32 size; #endif CHECK_ERROR(); @@ -731,23 +731,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = INT3; break; case SLJIT_NOP: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = NOP; break; - case SLJIT_LUMUL: - case SLJIT_LSMUL: - case SLJIT_UDIVMOD: - case SLJIT_SDIVMOD: - case SLJIT_UDIVI: - case SLJIT_SDIVI: + case SLJIT_LMUL_UW: + case SLJIT_LMUL_SW: + case SLJIT_DIVMOD_UW: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_UW: + case SLJIT_DIV_SW: compiler->flags_saved = 0; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #ifdef _WIN64 @@ -763,12 +763,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler && reg_map[TMP_REG1] == 2, invalid_register_assignment_for_div_mul); #endif - compiler->mode32 = op & SLJIT_INT_OP; + compiler->mode32 = op & SLJIT_I32_OP; #endif - SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments); + SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments); op = GET_OPCODE(op); - if ((op | 0x2) == SLJIT_UDIVI) { + if ((op | 0x2) == SLJIT_DIV_UW) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0); @@ -779,24 +779,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler *inst = XOR_r_rm; } - if ((op | 0x2) == SLJIT_SDIVI) { + if ((op | 0x2) == SLJIT_DIV_SW) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0); #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = CDQ; #else if (compiler->mode32) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); *inst = CDQ; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); *inst++ = REX_W; @@ -806,27 +806,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); + *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); #else #ifdef _WIN64 - size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2; + size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2; #else size = (!compiler->mode32) ? 3 : 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); #ifdef _WIN64 if (!compiler->mode32) - *inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0); - else if (op >= SLJIT_UDIVMOD) + *inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0); + else if (op >= SLJIT_DIVMOD_UW) *inst++ = REX_B; *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); + *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); #else if (!compiler->mode32) *inst++ = REX_W; @@ -835,26 +835,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #endif #endif switch (op) { - case SLJIT_LUMUL: + case SLJIT_LMUL_UW: *inst |= MUL; break; - case SLJIT_LSMUL: + case SLJIT_LMUL_SW: *inst |= IMUL; break; - case SLJIT_UDIVMOD: - case SLJIT_UDIVI: + case SLJIT_DIVMOD_UW: + case SLJIT_DIV_UW: *inst |= DIV; break; - case SLJIT_SDIVMOD: - case SLJIT_SDIVI: + case SLJIT_DIVMOD_SW: + case SLJIT_DIV_SW: *inst |= IDIV; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) - if (op <= SLJIT_SDIVMOD) + if (op <= SLJIT_DIVMOD_SW) EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #else - if (op >= SLJIT_UDIVI) + if (op >= SLJIT_DIV_UW) EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0); #endif break; @@ -865,20 +865,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #define ENCODE_PREFIX(prefix) \ do { \ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \ FAIL_IF(!inst); \ INC_SIZE(1); \ *inst = (prefix); \ } while (0) -static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si work_r; + sljit_s32 work_r; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -1016,12 +1016,12 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } -static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; @@ -1067,11 +1067,11 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; } -static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); @@ -1106,11 +1106,11 @@ static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, return SLJIT_SUCCESS; } -static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); @@ -1146,12 +1146,12 @@ static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; SLJIT_UNUSED_ARG(op_flags); if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { @@ -1164,7 +1164,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REG1, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REG1, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, TMP_REG1, 0); #endif FAIL_IF(!inst); *inst |= SHR; @@ -1199,8 +1199,8 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, #else dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; compiler->mode32 = 0; - EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); - compiler->mode32 = op_flags & SLJIT_INT_OP; + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 64 + 63 : 32 + 31); + compiler->mode32 = op_flags & SLJIT_I32_OP; #endif if (cpu_has_cmov == -1) @@ -1213,7 +1213,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst = CMOVNE_r_rm; } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); @@ -1222,7 +1222,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, *inst++ = MOV_r_rm; *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REG1]; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); FAIL_IF(!inst); INC_SIZE(5); @@ -1237,7 +1237,7 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); + inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_I32_OP) ? 63 : 31, dst_r, 0); #endif FAIL_IF(!inst); *(inst + 1) |= XOR; @@ -1255,16 +1255,16 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; - sljit_si update = 0; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_u8* inst; + sljit_s32 update = 0; + sljit_s32 op_flags = GET_ALL_FLAGS(op); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si dst_is_ereg = 0; - sljit_si src_is_ereg = 0; + sljit_s32 dst_is_ereg = 0; + sljit_s32 src_is_ereg = 0; #else # define src_is_ereg 0 #endif @@ -1277,7 +1277,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op_flags & SLJIT_INT_OP; + compiler->mode32 = op_flags & SLJIT_I32_OP; #endif op = GET_OPCODE(op); @@ -1286,20 +1286,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler compiler->mode32 = 0; #endif - if (op_flags & SLJIT_INT_OP) { + if (op_flags & SLJIT_I32_OP) { if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; + if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOV_U32; + if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM)) + op = SLJIT_MOVU_U32; + if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOV_S32; + if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM)) + op = SLJIT_MOVU_S32; #endif } @@ -1311,24 +1311,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler if (src & SLJIT_IMM) { switch (op) { - case SLJIT_MOV_UB: - srcw = (sljit_ub)srcw; + case SLJIT_MOV_U8: + srcw = (sljit_u8)srcw; break; - case SLJIT_MOV_SB: - srcw = (sljit_sb)srcw; + case SLJIT_MOV_S8: + srcw = (sljit_s8)srcw; break; - case SLJIT_MOV_UH: - srcw = (sljit_uh)srcw; + case SLJIT_MOV_U16: + srcw = (sljit_u16)srcw; break; - case SLJIT_MOV_SH: - srcw = (sljit_sh)srcw; + case SLJIT_MOV_S16: + srcw = (sljit_s16)srcw; break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - case SLJIT_MOV_UI: - srcw = (sljit_ui)srcw; + case SLJIT_MOV_U32: + srcw = (sljit_u32)srcw; break; - case SLJIT_MOV_SI: - srcw = (sljit_si)srcw; + case SLJIT_MOV_S32: + srcw = (sljit_s32)srcw; break; #endif } @@ -1347,7 +1347,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { + if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_U32 || op == SLJIT_MOV_S32 || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP)); dst = TMP_REG1; } @@ -1357,28 +1357,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV: case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: + case SLJIT_MOV_U32: + case SLJIT_MOV_S32: #endif FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); break; - case SLJIT_MOV_UB: + case SLJIT_MOV_U8: FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw)); break; - case SLJIT_MOV_SB: + case SLJIT_MOV_S8: FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw)); break; - case SLJIT_MOV_UH: + case SLJIT_MOV_U16: FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw)); break; - case SLJIT_MOV_SH: + case SLJIT_MOV_S16: FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw)); break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - case SLJIT_MOV_UI: + case SLJIT_MOV_U32: FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw)); break; - case SLJIT_MOV_SI: + case SLJIT_MOV_S32: FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw)); break; #endif @@ -1454,13 +1454,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); @@ -1570,13 +1570,13 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, - sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, + sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); @@ -1652,13 +1652,13 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_mul(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_mul(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; - sljit_si dst_r; + sljit_u8* inst; + sljit_s32 dst_r; dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; @@ -1686,17 +1686,17 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); - *inst = (sljit_sb)src1w; + *inst = (sljit_s8)src1w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); *(sljit_sw*)inst = src1w; @@ -1706,10 +1706,10 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src1w; + *(sljit_s32*)inst = (sljit_s32)src1w; } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); @@ -1729,17 +1729,17 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); INC_SIZE(1); - *inst = (sljit_sb)src2w; + *inst = (sljit_s8)src2w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); *(sljit_sw*)inst = src2w; @@ -1749,10 +1749,10 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src2w; + *(sljit_s32*)inst = (sljit_s32)src2w; } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src2w); @@ -1782,13 +1782,13 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, sljit_s32 keep_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; - sljit_si dst_r, done = 0; + sljit_u8* inst; + sljit_s32 dst_r, done = 0; /* These cases better be left to handled by normal way. */ if (!keep_flags) { @@ -1809,7 +1809,7 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_f } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_si)src2w); + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w); #else if (src2 & SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); @@ -1822,7 +1822,7 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_f else if (FAST_IS_REG(src2)) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); + inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w); #else if (src1 & SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); @@ -1841,11 +1841,11 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_f return SLJIT_ERR_UNSUPPORTED; } -static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { @@ -1892,11 +1892,11 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_test_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { @@ -2002,13 +2002,13 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_shift(struct sljit_compiler *compiler, - sljit_ub mode, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_shift(struct sljit_compiler *compiler, + sljit_u8 mode, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_ub* inst; + sljit_u8* inst; if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { if (dst == src1 && dstw == src1w) { @@ -2091,11 +2091,11 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, - sljit_ub mode, sljit_si set_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler, + sljit_u8 mode, sljit_s32 set_flags, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { /* The CPU does not set flags if the shift count is 0. */ if (src2 & SLJIT_IMM) { @@ -2126,10 +2126,10 @@ static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2141,7 +2141,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler CHECK_EXTRA_REGS(src1, src1w, (void)0); CHECK_EXTRA_REGS(src2, src2w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_INT_OP; + compiler->mode32 = op & SLJIT_I32_OP; #endif if (GET_OPCODE(op) >= SLJIT_MUL) { @@ -2221,7 +2221,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_register_index(reg)); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -2231,21 +2231,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) { CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_s32 size) { - sljit_ub *inst; + sljit_u8 *inst; CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); SLJIT_MEMMOVE(inst, instruction, size); @@ -2257,12 +2257,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* --------------------------------------------------------------------- */ /* Alignment + 2 * 16 bytes. */ -static sljit_si sse2_data[3 + (4 + 4) * 2]; -static sljit_si *sse2_buffer; +static sljit_s32 sse2_data[3 + (4 + 4) * 2]; +static sljit_s32 *sse2_buffer; static void init_compiler(void) { - sse2_buffer = (sljit_si*)(((sljit_uw)sse2_data + 15) & ~0xf); + sse2_buffer = (sljit_s32*)(((sljit_uw)sse2_data + 15) & ~0xf); /* Single precision constants. */ sse2_buffer[0] = 0x80000000; sse2_buffer[4] = 0x7fffffff; @@ -2273,7 +2273,7 @@ static void init_compiler(void) sse2_buffer[13] = 0x7fffffff; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_fpu_available(void) { #ifdef SLJIT_IS_FPU_AVAILABLE return SLJIT_IS_FPU_AVAILABLE; @@ -2286,10 +2286,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif /* SLJIT_DETECT_SSE2 */ } -static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode, + sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) { - sljit_ub *inst; + sljit_u8 *inst; inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); FAIL_IF(!inst); @@ -2298,10 +2298,10 @@ static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, return SLJIT_SUCCESS; } -static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si pref66, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode, + sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) { - sljit_ub *inst; + sljit_u8 *inst; inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); FAIL_IF(!inst); @@ -2310,31 +2310,31 @@ static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_sse2_load(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler, + sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); } -static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_sw dstw, sljit_si src) +static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, + sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src) { return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; - sljit_ub *inst; + sljit_s32 dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVW_FROMD) + if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) compiler->mode32 = 0; #endif - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); + inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); FAIL_IF(!inst); *inst++ = GROUP_0F; *inst = CVTTSD2SI_r_xm; @@ -2344,29 +2344,29 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convw_fromd(struct sljit_compiler * return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; - sljit_ub *inst; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMW) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) compiler->mode32 = 0; #endif if (src & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (GET_OPCODE(op) == SLJIT_CONVD_FROMI) - srcw = (sljit_si)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); src = TMP_REG1; srcw = 0; } - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_SINGLE_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); + inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_F32_OP) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); FAIL_IF(!inst); *inst++ = GROUP_0F; *inst = CVTSI2SD_x_rm; @@ -2375,27 +2375,27 @@ static SLJIT_INLINE sljit_si sljit_emit_fop1_convd_fromw(struct sljit_compiler * compiler->mode32 = 1; #endif if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_si op, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { compiler->flags_saved = 0; if (!FAST_IS_REG(src1)) { - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w)); src1 = TMP_FREG; } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), src1, src2, src2w); + return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_F32_OP), src1, src2, src2w); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - sljit_si dst_r; + sljit_s32 dst_r; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -2404,65 +2404,65 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile CHECK_ERROR(); SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw); - if (GET_OPCODE(op) == SLJIT_DMOV) { + if (GET_OPCODE(op) == SLJIT_MOV_F64) { if (FAST_IS_REG(dst)) - return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); + return emit_sse2_load(compiler, op & SLJIT_F32_OP, dst, src, srcw); if (FAST_IS_REG(src)) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, src); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src, srcw)); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); } - if (GET_OPCODE(op) == SLJIT_CONVD_FROMS) { + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) { dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; if (FAST_IS_REG(src)) { /* We overwrite the high bits of source. From SLJIT point of view, this is not an issue. Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */ - FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_SINGLE_OP, src, src, 0)); + FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_F32_OP, src, src, 0)); } else { - FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_SINGLE_OP), TMP_FREG, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_F32_OP), TMP_FREG, src, srcw)); src = TMP_FREG; } - FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_SINGLE_OP, dst_r, src, 0)); + FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_F32_OP, dst_r, src, 0)); if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } if (SLOW_IS_REG(dst)) { dst_r = dst; if (dst != src) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw)); } else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src, srcw)); } switch (GET_OPCODE(op)) { - case SLJIT_DNEG: - FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8))); + case SLJIT_NEG_F64: + FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer : sse2_buffer + 8))); break; - case SLJIT_DABS: - FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12))); + case SLJIT_ABS_F64: + FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_F32_OP ? sse2_buffer + 4 : sse2_buffer + 12))); break; } if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { - sljit_si dst_r; + sljit_s32 dst_r; CHECK_ERROR(); CHECK(check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w)); @@ -2478,43 +2478,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile dst_r = dst; if (dst == src1) ; /* Do nothing here. */ - else if (dst == src2 && (op == SLJIT_DADD || op == SLJIT_DMUL)) { + else if (dst == src2 && (op == SLJIT_ADD_F64 || op == SLJIT_MUL_F64)) { /* Swap arguments. */ src2 = src1; src2w = src1w; } else if (dst != src2) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, dst_r, src1, src1w)); else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w)); } } else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w)); } switch (GET_OPCODE(op)) { - case SLJIT_DADD: - FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_ADD_F64: + FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; - case SLJIT_DSUB: - FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_SUB_F64: + FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; - case SLJIT_DMUL: - FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_MUL_F64: + FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; - case SLJIT_DDIV: - FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_DIV_F64: + FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_F32_OP, dst_r, src2, src2w)); break; } if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, op & SLJIT_F32_OP, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } @@ -2524,7 +2524,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_label *label; CHECK_ERROR_PTR(); @@ -2542,7 +2542,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi PTR_FAIL_IF(!label); set_label(label, compiler); - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); *inst++ = 0; @@ -2551,9 +2551,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_jump *jump; CHECK_ERROR_PTR(); @@ -2580,7 +2580,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF_NULL(inst); *inst++ = 0; @@ -2588,9 +2588,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_jump *jump; CHECK_ERROR(); @@ -2638,7 +2638,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil compiler->size += 10 + 3; #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); FAIL_IF_NULL(inst); *inst++ = 0; @@ -2657,18 +2657,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw, + sljit_s32 type) { - sljit_ub *inst; - sljit_ub cond_set = 0; + sljit_u8 *inst; + sljit_u8 cond_set = 0; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; + sljit_s32 reg; #else /* CHECK_EXTRA_REGS migh overwrite these values. */ - sljit_si dst_save = dst; + sljit_s32 dst_save = dst; sljit_sw dstw_save = dstw; #endif @@ -2690,7 +2690,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 3); FAIL_IF(!inst); INC_SIZE(4 + 3); /* Set low register to conditional flag. */ @@ -2706,7 +2706,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com reg = (op == SLJIT_MOV && FAST_IS_REG(dst)) ? dst : TMP_REG1; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + 4); FAIL_IF(!inst); INC_SIZE(4 + 4); /* Set low register to conditional flag. */ @@ -2735,7 +2735,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { if (reg_map[dst] <= 4) { /* Low byte is accessible. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!inst); INC_SIZE(3 + 3); /* Set low byte to conditional flag. */ @@ -2758,7 +2758,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com /* a xor reg, reg operation would overwrite the flags. */ EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); FAIL_IF(!inst); INC_SIZE(3); @@ -2769,7 +2769,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 3 + 1); *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; @@ -2788,7 +2788,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && dst == src && reg_map[dst] <= 4) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_R0] == 0, scratch_reg1_must_be_eax); if (dst != SLJIT_R0) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 2 + 1); /* Set low register to conditional flag. */ @@ -2801,7 +2801,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); FAIL_IF(!inst); INC_SIZE(2 + 3 + 2 + 2); /* Set low register to conditional flag. */ @@ -2819,7 +2819,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com } /* Set TMP_REG1 to the bit. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); FAIL_IF(!inst); INC_SIZE(1 + 3 + 3 + 1); *inst++ = XCHG_EAX_r + reg_map[TMP_REG1]; @@ -2845,7 +2845,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com #endif /* SLJIT_CONFIG_X86_64 */ } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { CHECK_ERROR(); CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset)); @@ -2876,12 +2876,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co return emit_mov(compiler, dst, dstw, SLJIT_SP, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { - sljit_ub *inst; + sljit_u8 *inst; struct sljit_const *const_; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; + sljit_s32 reg; #endif CHECK_ERROR_PTR(); @@ -2908,7 +2908,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return NULL; #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); + inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); *inst++ = 0; @@ -2937,7 +2937,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta *(sljit_sw*)addr = new_constant; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_sse2_available(void) { #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) if (cpu_has_sse2 == -1) @@ -2948,34 +2948,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_is_cmov_available(void) { if (cpu_has_cmov == -1) get_cpu_features(); return cpu_has_cmov; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, - sljit_si type, - sljit_si dst_reg, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw) { - sljit_ub* inst; + sljit_u8* inst; CHECK_ERROR(); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_x86_is_cmov_available()); - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP)); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP)); FUNCTION_CHECK_SRC(src, srcw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " x86_cmov%s %s%s, ", - !(dst_reg & SLJIT_INT_OP) ? "" : ".i", - JUMP_PREFIX(type), jump_names[type & 0xff]); - sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP); + !(dst_reg & SLJIT_I32_OP) ? "" : ".i", + jump_names[type & 0xff], JUMP_POSTFIX(type)); + sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); @@ -2986,9 +2986,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *com CHECK_EXTRA_REGS(src, srcw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = dst_reg & SLJIT_INT_OP; + compiler->mode32 = dst_reg & SLJIT_I32_OP; #endif - dst_reg &= ~SLJIT_INT_OP; + dst_reg &= ~SLJIT_I32_OP; if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); diff --git a/pcre/sljit/sljitUtils.c b/pcre/sljit/sljitUtils.c index 5294b5f3f9be7..ec5c321194a6f 100644 --- a/pcre/sljit/sljitUtils.c +++ b/pcre/sljit/sljitUtils.c @@ -163,11 +163,11 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) #include /* Some old systems does not have MAP_ANON. */ -static sljit_si dev_zero = -1; +static sljit_s32 dev_zero = -1; #if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) -static SLJIT_INLINE sljit_si open_dev_zero(void) +static SLJIT_INLINE sljit_s32 open_dev_zero(void) { dev_zero = open("/dev/zero", O_RDWR); return dev_zero < 0; @@ -179,10 +179,13 @@ static SLJIT_INLINE sljit_si open_dev_zero(void) static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; -static SLJIT_INLINE sljit_si open_dev_zero(void) +static SLJIT_INLINE sljit_s32 open_dev_zero(void) { pthread_mutex_lock(&dev_zero_mutex); - dev_zero = open("/dev/zero", O_RDWR); + /* The dev_zero might be initialized by another thread during the waiting. */ + if (dev_zero < 0) { + dev_zero = open("/dev/zero", O_RDWR); + } pthread_mutex_unlock(&dev_zero_mutex); return dev_zero < 0; } diff --git a/pcre/testdata/testinput11 b/pcre/testdata/testinput11 index ac9d2289854a1..6f0989a14c2b7 100644 --- a/pcre/testdata/testinput11 +++ b/pcre/testdata/testinput11 @@ -138,4 +138,6 @@ is required for these tests. --/ /.((?2)(?R)\1)()/B +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ + /-- End of testinput11 --/ diff --git a/pcre/testdata/testinput2 b/pcre/testdata/testinput2 index e2e520f740422..75e402ee9b3c5 100644 --- a/pcre/testdata/testinput2 +++ b/pcre/testdata/testinput2 @@ -4217,4 +4217,30 @@ backtracking verbs. --/ /a[[:punct:]b]/BZ +/L(?#(|++)(?J:(?)(?))(?)/ + \O\CC + +/(?=a\K)/ + ring bpattingbobnd $ 1,oern cou \rb\L + +/(?<=((?C)0))/ + 9010 + abcd + +/((?J)(?'R'(?'R'(?'R'(?'R'(?'R'(?|(\k'R'))))))))/ + +/\N(?(?C)0?!.)*/ + /-- End of testinput2 --/ diff --git a/pcre/testdata/testinput6 b/pcre/testdata/testinput6 index aeb62a073fa0d..a178d3d67b408 100644 --- a/pcre/testdata/testinput6 +++ b/pcre/testdata/testinput6 @@ -1553,4 +1553,13 @@ \x{200} \x{37e} +/[^[:^ascii:]\d]/8W + a + ~ + 0 + \a + \x{7f} + \x{389} + \x{20ac} + /-- End of testinput6 --/ diff --git a/pcre/testdata/testinput7 b/pcre/testdata/testinput7 index e411a4b842e69..00b9738a37171 100644 --- a/pcre/testdata/testinput7 +++ b/pcre/testdata/testinput7 @@ -853,4 +853,8 @@ of case for anything other than the ASCII letters. --/ /a[b[:punct:]]/8WBZ +/L(?#(|++a)...(?P=a)bbb(?P>a)d/BM -Memory allocation (code space): 77 +Memory allocation (code space): 93 ------------------------------------------------------------------ 0 24 Bra 2 5 CBra 1 @@ -765,4 +765,7 @@ Memory allocation (code space): 14 25 End ------------------------------------------------------------------ +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ +Failed: regular expression is too complicated at offset 490 + /-- End of testinput11 --/ diff --git a/pcre/testdata/testoutput11-32 b/pcre/testdata/testoutput11-32 index 57e5da0279529..e19518db59444 100644 --- a/pcre/testdata/testoutput11-32 +++ b/pcre/testdata/testoutput11-32 @@ -231,7 +231,7 @@ Memory allocation (code space): 155 ------------------------------------------------------------------ /(?Pa)...(?P=a)bbb(?P>a)d/BM -Memory allocation (code space): 157 +Memory allocation (code space): 189 ------------------------------------------------------------------ 0 24 Bra 2 5 CBra 1 @@ -765,4 +765,7 @@ Memory allocation (code space): 28 25 End ------------------------------------------------------------------ +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ +Failed: missing ) at offset 509 + /-- End of testinput11 --/ diff --git a/pcre/testdata/testoutput11-8 b/pcre/testdata/testoutput11-8 index 748548a5abbd2..5a4fbb23663f6 100644 --- a/pcre/testdata/testoutput11-8 +++ b/pcre/testdata/testoutput11-8 @@ -231,7 +231,7 @@ Memory allocation (code space): 45 ------------------------------------------------------------------ /(?Pa)...(?P=a)bbb(?P>a)d/BM -Memory allocation (code space): 50 +Memory allocation (code space): 62 ------------------------------------------------------------------ 0 30 Bra 3 7 CBra 1 @@ -765,4 +765,7 @@ Memory allocation (code space): 10 38 End ------------------------------------------------------------------ +/([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00]([00](*ACCEPT)/ +Failed: missing ) at offset 509 + /-- End of testinput11 --/ diff --git a/pcre/testdata/testoutput2 b/pcre/testdata/testoutput2 index 85c565d1326ef..5e88d1a70912f 100644 --- a/pcre/testdata/testoutput2 +++ b/pcre/testdata/testoutput2 @@ -419,7 +419,7 @@ Need char = '>' /(?U)<.*>/I Capturing subpattern count = 0 -Options: ungreedy +No options First char = '<' Need char = '>' abcghinop @@ -443,7 +443,7 @@ Need char = '=' /(?U)={3,}?/I Capturing subpattern count = 0 -Options: ungreedy +No options First char = '=' Need char = '=' abc========def @@ -477,7 +477,7 @@ Failed: lookbehind assertion is not fixed length at offset 12 /(?i)abc/I Capturing subpattern count = 0 -Options: caseless +No options First char = 'a' (caseless) Need char = 'c' (caseless) @@ -489,7 +489,7 @@ No need char /(?i)^1234/I Capturing subpattern count = 0 -Options: anchored caseless +Options: anchored No first char No need char @@ -502,7 +502,7 @@ No need char /(?s).*/I Capturing subpattern count = 0 May match empty string -Options: anchored dotall +Options: anchored No first char No need char @@ -516,7 +516,7 @@ Starting chars: a b c d /(?i)[abcd]/IS Capturing subpattern count = 0 -Options: caseless +No options No first char No need char Subject length lower bound = 1 @@ -524,7 +524,7 @@ Starting chars: A B C D a b c d /(?m)[xy]|(b|c)/IS Capturing subpattern count = 1 -Options: multiline +No options No first char No need char Subject length lower bound = 1 @@ -538,7 +538,7 @@ No need char /(?i)(^a|^b)/Im Capturing subpattern count = 1 -Options: caseless multiline +Options: multiline First char at start or follows newline No need char @@ -555,13 +555,13 @@ Failed: malformed number or name after (?( at offset 4 Failed: malformed number or name after (?( at offset 4 /(?(?i))/ -Failed: assertion expected after (?( at offset 3 +Failed: assertion expected after (?( or (?(?C) at offset 3 /(?(abc))/ Failed: reference to non-existent subpattern at offset 7 /(?(?.*!.*)?)" -Failed: assertion expected after (?( at offset 3 +Failed: assertion expected after (?( or (?(?C) at offset 3 "X((?2)()*+){2}+"BZ ------------------------------------------------------------------ @@ -14574,4 +14574,100 @@ No match End ------------------------------------------------------------------ +/L(?#(|++)(?J:(?)(?))(?)/ + \O\CC +Matched, but too many substrings +copy substring C failed -7 + +/(?=a\K)/ + ring bpattingbobnd $ 1,oern cou \rb\L +Start of matched string is beyond its end - displaying from end to start. + 0: a + 0L + +/(?<=((?C)0))/ + 9010 +--->9010 + 0 ^ 0 + 0 ^ 0 + 0: + 1: 0 + abcd +--->abcd + 0 ^ 0 + 0 ^ 0 + 0 ^ 0 + 0 ^ 0 +No match + +/((?J)(?'R'(?'R'(?'R'(?'R'(?'R'(?|(\k'R'))))))))/ + +/\N(?(?C)0?!.)*/ +Failed: assertion expected after (?( or (?(?C) at offset 4 + /-- End of testinput2 --/ diff --git a/pcre/testdata/testoutput6 b/pcre/testdata/testoutput6 index beb85aaa0b6ec..b64dc0dc366b0 100644 --- a/pcre/testdata/testoutput6 +++ b/pcre/testdata/testoutput6 @@ -2557,4 +2557,20 @@ No match \x{37e} 0: \x{37e} +/[^[:^ascii:]\d]/8W + a + 0: a + ~ + 0: ~ + 0 +No match + \a + 0: \x{07} + \x{7f} + 0: \x{7f} + \x{389} +No match + \x{20ac} +No match + /-- End of testinput6 --/ diff --git a/pcre/testdata/testoutput7 b/pcre/testdata/testoutput7 index cc9ebdd558882..fdfff646d3eba 100644 --- a/pcre/testdata/testoutput7 +++ b/pcre/testdata/testoutput7 @@ -2348,4 +2348,24 @@ No match End ------------------------------------------------------------------ +/L(?#(|++ Date: Mon, 20 Jun 2016 14:35:58 +0200 Subject: [PATCH 093/112] MDEV-5973: MySQL Bug#11757486:49539: NON-DESCRIPTIVE ERR (ERROR 0 FROM STORAGE ENGINE) WITH MULTI-TABLE UPDATE Condition in processing IGNORE clause for UPDATE & multi-table UPDATE made the same. --- mysql-test/r/multi_update.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/multi_update.test | 24 ++++++++++++++++++++++++ sql/sql_update.cc | 2 +- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index 688184f2f83ce..3b75cef2cf052 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -1039,4 +1039,36 @@ f1 f2 1 97 DROP TABLE t1, t2; DROP VIEW v1; +# +# MDEV-5973: MySQL Bug#11757486:49539: NON-DESCRIPTIVE ERR (ERROR 0 +# FROM STORAGE ENGINE) WITH MULTI-TABLE UPDATE +# +CREATE TABLE table_11757486 (field1 tinyint) ENGINE=INNODB; +INSERT INTO table_11757486 VALUES (0),(0); +SET SESSION SQL_MODE='STRICT_ALL_TABLES'; +UPDATE IGNORE (SELECT 128 as col1) x, table_11757486 SET field1=x.col1; +Warnings: +Warning 1264 Out of range value for column 'field1' at row 1 +Warning 1264 Out of range value for column 'field1' at row 2 +UPDATE IGNORE table_11757486 SET field1=128; +Warnings: +Warning 1264 Out of range value for column 'field1' at row 1 +Warning 1264 Out of range value for column 'field1' at row 2 +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. UPDATE IGNORE is unsafe because the order in which rows are updated determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. +UPDATE (SELECT 128 as col1) x, table_11757486 SET field1=x.col1; +ERROR 22003: Out of range value for column 'field1' at row 1 +UPDATE table_11757486 SET field1=128; +ERROR 22003: Out of range value for column 'field1' at row 1 +SET SESSION SQL_MODE=''; +UPDATE IGNORE (SELECT 128 as col1) x, table_11757486 SET field1=x.col1; +Warnings: +Warning 1264 Out of range value for column 'field1' at row 1 +Warning 1264 Out of range value for column 'field1' at row 2 +UPDATE IGNORE table_11757486 SET field1=128; +Warnings: +Warning 1264 Out of range value for column 'field1' at row 1 +Warning 1264 Out of range value for column 'field1' at row 2 +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. UPDATE IGNORE is unsafe because the order in which rows are updated determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave. +DROP TABLE table_11757486; +SET SESSION SQL_MODE=default; end of 10.0 tests diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test index c013938416e6e..04611fef7dced 100644 --- a/mysql-test/t/multi_update.test +++ b/mysql-test/t/multi_update.test @@ -1082,4 +1082,28 @@ SELECT * FROM v1; DROP TABLE t1, t2; DROP VIEW v1; +--echo # +--echo # MDEV-5973: MySQL Bug#11757486:49539: NON-DESCRIPTIVE ERR (ERROR 0 +--echo # FROM STORAGE ENGINE) WITH MULTI-TABLE UPDATE +--echo # + +CREATE TABLE table_11757486 (field1 tinyint) ENGINE=INNODB; +INSERT INTO table_11757486 VALUES (0),(0); +SET SESSION SQL_MODE='STRICT_ALL_TABLES'; +UPDATE IGNORE (SELECT 128 as col1) x, table_11757486 SET field1=x.col1; +UPDATE IGNORE table_11757486 SET field1=128; + +--error ER_WARN_DATA_OUT_OF_RANGE +UPDATE (SELECT 128 as col1) x, table_11757486 SET field1=x.col1; +--error ER_WARN_DATA_OUT_OF_RANGE +UPDATE table_11757486 SET field1=128; + +SET SESSION SQL_MODE=''; +UPDATE IGNORE (SELECT 128 as col1) x, table_11757486 SET field1=x.col1; +UPDATE IGNORE table_11757486 SET field1=128; + +DROP TABLE table_11757486; + +SET SESSION SQL_MODE=default; + --echo end of 10.0 tests diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2507c3fec5347..b2af075e2f44a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1584,7 +1584,7 @@ bool mysql_multi_update(THD *thd, DBUG_RETURN(TRUE); } - thd->abort_on_warning= thd->is_strict_mode(); + thd->abort_on_warning= !ignore && thd->is_strict_mode(); List total_list; res= mysql_select(thd, &select_lex->ref_pointer_array, From 69f1a3215e5062eb6c06ed35ec38e1d824efbef6 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 21 Jun 2016 19:20:11 +0200 Subject: [PATCH 094/112] Replace dynamic loading of mysqld.exe data for plugins, replace with MYSQL_PLUGIN_IMPORT --- include/m_ctype.h | 2 +- include/my_default.h | 4 ++-- sql/mysqld.h | 6 +++--- sql/slave.h | 4 ++-- sql/sql_class.h | 4 ++-- sql/sql_plugin.h | 2 +- storage/connect/mycat.cc | 14 +------------- storage/spider/spd_table.cc | 38 ------------------------------------- 8 files changed, 12 insertions(+), 62 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 5994816cbfc1e..641d0966f9e14 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -516,7 +516,7 @@ extern struct charset_info_st my_charset_utf16le_general_ci; extern struct charset_info_st my_charset_utf32_bin; extern struct charset_info_st my_charset_utf32_general_ci; extern struct charset_info_st my_charset_utf32_unicode_ci; -extern struct charset_info_st my_charset_utf8_bin; +extern struct charset_info_st MYSQL_PLUGIN_IMPORT my_charset_utf8_bin; extern struct charset_info_st my_charset_utf8_general_mysql500_ci; extern struct charset_info_st my_charset_utf8_unicode_ci; extern struct charset_info_st my_charset_utf8mb4_bin; diff --git a/include/my_default.h b/include/my_default.h index 1d556de69eeb0..123924249392d 100644 --- a/include/my_default.h +++ b/include/my_default.h @@ -20,9 +20,9 @@ C_MODE_START -extern const char *my_defaults_extra_file; +extern MYSQL_PLUGIN_IMPORT const char *my_defaults_extra_file; extern const char *my_defaults_group_suffix; -extern const char *my_defaults_file; +extern MYSQL_PLUGIN_IMPORT const char *my_defaults_file; extern my_bool my_getopt_use_args_separator; extern my_bool my_getopt_is_args_separator(const char* arg); diff --git a/sql/mysqld.h b/sql/mysqld.h index dbc65cd2a4378..02e3184404b0c 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -92,7 +92,7 @@ extern bool opt_disable_networking, opt_skip_show_db; extern bool opt_skip_name_resolve; extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; -extern bool volatile abort_loop; +extern MYSQL_PLUGIN_IMPORT bool volatile abort_loop; extern bool in_bootstrap; extern uint connection_count; extern my_bool opt_safe_user_create; @@ -155,7 +155,7 @@ extern char log_error_file[FN_REFLEN], *opt_tc_log_file; extern const double log_10[309]; extern ulonglong keybuff_size; extern ulonglong thd_startup_options; -extern ulong thread_id; +extern MYSQL_PLUGIN_IMPORT ulong thread_id; extern ulong binlog_cache_use, binlog_cache_disk_use; extern ulong binlog_stmt_cache_use, binlog_stmt_cache_disk_use; extern ulong aborted_threads,aborted_connects; @@ -226,7 +226,7 @@ extern MYSQL_FILE *bootstrap_file; extern my_bool old_mode; extern LEX_STRING opt_init_connect, opt_init_slave; extern int bootstrap_error; -extern I_List threads; +extern MYSQL_PLUGIN_IMPORT I_List threads; extern char err_shared_dir[]; extern ulong connection_errors_select; extern ulong connection_errors_accept; diff --git a/sql/slave.h b/sql/slave.h index 5cc02c8a10b3c..946cc956c41be 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -244,7 +244,7 @@ void slave_output_error_info(rpl_group_info *rgi, THD *thd); pthread_handler_t handle_slave_sql(void *arg); bool net_request_file(NET* net, const char* fname); -extern bool volatile abort_loop; +extern MYSQL_PLUGIN_IMPORT bool volatile abort_loop; extern Master_info *active_mi; /* active_mi for multi-master */ extern Master_info *default_master_info; /* To replace active_mi */ extern Master_info_index *master_info_index; @@ -258,7 +258,7 @@ extern uint report_port; extern char *master_info_file, *report_user; extern char *report_host, *report_password; -extern I_List threads; +extern MYSQL_PLUGIN_IMPORT I_List threads; #else #define close_active_mi() /* no-op */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 46eeeceb1124d..799a6088d3ff1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1094,8 +1094,8 @@ typedef struct st_xid_state { uint rm_error; } XID_STATE; -extern mysql_mutex_t LOCK_xid_cache; -extern HASH xid_cache; +extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_xid_cache; +extern MYSQL_PLUGIN_IMPORT HASH xid_cache; bool xid_cache_init(void); void xid_cache_free(void); XID_STATE *xid_cache_search(XID *xid); diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index a0225f4a071aa..e5f985aa08294 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -153,7 +153,7 @@ typedef int (*plugin_type_init)(struct st_plugin_int *); extern I_List *opt_plugin_load_list_ptr; extern char *opt_plugin_dir_ptr; -extern char opt_plugin_dir[FN_REFLEN]; +extern MYSQL_PLUGIN_IMPORT char opt_plugin_dir[FN_REFLEN]; extern const LEX_STRING plugin_type_names[]; extern ulong plugin_maturity; extern TYPELIB plugin_maturity_values; diff --git a/storage/connect/mycat.cc b/storage/connect/mycat.cc index 97ad980dd6a7a..04cea59734e50 100644 --- a/storage/connect/mycat.cc +++ b/storage/connect/mycat.cc @@ -105,19 +105,7 @@ PQRYRES OEMColumns(PGLOBAL g, PTOS topt, char *tab, char *db, bool info); /***********************************************************************/ char *GetPluginDir(void) { - char *plugin_dir; - -#if defined(_WIN64) - plugin_dir = (char *)GetProcAddress(GetModuleHandle(NULL), - "?opt_plugin_dir@@3PADEA"); -#elif defined(_WIN32) - plugin_dir = (char*)GetProcAddress(GetModuleHandle(NULL), - "?opt_plugin_dir@@3PADA"); -#else - plugin_dir = opt_plugin_dir; -#endif - - return plugin_dir; + return opt_plugin_dir; } // end of GetPluginDir /***********************************************************************/ diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index ead335c07ea74..2448ee661c517 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6325,43 +6325,6 @@ int spider_db_init( memset(&spider_alloc_mem_count, 0, sizeof(spider_alloc_mem_count)); memset(&spider_free_mem_count, 0, sizeof(spider_free_mem_count)); -#ifdef _WIN32 - HMODULE current_module = GetModuleHandle(NULL); - spd_db_att_thread_id = (ulong *) - GetProcAddress(current_module, "?thread_id@@3KA"); -#ifdef SPIDER_XID_USES_xid_cache_iterate -#else -#ifdef XID_CACHE_IS_SPLITTED - spd_db_att_xid_cache_split_num = (uint *) - GetProcAddress(current_module, - "?opt_xid_cache_split_num@@3IA"); - spd_db_att_LOCK_xid_cache = *((pthread_mutex_t **) - GetProcAddress(current_module, - "?LOCK_xid_cache@@3PAUst_mysql_mutex@@A")); - spd_db_att_xid_cache = *((HASH **) - GetProcAddress(current_module, "?xid_cache@@3PAUst_hash@@A")); -#else - spd_db_att_LOCK_xid_cache = (pthread_mutex_t *) -#if MYSQL_VERSION_ID < 50500 - GetProcAddress(current_module, - "?LOCK_xid_cache@@3U_RTL_CRITICAL_SECTION@@A"); -#else - GetProcAddress(current_module, - "?LOCK_xid_cache@@3Ust_mysql_mutex@@A"); -#endif - spd_db_att_xid_cache = (HASH *) - GetProcAddress(current_module, "?xid_cache@@3Ust_hash@@A"); -#endif -#endif - spd_charset_utf8_bin = (struct charset_info_st *) - GetProcAddress(current_module, "my_charset_utf8_bin"); - spd_defaults_extra_file = (const char **) - GetProcAddress(current_module, "my_defaults_extra_file"); - spd_defaults_file = (const char **) - GetProcAddress(current_module, "my_defaults_file"); - spd_abort_loop = (bool volatile *) - GetProcAddress(current_module, "?abort_loop@@3_NC"); -#else spd_db_att_thread_id = &thread_id; #ifdef SPIDER_XID_USES_xid_cache_iterate #else @@ -6378,7 +6341,6 @@ int spider_db_init( spd_defaults_extra_file = &my_defaults_extra_file; spd_defaults_file = &my_defaults_file; spd_abort_loop = &abort_loop; -#endif #ifdef HAVE_PSI_INTERFACE init_spider_psi_keys(); From 21479a6bb3cc37ffa1fb4f53a0ab71d22c7ad445 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 21 Jun 2016 21:26:31 +0400 Subject: [PATCH 095/112] MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH The patch fixes the problem with loading information from system tables (e.g. event and help related tables) when PAD_CHAR_TO_FULL_LENGTH is enabled, as well as includes some additional minor improvements: - refactoring in get_field() to return an error rather than success if strmake_root() failed - removing of duplicate code in similar functions: char *get_field(MEM_ROOT *mem, Field *field) bool get_field(MEM_ROOT *mem, Field *field, String *res) --- mysql-test/r/events_1.result | 20 ++++++++++++++++++++ mysql-test/r/help.result | 15 +++++++++++++++ mysql-test/t/events_1.test | 19 +++++++++++++++++++ mysql-test/t/help.test | 6 ++++++ sql/sql_help.cc | 11 ++++++++++- sql/table.cc | 34 ++++++++++++++++------------------ 6 files changed, 86 insertions(+), 19 deletions(-) diff --git a/mysql-test/r/events_1.result b/mysql-test/r/events_1.result index e03ccf51d8b2a..4e7ff526ecab0 100644 --- a/mysql-test/r/events_1.result +++ b/mysql-test/r/events_1.result @@ -469,6 +469,26 @@ DROP EVENT ev1; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +# +# MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH +# +CREATE TABLE t1 (a INT); +CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1; +SHOW EVENTS; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +events_test ev1 root@localhost SYSTEM RECURRING NULL 5 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +SHOW EVENTS; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +events_test ev1 root@localhost SYSTEM RECURRING NULL 5 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +DROP EVENT ev1; +CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1; +SHOW EVENTS; +Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation +events_test ev1 root@localhost SYSTEM RECURRING NULL 5 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +DROP EVENT ev1; +DROP TABLE t1; +SET sql_mode=DEFAULT; # # End of tests diff --git a/mysql-test/r/help.result b/mysql-test/r/help.result index 16719cc819350..319a1ba3e8599 100644 --- a/mysql-test/r/help.result +++ b/mysql-test/r/help.result @@ -148,6 +148,21 @@ help 'impossible_category_1'; source_category_name name is_it_category impossible_category_1 impossible_function_1 N impossible_category_1 impossible_function_2 N +# MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH +help 'impossible_function_1'; +name description example +impossible_function_1 description of + impossible_function1 + example of + impossible_function1 +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +help 'impossible_function_1'; +name description example +impossible_function_1 description of + impossible_function1 + example of + impossible_function1 +SET sql_mode=DEFAULT; alter table mysql.help_relation engine=innodb; alter table mysql.help_keyword engine=innodb; alter table mysql.help_topic engine=innodb; diff --git a/mysql-test/t/events_1.test b/mysql-test/t/events_1.test index bf5a356cee308..250b0d004dc6f 100644 --- a/mysql-test/t/events_1.test +++ b/mysql-test/t/events_1.test @@ -459,6 +459,25 @@ DROP EVENT ev1; SHOW EVENTS; +--echo # +--echo # MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH +--echo # +CREATE TABLE t1 (a INT); +CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1; +--replace_column 8 # 9 # +SHOW EVENTS; +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +--replace_column 8 # 9 # +SHOW EVENTS; +DROP EVENT ev1; +CREATE EVENT ev1 ON SCHEDULE EVERY 5 SECOND DO DELETE FROM t1; +--replace_column 8 # 9 # +SHOW EVENTS; +DROP EVENT ev1; +DROP TABLE t1; +SET sql_mode=DEFAULT; + + --echo --echo # --echo # End of tests diff --git a/mysql-test/t/help.test b/mysql-test/t/help.test index 71821e4677111..881299a216c60 100644 --- a/mysql-test/t/help.test +++ b/mysql-test/t/help.test @@ -61,6 +61,12 @@ help '%function_7'; help '%category_2'; help 'impossible_function_1'; help 'impossible_category_1'; + +--echo # MDEV-9524 Cannot load from mysql.event when sql_mode is set to PAD_CHAR_TO_FULL_LENGTH +help 'impossible_function_1'; +SET sql_mode=PAD_CHAR_TO_FULL_LENGTH; +help 'impossible_function_1'; +SET sql_mode=DEFAULT; ############## --disable_warnings diff --git a/sql/sql_help.cc b/sql/sql_help.cc index afeb9395a555b..f509d8b8f99dc 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -647,7 +647,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, TRUE Error and send_error already commited */ -bool mysqld_help(THD *thd, const char *mask) +static bool mysqld_help_internal(THD *thd, const char *mask) { Protocol *protocol= thd->protocol; SQL_SELECT *select; @@ -823,3 +823,12 @@ bool mysqld_help(THD *thd, const char *mask) DBUG_RETURN(TRUE); } + +bool mysqld_help(THD *thd, const char *mask) +{ + ulonglong sql_mode_backup= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; + bool rc= mysqld_help_internal(thd, mask); + thd->variables.sql_mode= sql_mode_backup; + return rc; +} diff --git a/sql/table.cc b/sql/table.cc index 5dae23116cc6f..e357d508e9ea5 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3384,18 +3384,23 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) { char buff[MAX_FIELD_WIDTH], *to; String str(buff,sizeof(buff),&my_charset_bin); - uint length; + bool rc; + THD *thd= field->get_thd(); + ulonglong sql_mode_backup= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; field->val_str(&str); - if (!(length= str.length())) + if ((rc= !str.length() || + !(to= strmake_root(mem, str.ptr(), str.length())))) { res->length(0); - return 1; + goto ex; } - if (!(to= strmake_root(mem, str.ptr(), length))) - length= 0; // Safety fix - res->set(to, length, field->charset()); - return 0; + res->set(to, str.length(), field->charset()); + +ex: + thd->variables.sql_mode= sql_mode_backup; + return rc; } @@ -3414,17 +3419,10 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) char *get_field(MEM_ROOT *mem, Field *field) { - char buff[MAX_FIELD_WIDTH], *to; - String str(buff,sizeof(buff),&my_charset_bin); - uint length; - - field->val_str(&str); - length= str.length(); - if (!length || !(to= (char*) alloc_root(mem,length+1))) - return NullS; - memcpy(to,str.ptr(),(uint) length); - to[length]=0; - return to; + String str; + bool rc= get_field(mem, field, &str); + DBUG_ASSERT(rc || str.ptr()[str.length()] == '\0'); + return rc ? NullS : (char *) str.ptr(); } /* From 1f761c5615c7414d1ccd88ceb70272029ac263cc Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Tue, 21 Jun 2016 23:34:31 +0400 Subject: [PATCH 096/112] MDEV-9728 - Hard crash in metadata_lock_info Added missing target_thd initialization when processing local thread. --- plugin/metadata_lock_info/metadata_lock_info.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index 19c0ee351031b..72108f7bcb455 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -174,7 +174,10 @@ static int i_s_metadata_lock_info_fill_table(THD *thd, TABLE_LIST *tables, delete_dynamic(&ids); if (info.error == 0) + { + info.target_thd= thd; info.call_in_target_thread(); + } DBUG_RETURN(info.error); } From 25f1a7ae69a28ff2b32cd0dfd39437384c9ed400 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 Jun 2016 10:23:11 +0200 Subject: [PATCH 097/112] revert part of 69f1a32 in particular, revert changes to the spider (avoid diverging from the upstream if possible) --- include/m_ctype.h | 2 +- include/my_default.h | 4 ++-- sql/mysqld.h | 6 +++--- sql/slave.h | 4 ++-- sql/sql_class.h | 4 ++-- storage/spider/spd_table.cc | 38 +++++++++++++++++++++++++++++++++++++ 6 files changed, 48 insertions(+), 10 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index 641d0966f9e14..5994816cbfc1e 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -516,7 +516,7 @@ extern struct charset_info_st my_charset_utf16le_general_ci; extern struct charset_info_st my_charset_utf32_bin; extern struct charset_info_st my_charset_utf32_general_ci; extern struct charset_info_st my_charset_utf32_unicode_ci; -extern struct charset_info_st MYSQL_PLUGIN_IMPORT my_charset_utf8_bin; +extern struct charset_info_st my_charset_utf8_bin; extern struct charset_info_st my_charset_utf8_general_mysql500_ci; extern struct charset_info_st my_charset_utf8_unicode_ci; extern struct charset_info_st my_charset_utf8mb4_bin; diff --git a/include/my_default.h b/include/my_default.h index 123924249392d..1d556de69eeb0 100644 --- a/include/my_default.h +++ b/include/my_default.h @@ -20,9 +20,9 @@ C_MODE_START -extern MYSQL_PLUGIN_IMPORT const char *my_defaults_extra_file; +extern const char *my_defaults_extra_file; extern const char *my_defaults_group_suffix; -extern MYSQL_PLUGIN_IMPORT const char *my_defaults_file; +extern const char *my_defaults_file; extern my_bool my_getopt_use_args_separator; extern my_bool my_getopt_is_args_separator(const char* arg); diff --git a/sql/mysqld.h b/sql/mysqld.h index 02e3184404b0c..dbc65cd2a4378 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -92,7 +92,7 @@ extern bool opt_disable_networking, opt_skip_show_db; extern bool opt_skip_name_resolve; extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; -extern MYSQL_PLUGIN_IMPORT bool volatile abort_loop; +extern bool volatile abort_loop; extern bool in_bootstrap; extern uint connection_count; extern my_bool opt_safe_user_create; @@ -155,7 +155,7 @@ extern char log_error_file[FN_REFLEN], *opt_tc_log_file; extern const double log_10[309]; extern ulonglong keybuff_size; extern ulonglong thd_startup_options; -extern MYSQL_PLUGIN_IMPORT ulong thread_id; +extern ulong thread_id; extern ulong binlog_cache_use, binlog_cache_disk_use; extern ulong binlog_stmt_cache_use, binlog_stmt_cache_disk_use; extern ulong aborted_threads,aborted_connects; @@ -226,7 +226,7 @@ extern MYSQL_FILE *bootstrap_file; extern my_bool old_mode; extern LEX_STRING opt_init_connect, opt_init_slave; extern int bootstrap_error; -extern MYSQL_PLUGIN_IMPORT I_List threads; +extern I_List threads; extern char err_shared_dir[]; extern ulong connection_errors_select; extern ulong connection_errors_accept; diff --git a/sql/slave.h b/sql/slave.h index 946cc956c41be..5cc02c8a10b3c 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -244,7 +244,7 @@ void slave_output_error_info(rpl_group_info *rgi, THD *thd); pthread_handler_t handle_slave_sql(void *arg); bool net_request_file(NET* net, const char* fname); -extern MYSQL_PLUGIN_IMPORT bool volatile abort_loop; +extern bool volatile abort_loop; extern Master_info *active_mi; /* active_mi for multi-master */ extern Master_info *default_master_info; /* To replace active_mi */ extern Master_info_index *master_info_index; @@ -258,7 +258,7 @@ extern uint report_port; extern char *master_info_file, *report_user; extern char *report_host, *report_password; -extern MYSQL_PLUGIN_IMPORT I_List threads; +extern I_List threads; #else #define close_active_mi() /* no-op */ diff --git a/sql/sql_class.h b/sql/sql_class.h index 799a6088d3ff1..46eeeceb1124d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1094,8 +1094,8 @@ typedef struct st_xid_state { uint rm_error; } XID_STATE; -extern MYSQL_PLUGIN_IMPORT mysql_mutex_t LOCK_xid_cache; -extern MYSQL_PLUGIN_IMPORT HASH xid_cache; +extern mysql_mutex_t LOCK_xid_cache; +extern HASH xid_cache; bool xid_cache_init(void); void xid_cache_free(void); XID_STATE *xid_cache_search(XID *xid); diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc index 2448ee661c517..ead335c07ea74 100644 --- a/storage/spider/spd_table.cc +++ b/storage/spider/spd_table.cc @@ -6325,6 +6325,43 @@ int spider_db_init( memset(&spider_alloc_mem_count, 0, sizeof(spider_alloc_mem_count)); memset(&spider_free_mem_count, 0, sizeof(spider_free_mem_count)); +#ifdef _WIN32 + HMODULE current_module = GetModuleHandle(NULL); + spd_db_att_thread_id = (ulong *) + GetProcAddress(current_module, "?thread_id@@3KA"); +#ifdef SPIDER_XID_USES_xid_cache_iterate +#else +#ifdef XID_CACHE_IS_SPLITTED + spd_db_att_xid_cache_split_num = (uint *) + GetProcAddress(current_module, + "?opt_xid_cache_split_num@@3IA"); + spd_db_att_LOCK_xid_cache = *((pthread_mutex_t **) + GetProcAddress(current_module, + "?LOCK_xid_cache@@3PAUst_mysql_mutex@@A")); + spd_db_att_xid_cache = *((HASH **) + GetProcAddress(current_module, "?xid_cache@@3PAUst_hash@@A")); +#else + spd_db_att_LOCK_xid_cache = (pthread_mutex_t *) +#if MYSQL_VERSION_ID < 50500 + GetProcAddress(current_module, + "?LOCK_xid_cache@@3U_RTL_CRITICAL_SECTION@@A"); +#else + GetProcAddress(current_module, + "?LOCK_xid_cache@@3Ust_mysql_mutex@@A"); +#endif + spd_db_att_xid_cache = (HASH *) + GetProcAddress(current_module, "?xid_cache@@3Ust_hash@@A"); +#endif +#endif + spd_charset_utf8_bin = (struct charset_info_st *) + GetProcAddress(current_module, "my_charset_utf8_bin"); + spd_defaults_extra_file = (const char **) + GetProcAddress(current_module, "my_defaults_extra_file"); + spd_defaults_file = (const char **) + GetProcAddress(current_module, "my_defaults_file"); + spd_abort_loop = (bool volatile *) + GetProcAddress(current_module, "?abort_loop@@3_NC"); +#else spd_db_att_thread_id = &thread_id; #ifdef SPIDER_XID_USES_xid_cache_iterate #else @@ -6341,6 +6378,7 @@ int spider_db_init( spd_defaults_extra_file = &my_defaults_extra_file; spd_defaults_file = &my_defaults_file; spd_abort_loop = &abort_loop; +#endif #ifdef HAVE_PSI_INTERFACE init_spider_psi_keys(); From 805703fa8e9dd2dc09b9e3a2b8d7786e541621ff Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 Jun 2016 00:20:28 +0200 Subject: [PATCH 098/112] Fixed for failures in buildbot: Windows fix constants to stay 64-bit instead of being truncated by VS. this fixes a hang on startup. --- storage/xtradb/include/os0sync.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index 9bbb0bb7b5fba..0f93f3ff074d0 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -96,8 +96,8 @@ struct os_event { private: /** Masks for the event signal count and set flag in the count_and_set field */ - enum { count_mask = 0x7fffffffffffffffULL, - set_mask = 0x8000000000000000ULL}; + static const ib_uint64_t count_mask = 0x7fffffffffffffffULL; + static const ib_uint64_t set_mask = 0x8000000000000000ULL; /** The MSB is set whenever when the event is in the signaled state, i.e. a thread does not stop if it tries to wait for this event. Lower From a10fd659aacd3a23386e5ff61a8c0ef9165690a3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 Jun 2016 00:24:42 +0200 Subject: [PATCH 099/112] Fixed for failures in buildbot: Replication 1. remove unnecessary rpl-tokudb combination file. 2. fix rpl_ignore_table to cleanup properly (not leave test grants in memory) 3. check_temp_dir() is supposed to set the error in stmt_da - do it even when called multiple times, this fixes a crash when rpl.rpl_slave_load_tmpdir_not_exist is run twice. --- mysql-test/suite/rpl/r/rpl_ignore_table.result | 1 + mysql-test/suite/rpl/t/rpl_ignore_table.test | 5 +++-- sql/slave.cc | 7 +++++-- storage/tokudb/mysql-test/rpl/combinations | 8 -------- 4 files changed, 9 insertions(+), 12 deletions(-) delete mode 100644 storage/tokudb/mysql-test/rpl/combinations diff --git a/mysql-test/suite/rpl/r/rpl_ignore_table.result b/mysql-test/suite/rpl/r/rpl_ignore_table.result index 8e7166fa278fe..6d7c4e3686c3b 100644 --- a/mysql-test/suite/rpl/r/rpl_ignore_table.result +++ b/mysql-test/suite/rpl/r/rpl_ignore_table.result @@ -142,4 +142,5 @@ HEX(word) SELECT * FROM tmptbl504451f4258$1; ERROR 42S02: Table 'test.tmptbl504451f4258$1' doesn't exist DROP TABLE t5; +flush privileges; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_ignore_table.test b/mysql-test/suite/rpl/t/rpl_ignore_table.test index b0019b70dc87a..f4c2c32a80519 100644 --- a/mysql-test/suite/rpl/t/rpl_ignore_table.test +++ b/mysql-test/suite/rpl/t/rpl_ignore_table.test @@ -1,6 +1,6 @@ -source include/master-slave.inc; let collation=utf8_unicode_ci; ---source include/have_collation.inc +source include/have_collation.inc; +source include/master-slave.inc; call mtr.add_suppression("Can't find record in 't.'"); call mtr.add_suppression("Can't find record in 'user'"); @@ -180,6 +180,7 @@ SELECT HEX(word) FROM t5; SELECT * FROM tmptbl504451f4258$1; connection master; DROP TABLE t5; +flush privileges; sync_slave_with_master; --source include/rpl_end.inc diff --git a/sql/slave.cc b/sql/slave.cc index 5dce7feed735c..5d44fb2b6a804 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4292,7 +4292,8 @@ int check_temp_dir(char* tmp_file) mysql_mutex_lock(&LOCK_thread_count); if (check_temp_dir_run) { - result= check_temp_dir_result; + if ((result= check_temp_dir_result)) + my_message(result, tmp_file, MYF(0)); goto end; } check_temp_dir_run= 1; @@ -4327,7 +4328,6 @@ int check_temp_dir(char* tmp_file) mysql_file_delete(key_file_misc, tmp_file, MYF(0)); end: - check_temp_dir_result= result; mysql_mutex_unlock(&LOCK_thread_count); DBUG_RETURN(result); } @@ -4603,11 +4603,14 @@ log '%s' at position %s, relay log '%s' position: %s%s", RPL_LOG_NAME, if (check_temp_dir(rli->slave_patternload_file)) { + check_temp_dir_result= thd->get_stmt_da()->sql_errno(); rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(), NULL, "Unable to use slave's temporary directory %s - %s", slave_load_tmpdir, thd->get_stmt_da()->message()); goto err; } + else + check_temp_dir_result= 0; /* Load the set of seen GTIDs, if we did not already. */ if (rpl_load_gtid_slave_state(thd)) diff --git a/storage/tokudb/mysql-test/rpl/combinations b/storage/tokudb/mysql-test/rpl/combinations deleted file mode 100644 index 07042c2cbecd2..0000000000000 --- a/storage/tokudb/mysql-test/rpl/combinations +++ /dev/null @@ -1,8 +0,0 @@ -[row] -binlog-format=row - -[stmt] -binlog-format=statement - -[mix] -binlog-format=mixed From 87da7670bd3d3fbeb8610f7232b717ead7ae2cfb Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 Jun 2016 09:41:06 +0200 Subject: [PATCH 100/112] Fixed for failures in buildbot: TokuDB disable unstable tokudb tests, (old change that was lost in a merge) --- storage/tokudb/mysql-test/tokudb/disabled.def | 2 ++ 1 file changed, 2 insertions(+) diff --git a/storage/tokudb/mysql-test/tokudb/disabled.def b/storage/tokudb/mysql-test/tokudb/disabled.def index ee8de9b141b09..c98a8aa622a93 100644 --- a/storage/tokudb/mysql-test/tokudb/disabled.def +++ b/storage/tokudb/mysql-test/tokudb/disabled.def @@ -26,3 +26,5 @@ type_temporal_fractional: type_temporal_upgrade: type_timestamp_explicit: cluster_key_part: engine options on partitioned tables +i_s_tokudb_lock_waits_released: unstable, race conditions +i_s_tokudb_locks_released: unstable, race conditions From 5fd80875909c88e624a79a528eaaf9418089a211 Mon Sep 17 00:00:00 2001 From: Igor Pashev Date: Mon, 30 May 2016 21:42:36 +0300 Subject: [PATCH 101/112] [MDEV-9614] Roles and Users longer than 6 characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bug is apparent when the username is longer than the rolename. It is caused by a simple typo that caused a memcmp call to compare a different number of bytes than necessary. The fix was proposed by Igor Pashev. I have reviewed it and it is the correct approach. Test case introduced by me, using the details provided in the MDEV. Signed-off-by: VicenÈ›iu Ciorbaru --- mysql-test/suite/roles/set_role-9614.result | 99 +++++++++++++++++++++ mysql-test/suite/roles/set_role-9614.test | 79 ++++++++++++++++ sql/sql_acl.cc | 12 ++- 3 files changed, 183 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/roles/set_role-9614.result create mode 100644 mysql-test/suite/roles/set_role-9614.test diff --git a/mysql-test/suite/roles/set_role-9614.result b/mysql-test/suite/roles/set_role-9614.result new file mode 100644 index 0000000000000..37f6db070c00e --- /dev/null +++ b/mysql-test/suite/roles/set_role-9614.result @@ -0,0 +1,99 @@ +# +# MDEV-9614 Roles and Users Longer than 6 characters +# +# This test case checks the edge case presented in the MDEV. The +# real issue is actually apparent when the username is longer than the +# rolename. +# +# We need a separate database not including test or test_% names. Due to +# default privileges given on these databases. +# +DROP DATABASE IF EXISTS `bug_db`; +Warnings: +Note 1008 Can't drop database 'bug_db'; database doesn't exist +# +# The first user did not show the bug as john's length is smaller +# than client. The bug is apparent most of the time for usertestjohn. +# +CREATE USER `john`@`%`; +CREATE USER `usertestjohn`@`%`; +CREATE ROLE `client`; +# +# Setup the required tables. +# +CREATE DATABASE `bug_db`; +CREATE TABLE `bug_db`.`t0`(`c0` INT); +# +# Setup select privileges only on the role. Setting the role should give +# select access to bug_db.t0. +# +GRANT SELECT ON `bug_db`.`t0` TO `client`; +GRANT `client` TO `john`@`%`; +GRANT `client` TO `usertestjohn`@`%`; +# +# Check to see grants are set. +# +SHOW GRANTS FOR `john`@`%`; +Grants for john@% +GRANT client TO 'john'@'%' +GRANT USAGE ON *.* TO 'john'@'%' +SHOW GRANTS FOR `usertestjohn`@`%`; +Grants for usertestjohn@% +GRANT client TO 'usertestjohn'@'%' +GRANT USAGE ON *.* TO 'usertestjohn'@'%' +SHOW GRANTS FOR `client`; +Grants for client +GRANT USAGE ON *.* TO 'client' +GRANT SELECT ON `bug_db`.`t0` TO 'client' +show databases; +Database +bug_db +information_schema +mtr +mysql +performance_schema +test +# +# Try using the database as john. +# +connect john, localhost, john,,information_schema; +show databases; +Database +information_schema +test +set role client; +show databases; +Database +bug_db +information_schema +test +use bug_db; +# +# Try using the database as usertestjohn. +# +connect usertestjohn, localhost, usertestjohn,,information_schema; +show databases; +Database +information_schema +test +set role client; +show databases; +Database +bug_db +information_schema +test +show grants; +Grants for usertestjohn@% +GRANT client TO 'usertestjohn'@'%' +GRANT USAGE ON *.* TO 'usertestjohn'@'%' +GRANT USAGE ON *.* TO 'client' +GRANT SELECT ON `bug_db`.`t0` TO 'client' +use bug_db; +# +# Cleanup +# +connection default; +drop user john; +drop user usertestjohn; +drop role client; +drop database bug_db; diff --git a/mysql-test/suite/roles/set_role-9614.test b/mysql-test/suite/roles/set_role-9614.test new file mode 100644 index 0000000000000..5e9f7dacf19c7 --- /dev/null +++ b/mysql-test/suite/roles/set_role-9614.test @@ -0,0 +1,79 @@ +--source include/not_embedded.inc + +--echo # +--echo # MDEV-9614 Roles and Users Longer than 6 characters +--echo # +--echo # This test case checks the edge case presented in the MDEV. The +--echo # real issue is actually apparent when the username is longer than the +--echo # rolename. + +--enable_connect_log +--echo # +--echo # We need a separate database not including test or test_% names. Due to +--echo # default privileges given on these databases. +--echo # +DROP DATABASE IF EXISTS `bug_db`; + +--echo # +--echo # The first user did not show the bug as john's length is smaller +--echo # than client. The bug is apparent most of the time for usertestjohn. +--echo # +CREATE USER `john`@`%`; +CREATE USER `usertestjohn`@`%`; +CREATE ROLE `client`; + +--echo # +--echo # Setup the required tables. +--echo # +CREATE DATABASE `bug_db`; +CREATE TABLE `bug_db`.`t0`(`c0` INT); + +--echo # +--echo # Setup select privileges only on the role. Setting the role should give +--echo # select access to bug_db.t0. +--echo # +GRANT SELECT ON `bug_db`.`t0` TO `client`; +GRANT `client` TO `john`@`%`; +GRANT `client` TO `usertestjohn`@`%`; + +--echo # +--echo # Check to see grants are set. +--echo # +SHOW GRANTS FOR `john`@`%`; +SHOW GRANTS FOR `usertestjohn`@`%`; +SHOW GRANTS FOR `client`; + +show databases; + +--echo # +--echo # Try using the database as john. +--echo # +connect (john, localhost, john,,information_schema); + +show databases; +set role client; +show databases; +use bug_db; + +--echo # +--echo # Try using the database as usertestjohn. +--echo # +connect (usertestjohn, localhost, usertestjohn,,information_schema); + +show databases; +set role client; +show databases; + +show grants; +use bug_db; + + +--echo # +--echo # Cleanup +--echo # +connection default; +drop user john; +drop user usertestjohn; +drop role client; +drop database bug_db; +--disable_connect_log diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8cc9469cd09e3..f06e9ce647c2c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7195,8 +7195,7 @@ bool check_grant_db(THD *thd, const char *db) len= (uint) (end - helping) + 1; /* - If a role is set, we need to check for privileges - here aswell + If a role is set, we need to check for privileges here as well. */ if (sctx->priv_role[0]) { @@ -7210,11 +7209,10 @@ bool check_grant_db(THD *thd, const char *db) for (uint idx=0 ; idx < column_priv_hash.records ; idx++) { - GRANT_TABLE *grant_table= (GRANT_TABLE*) - my_hash_element(&column_priv_hash, - idx); + GRANT_TABLE *grant_table= (GRANT_TABLE*) my_hash_element(&column_priv_hash, + idx); if (len < grant_table->key_length && - !memcmp(grant_table->hash_key,helping,len) && + !memcmp(grant_table->hash_key, helping, len) && compare_hostname(&grant_table->host, sctx->host, sctx->ip)) { error= FALSE; /* Found match. */ @@ -7222,7 +7220,7 @@ bool check_grant_db(THD *thd, const char *db) } if (sctx->priv_role[0] && len2 < grant_table->key_length && - !memcmp(grant_table->hash_key,helping2,len) && + !memcmp(grant_table->hash_key, helping2, len2) && (!grant_table->host.hostname || !grant_table->host.hostname[0])) { error= FALSE; /* Found role match */ From b449612907bd09bebf8d1280d80839cd16784fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicen=C8=9Biu=20Ciorbaru?= Date: Mon, 20 Jun 2016 23:43:01 +0300 Subject: [PATCH 102/112] MDEV-8638: REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_ROLE breaks replication Fix the replication failure caused by incorect initialization of THD::invoker_host && THD::invoker_user. Breakdown of the failure is this: Query_log_event::host and Query_log_event::user can have their LEX_STRING's set to length 0, but the actual str member points to garbage. Code afterwards copies Query_log_event::host and user to THD::invoker_host and THD::invoker_user. Calling code for these members expects both members to be initialized. Eg. the str member be a NULL terminated string and length have appropriate size. --- .../rpl_grant_revoke_current_role-8638.result | 21 +++++++++++++++++++ .../rpl_grant_revoke_current_role-8638.test | 12 +++++++++++ sql/log_event.cc | 19 +++++++++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result create mode 100644 mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test diff --git a/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result new file mode 100644 index 0000000000000..67af4a068d67d --- /dev/null +++ b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.result @@ -0,0 +1,21 @@ +include/master-slave.inc +[connection master] +create role r1; +set role r1; +grant select on db.* to current_role; +revoke all privileges, grant option from current_role; +drop role r1; +include/rpl_end.inc +connection server_2; +connection server_2; +connection server_2; +connection server_2; +connection server_1; +connection server_1; +connection server_1; +connection server_2; +connection server_1; +connection server_2; +connection server_2; +connection server_1; +connection server_1; diff --git a/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test new file mode 100644 index 0000000000000..6a6c4f2a7568b --- /dev/null +++ b/mysql-test/suite/roles/rpl_grant_revoke_current_role-8638.test @@ -0,0 +1,12 @@ +--source include/master-slave.inc +--source include/have_binlog_format_mixed.inc + +--enable_connect_log + +create role r1; +set role r1; +grant select on db.* to current_role; +revoke all privileges, grant option from current_role; +drop role r1; + +--source include/rpl_end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index 82cd82b5e7ac8..4a1d13a8004fb 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3631,10 +3631,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, if (time_zone_len) copy_str_and_move(&time_zone_str, &start, time_zone_len); - if (user.length > 0) + if (user.length) + { copy_str_and_move((const char **)&(user.str), &start, user.length); - if (host.length > 0) + } + else + { + user.str= (char *) start++; + user.str[0]= '\0'; + } + + if (host.length) + { copy_str_and_move((const char **)&(host.str), &start, host.length); + } + else + { + host.str= (char *) start++; + host.str[0]= '\0'; + } /** if time_zone_len or catalog_len are 0, then time_zone and catalog From 26bf066d566371abc04e15c9d9415cfcc75833cb Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Tue, 21 Jun 2016 10:25:08 +1000 Subject: [PATCH 103/112] MDEV-9479: Enable OQGRAPH Engine to compile with Boost-1.60+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This used to be a compile failure. The defined structure isn't required in the later versions of boost. Signed-off-by: VicenÈ›iu Ciorbaru --- storage/oqgraph/oqgraph_shim.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/oqgraph/oqgraph_shim.h b/storage/oqgraph/oqgraph_shim.h index 6ea9d10631f39..af240b88ebdcb 100644 --- a/storage/oqgraph/oqgraph_shim.h +++ b/storage/oqgraph/oqgraph_shim.h @@ -254,7 +254,7 @@ namespace boost typedef no_property type; }; -#if BOOST_VERSION >= 104601 +#if BOOST_VERSION < 106000 && BOOST_VERSION >= 104601 template <> struct graph_bundle_type { From e16780619630676f822248f3637972235481fd96 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 22 Jun 2016 15:31:58 +0200 Subject: [PATCH 104/112] compilation failures windows: use GetProcAddress() to access internal server data structures rhel5: CONNECT-JDBC requires at least Java 1.6 --- plugin/metadata_lock_info/metadata_lock_info.cc | 14 +++++++++++--- storage/connect/CMakeLists.txt | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index 72108f7bcb455..a7621cbda15a4 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -20,6 +20,8 @@ #include "sql_class.h" #include "sql_show.h" +I_List *thds; + static const LEX_STRING metadata_lock_info_lock_name[] = { { C_STRING_WITH_LEN("Global read lock") }, { C_STRING_WITH_LEN("Schema metadata lock") }, @@ -134,7 +136,7 @@ static THD *find_thread(my_thread_id id) THD *tmp; mysql_mutex_lock(&LOCK_thread_count); - I_List_iterator it(threads); + I_List_iterator it(*thds); while ((tmp= it++)) { if (id == tmp->thread_id) @@ -160,7 +162,7 @@ static int i_s_metadata_lock_info_fill_table(THD *thd, TABLE_LIST *tables, /* Gather thread identifiers */ my_init_dynamic_array(&ids, sizeof(my_thread_id), 512, 1, MYF(0)); mysql_mutex_lock(&LOCK_thread_count); - I_List_iterator it(threads); + I_List_iterator it(*thds); while ((tmp= it++)) if (tmp != thd && (info.error= insert_dynamic(&ids, &tmp->thread_id))) break; @@ -186,10 +188,16 @@ static int i_s_metadata_lock_info_init( ) { ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; DBUG_ENTER("i_s_metadata_lock_info_init"); +#ifdef _WIN32 + thds = (I_List*) + GetProcAddress(GetModuleHandle(NULL), "?threads@@3V?$I_List@VTHD@@@@A"); +#else + thds = &threads; +#endif schema->fields_info = i_s_metadata_lock_info_fields_info; schema->fill_table = i_s_metadata_lock_info_fill_table; schema->idx_field1 = 0; - DBUG_RETURN(0); + DBUG_RETURN(thds == 0); } static int i_s_metadata_lock_info_deinit( diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index 254d074612a1f..c6b808acc600f 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -243,8 +243,8 @@ IF(CONNECT_WITH_JDBC) # TODO: Find how to compile and install the java wrapper class # Find required libraries and include directories - FIND_PACKAGE(Java) - FIND_PACKAGE(JNI) + FIND_PACKAGE(Java 1.6) + FIND_PACKAGE(JNI) IF (JAVA_FOUND AND JNI_FOUND) INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH}) INCLUDE_DIRECTORIES(${JAVA_INCLUDE_PATH2}) From ef92aaf9ece92c873ae0f3448ab2274c958ba3fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 22 Jun 2016 22:37:28 +0300 Subject: [PATCH 105/112] MDEV-10083: Orphan ibd file when playing with foreign keys Analysis: row_drop_table_for_mysql did not allow dropping referenced table even in case when actual creating of the referenced table was not successfull if foreign_key_checks=1. Fix: Allow dropping referenced table even if foreign_key_checks=1 if actual table create returned error. --- .../suite/innodb/r/innodb-fkcheck.result | 87 +++++++++++++ mysql-test/suite/innodb/t/innodb-fkcheck.test | 115 ++++++++++++++++++ storage/innobase/dict/dict0crea.c | 8 +- storage/innobase/handler/ha_innodb.cc | 3 +- storage/innobase/include/row0mysql.h | 5 +- storage/innobase/row/row0merge.c | 2 +- storage/innobase/row/row0mysql.c | 23 ++-- storage/innobase/trx/trx0roll.c | 2 +- storage/xtradb/dict/dict0crea.c | 8 +- storage/xtradb/handler/ha_innodb.cc | 4 +- storage/xtradb/include/row0mysql.h | 5 +- storage/xtradb/row/row0merge.c | 2 +- storage/xtradb/row/row0mysql.c | 23 ++-- storage/xtradb/trx/trx0roll.c | 2 +- 14 files changed, 257 insertions(+), 32 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-fkcheck.result create mode 100644 mysql-test/suite/innodb/t/innodb-fkcheck.test diff --git a/mysql-test/suite/innodb/r/innodb-fkcheck.result b/mysql-test/suite/innodb/r/innodb-fkcheck.result new file mode 100644 index 0000000000000..a6bbcc9024eb9 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-fkcheck.result @@ -0,0 +1,87 @@ +set global innodb_file_per_table = 1; +drop table if exists b; +drop database if exists bug_fk; +create database bug_fk; +use bug_fk; +CREATE TABLE b ( +b int unsigned NOT NULL, +d1 datetime NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +CREATE TABLE c ( +b int unsigned NOT NULL, +d1 datetime NOT NULL, +d2 datetime NOT NULL, +PRIMARY KEY (b,d1), +CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; +show warnings; +Level Code Message +set foreign_key_checks = 0; +DROP TABLE IF EXISTS b; +show create table c; +Table Create Table +c CREATE TABLE `c` ( + `b` int(10) unsigned NOT NULL, + `d1` datetime NOT NULL, + `d2` datetime NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CREATE TABLE b ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +ERROR HY000: Can't create table 'bug_fk.b' (errno: 150) +show warnings; +Level Code Message +Error 1005 Can't create table 'bug_fk.b' (errno: 150) +DROP TABLE IF EXISTS d; +Warnings: +Note 1051 Unknown table 'd' +CREATE TABLE d ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1), +CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; +show warnings; +Level Code Message +set foreign_key_checks = 1; +show create table c; +Table Create Table +c CREATE TABLE `c` ( + `b` int(10) unsigned NOT NULL, + `d1` datetime NOT NULL, + `d2` datetime NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table d; +Table Create Table +d CREATE TABLE `d` ( + `b` bigint(20) unsigned NOT NULL, + `d1` date NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `bd_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CREATE TABLE b ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +ERROR HY000: Can't create table 'bug_fk.b' (errno: 150) +show warnings; +Level Code Message +Error 1005 Can't create table 'bug_fk.b' (errno: 150) +set foreign_key_checks=0; +drop table c; +drop table d; +create table b(id int) engine=innodb; +show warnings; +Level Code Message +b.frm +b.ibd +drop table if exists b; +drop database if exists bug_fk; diff --git a/mysql-test/suite/innodb/t/innodb-fkcheck.test b/mysql-test/suite/innodb/t/innodb-fkcheck.test new file mode 100644 index 0000000000000..51e36ae6984dc --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-fkcheck.test @@ -0,0 +1,115 @@ +--source include/have_innodb.inc + +# +# MDEV-10083: Orphan ibd file when playing with foreign keys +# +--disable_query_log +SET @start_global_fpt = @@global.innodb_file_per_table; +SET @start_global_fkc = @@global.foreign_key_checks; +--enable_query_log + +set global innodb_file_per_table = 1; + +--disable_warnings +drop table if exists b; +drop database if exists bug_fk; +--enable_warnings + +let $MYSQLD_DATADIR = `select @@datadir`; + +create database bug_fk; +use bug_fk; + +CREATE TABLE b ( + b int unsigned NOT NULL, + d1 datetime NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +CREATE TABLE c ( + b int unsigned NOT NULL, + d1 datetime NOT NULL, + d2 datetime NOT NULL, + PRIMARY KEY (b,d1), + CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; + +show warnings; + +set foreign_key_checks = 0; + +DROP TABLE IF EXISTS b; + +show create table c; + +# +# Note that column b has different type in parent table +# +--error 1005 +CREATE TABLE b ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +show warnings; + +DROP TABLE IF EXISTS d; + +CREATE TABLE d ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1), + CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; + +show warnings; + +set foreign_key_checks = 1; + +show create table c; +show create table d; + +# +# Table c column b used on foreign key has different type +# compared referenced column b in table b, but this +# create still produced b.ibd file. This is because +# we row_drop_table_for_mysql was called and referenced +# table is not allowed to be dropped even in case +# when actual create is not successfull. +# +--error 1005 +CREATE TABLE b ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +show warnings; + +--list_files $MYSQLD_DATADIR/bug_fk b* + +set foreign_key_checks=0; + +drop table c; +drop table d; + +--list_files $MYSQLD_DATADIR/bug_fk b* + +create table b(id int) engine=innodb; +show warnings; + +--list_files $MYSQLD_DATADIR/bug_fk b* + +# +# Cleanup +# +--disable_query_log +SET @@global.innodb_file_per_table = @start_global_fpt; +SET @@global.foreign_key_checks = @start_global_fkc; +--enable_query_log + +--disable_warnings +drop table if exists b; +drop database if exists bug_fk; +--enable_warnings diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index 8102f5701759a..f8bcc6f2d5f1e 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -1242,14 +1242,14 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN table\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); } if (table2) { fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN_COLS table\n"); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); } fprintf(stderr, @@ -1298,8 +1298,8 @@ dict_create_or_check_foreign_constraint_tables(void) "InnoDB: dropping incompletely created" " SYS_FOREIGN tables\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); error = DB_MUST_GET_MORE_FILE_SPACE; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 734dbe1cafd69..780f3a6f82fe1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7644,7 +7644,8 @@ ha_innobase::delete_table( error = row_drop_table_for_mysql(norm_name, trx, thd_sql_command(thd) - == SQLCOM_DROP_DB); + == SQLCOM_DROP_DB, + FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 7abb0b67fffac..0f66644d906f7 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -454,7 +454,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db);/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed);/*!n_mysql_handles_opened == 0); - return(row_drop_table_for_mysql(table->name, trx, FALSE)); + return(row_drop_table_for_mysql(table->name, trx, FALSE, FALSE)); } /*********************************************************************//** diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 1a11e39895977..6206bef6b56e6 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1987,7 +1987,7 @@ row_create_table_for_mysql( if (dict_table_get_low(table->name, DICT_ERR_IGNORE_NONE)) { - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); } else { dict_mem_table_free(table); @@ -2117,7 +2117,7 @@ row_create_index_for_mysql( trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2187,7 +2187,7 @@ row_table_add_foreign_constraints( trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(name, trx, FALSE); + row_drop_table_for_mysql(name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2228,7 +2228,7 @@ row_drop_table_for_mysql_in_background( /* Try to drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx, FALSE, FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3078,7 +3078,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db)/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed) /*!check_foreigns + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign && trx->check_foreigns && !create_failed && !(drop_db && dict_tables_have_same_db( name, foreign->foreign_table_name_lookup))) { FILE* ef = dict_foreign_err_file; @@ -3578,7 +3585,7 @@ row_mysql_drop_temp_tables(void) table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE); if (table) { - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, FALSE); trx_commit_for_mysql(trx); } @@ -3708,7 +3715,7 @@ row_drop_database_for_mysql( goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); if (err != DB_SUCCESS) { diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index ffd7bb3d14696..877a478e50ae7 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -504,7 +504,7 @@ trx_rollback_active( ut_print_name(stderr, trx, TRUE, table->name); fputs(" in recovery\n", stderr); - err = row_drop_table_for_mysql(table->name, trx, TRUE); + err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); ut_a(err == (int) DB_SUCCESS); diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index a77acf8b57713..b44fdc1d2e473 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1444,14 +1444,14 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN table\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); } if (table2) { fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN_COLS table\n"); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); } fprintf(stderr, @@ -1500,8 +1500,8 @@ dict_create_or_check_foreign_constraint_tables(void) "InnoDB: dropping incompletely created" " SYS_FOREIGN tables\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); error = DB_MUST_GET_MORE_FILE_SPACE; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 8148c3e1dd50a..d5da3825ef0c0 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -8773,7 +8773,8 @@ ha_innobase::delete_table( error = row_drop_table_for_mysql(norm_name, trx, thd_sql_command(thd) - == SQLCOM_DROP_DB); + == SQLCOM_DROP_DB, + FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -8858,6 +8859,7 @@ innobase_drop_database( trx_free_for_mysql(trx); return; /* ignore */ } + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf); diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index 35378bf3302c5..e228289bdae37 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -470,7 +470,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db);/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed);/*!n_mysql_handles_opened == 0); - return(row_drop_table_for_mysql(table->name, trx, FALSE)); + return(row_drop_table_for_mysql(table->name, trx, FALSE, FALSE)); } /*********************************************************************//** diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index e6ccf44b884db..0182752132a39 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -2013,7 +2013,7 @@ row_create_table_for_mysql( if (dict_table_get_low(table->name, DICT_ERR_IGNORE_NONE)) { - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); } else { dict_mem_table_free(table); @@ -2143,7 +2143,7 @@ row_create_index_for_mysql( trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2278,7 +2278,7 @@ row_table_add_foreign_constraints( trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(name, trx, FALSE); + row_drop_table_for_mysql(name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2319,7 +2319,7 @@ row_drop_table_for_mysql_in_background( /* Try to drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx, FALSE, FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3216,7 +3216,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db)/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed) /*!check_foreigns + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign && trx->check_foreigns && !create_failed && !(drop_db && dict_tables_have_same_db( name, foreign->foreign_table_name_lookup))) { FILE* ef = dict_foreign_err_file; @@ -3718,7 +3725,7 @@ row_mysql_drop_temp_tables(void) table = dict_table_get_low(table_name, DICT_ERR_IGNORE_ALL); if (table) { - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, FALSE); trx_commit_for_mysql(trx); } @@ -3848,7 +3855,7 @@ row_drop_database_for_mysql( goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c index 25c1d5d469268..236eb88e7a43d 100644 --- a/storage/xtradb/trx/trx0roll.c +++ b/storage/xtradb/trx/trx0roll.c @@ -504,7 +504,7 @@ trx_rollback_active( ut_print_name(stderr, trx, TRUE, table->name); fputs(" in recovery\n", stderr); - err = row_drop_table_for_mysql(table->name, trx, TRUE); + err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); ut_a(err == (int) DB_SUCCESS); From 26de9061e8c4462152b4bcff2b9cbb80cde12de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 23 Jun 2016 07:42:40 +0300 Subject: [PATCH 106/112] Merge following commit from 5.5: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit ef92aaf9ece92c873ae0f3448ab2274c958ba3fe Author: Jan Lindström Date: Wed Jun 22 22:37:28 2016 +0300 MDEV-10083: Orphan ibd file when playing with foreign keys Analysis: row_drop_table_for_mysql did not allow dropping referenced table even in case when actual creating of the referenced table was not successfull if foreign_key_checks=1. Fix: Allow dropping referenced table even if foreign_key_checks=1 if actual table create returned error. --- .../suite/innodb/r/innodb-fkcheck.result | 89 ++++++++++++++ mysql-test/suite/innodb/t/innodb-fkcheck.test | 115 ++++++++++++++++++ storage/innobase/dict/dict0crea.cc | 16 +-- storage/innobase/fts/fts0fts.cc | 4 +- storage/innobase/handler/ha_innodb.cc | 6 +- storage/innobase/include/row0mysql.h | 3 + storage/innobase/row/row0merge.cc | 2 +- storage/innobase/row/row0mysql.cc | 22 ++-- storage/innobase/trx/trx0roll.cc | 2 +- storage/xtradb/dict/dict0crea.cc | 16 +-- storage/xtradb/fts/fts0fts.cc | 4 +- storage/xtradb/handler/ha_innodb.cc | 6 +- storage/xtradb/include/row0mysql.h | 3 + storage/xtradb/row/row0merge.cc | 2 +- storage/xtradb/row/row0mysql.cc | 22 ++-- storage/xtradb/trx/trx0roll.cc | 2 +- 16 files changed, 272 insertions(+), 42 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-fkcheck.result create mode 100644 mysql-test/suite/innodb/t/innodb-fkcheck.test diff --git a/mysql-test/suite/innodb/r/innodb-fkcheck.result b/mysql-test/suite/innodb/r/innodb-fkcheck.result new file mode 100644 index 0000000000000..c6beabb0f5051 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-fkcheck.result @@ -0,0 +1,89 @@ +set global innodb_file_per_table = 1; +drop table if exists b; +drop database if exists bug_fk; +create database bug_fk; +use bug_fk; +CREATE TABLE b ( +b int unsigned NOT NULL, +d1 datetime NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +CREATE TABLE c ( +b int unsigned NOT NULL, +d1 datetime NOT NULL, +d2 datetime NOT NULL, +PRIMARY KEY (b,d1), +CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; +show warnings; +Level Code Message +set foreign_key_checks = 0; +DROP TABLE IF EXISTS b; +show create table c; +Table Create Table +c CREATE TABLE `c` ( + `b` int(10) unsigned NOT NULL, + `d1` datetime NOT NULL, + `d2` datetime NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CREATE TABLE b ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") +show warnings; +Level Code Message +Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") +Warning 1215 Cannot add foreign key constraint +DROP TABLE IF EXISTS d; +Warnings: +Note 1051 Unknown table 'bug_fk.d' +CREATE TABLE d ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1), +CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; +show warnings; +Level Code Message +set foreign_key_checks = 1; +show create table c; +Table Create Table +c CREATE TABLE `c` ( + `b` int(10) unsigned NOT NULL, + `d1` datetime NOT NULL, + `d2` datetime NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `b_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table d; +Table Create Table +d CREATE TABLE `d` ( + `b` bigint(20) unsigned NOT NULL, + `d1` date NOT NULL, + PRIMARY KEY (`b`,`d1`), + CONSTRAINT `bd_fk` FOREIGN KEY (`b`) REFERENCES `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CREATE TABLE b ( +b bigint unsigned NOT NULL, +d1 date NOT NULL, +PRIMARY KEY (b,d1) +) ENGINE=InnoDB; +ERROR HY000: Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") +show warnings; +Level Code Message +Error 1005 Can't create table `bug_fk`.`b` (errno: 150 "Foreign key constraint is incorrectly formed") +Warning 1215 Cannot add foreign key constraint +set foreign_key_checks=0; +drop table c; +drop table d; +create table b(id int) engine=innodb; +show warnings; +Level Code Message +b.frm +b.ibd +drop table if exists b; +drop database if exists bug_fk; diff --git a/mysql-test/suite/innodb/t/innodb-fkcheck.test b/mysql-test/suite/innodb/t/innodb-fkcheck.test new file mode 100644 index 0000000000000..51e36ae6984dc --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-fkcheck.test @@ -0,0 +1,115 @@ +--source include/have_innodb.inc + +# +# MDEV-10083: Orphan ibd file when playing with foreign keys +# +--disable_query_log +SET @start_global_fpt = @@global.innodb_file_per_table; +SET @start_global_fkc = @@global.foreign_key_checks; +--enable_query_log + +set global innodb_file_per_table = 1; + +--disable_warnings +drop table if exists b; +drop database if exists bug_fk; +--enable_warnings + +let $MYSQLD_DATADIR = `select @@datadir`; + +create database bug_fk; +use bug_fk; + +CREATE TABLE b ( + b int unsigned NOT NULL, + d1 datetime NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +CREATE TABLE c ( + b int unsigned NOT NULL, + d1 datetime NOT NULL, + d2 datetime NOT NULL, + PRIMARY KEY (b,d1), + CONSTRAINT b_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; + +show warnings; + +set foreign_key_checks = 0; + +DROP TABLE IF EXISTS b; + +show create table c; + +# +# Note that column b has different type in parent table +# +--error 1005 +CREATE TABLE b ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +show warnings; + +DROP TABLE IF EXISTS d; + +CREATE TABLE d ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1), + CONSTRAINT bd_fk FOREIGN KEY (b) REFERENCES b (b) +) ENGINE=InnoDB; + +show warnings; + +set foreign_key_checks = 1; + +show create table c; +show create table d; + +# +# Table c column b used on foreign key has different type +# compared referenced column b in table b, but this +# create still produced b.ibd file. This is because +# we row_drop_table_for_mysql was called and referenced +# table is not allowed to be dropped even in case +# when actual create is not successfull. +# +--error 1005 +CREATE TABLE b ( + b bigint unsigned NOT NULL, + d1 date NOT NULL, + PRIMARY KEY (b,d1) +) ENGINE=InnoDB; + +show warnings; + +--list_files $MYSQLD_DATADIR/bug_fk b* + +set foreign_key_checks=0; + +drop table c; +drop table d; + +--list_files $MYSQLD_DATADIR/bug_fk b* + +create table b(id int) engine=innodb; +show warnings; + +--list_files $MYSQLD_DATADIR/bug_fk b* + +# +# Cleanup +# +--disable_query_log +SET @@global.innodb_file_per_table = @start_global_fpt; +SET @@global.foreign_key_checks = @start_global_fkc; +--enable_query_log + +--disable_warnings +drop table if exists b; +drop database if exists bug_fk; +--enable_warnings diff --git a/storage/innobase/dict/dict0crea.cc b/storage/innobase/dict/dict0crea.cc index 2706ed9be4da0..3c140dbb07e7c 100644 --- a/storage/innobase/dict/dict0crea.cc +++ b/storage/innobase/dict/dict0crea.cc @@ -1365,7 +1365,7 @@ dict_create_or_check_foreign_constraint_tables(void) ib_logf(IB_LOG_LEVEL_WARN, "Dropping incompletely created " "SYS_FOREIGN table."); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); } if (sys_foreign_cols_err == DB_CORRUPTION) { @@ -1373,7 +1373,7 @@ dict_create_or_check_foreign_constraint_tables(void) "Dropping incompletely created " "SYS_FOREIGN_COLS table."); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); } ib_logf(IB_LOG_LEVEL_WARN, @@ -1427,8 +1427,8 @@ dict_create_or_check_foreign_constraint_tables(void) ut_ad(err == DB_OUT_OF_FILE_SPACE || err == DB_TOO_MANY_CONCURRENT_TRXS); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); if (err == DB_OUT_OF_FILE_SPACE) { err = DB_MUST_GET_MORE_FILE_SPACE; @@ -1853,7 +1853,7 @@ dict_create_or_check_sys_tablespace(void) ib_logf(IB_LOG_LEVEL_WARN, "Dropping incompletely created " "SYS_TABLESPACES table."); - row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE); + row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE, TRUE); } if (sys_datafiles_err == DB_CORRUPTION) { @@ -1861,7 +1861,7 @@ dict_create_or_check_sys_tablespace(void) "Dropping incompletely created " "SYS_DATAFILES table."); - row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE); + row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE, TRUE); } ib_logf(IB_LOG_LEVEL_INFO, @@ -1897,8 +1897,8 @@ dict_create_or_check_sys_tablespace(void) ut_a(err == DB_OUT_OF_FILE_SPACE || err == DB_TOO_MANY_CONCURRENT_TRXS); - row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE); - row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE); + row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE, TRUE); if (err == DB_OUT_OF_FILE_SPACE) { err = DB_MUST_GET_MORE_FILE_SPACE; diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 2eac5dcac861d..99865f20f684b 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1918,7 +1918,7 @@ fts_create_common_tables( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); trx->error_state = DB_SUCCESS; } @@ -2070,7 +2070,7 @@ fts_create_index_tables_low( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx->error_state = DB_SUCCESS; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 06fd6591d8986..9d976d685ed2c 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10686,7 +10686,8 @@ ha_innobase::delete_table( /* Drop the table in InnoDB */ err = row_drop_table_for_mysql( - norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB); + norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB, + FALSE); if (err == DB_TABLE_NOT_FOUND @@ -10717,7 +10718,8 @@ ha_innobase::delete_table( #endif err = row_drop_table_for_mysql( par_case_name, trx, - thd_sql_command(thd) == SQLCOM_DROP_DB); + thd_sql_command(thd) == SQLCOM_DROP_DB, + FALSE); } } diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index fc1846b76f312..f5f159fc41414 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -488,6 +488,9 @@ row_drop_table_for_mysql( const char* name, /*!< in: table name */ trx_t* trx, /*!< in: dictionary transaction handle */ bool drop_db,/*!< in: true=dropping whole database */ + ibool create_failed,/*!n_ref_count == 0); - return(row_drop_table_for_mysql(table->name, trx, false, false)); + return(row_drop_table_for_mysql(table->name, trx, false, false, false)); } /*********************************************************************//** diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 4c3fa5364b79f..122c03b7cc9fe 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2391,7 +2391,7 @@ row_create_table_for_mysql( dict_table_close(table, TRUE, FALSE); - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); if (commit) { trx_commit_for_mysql(trx); @@ -2551,7 +2551,7 @@ row_create_index_for_mysql( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2628,7 +2628,7 @@ row_table_add_foreign_constraints( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(name, trx, FALSE); + row_drop_table_for_mysql(name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2669,7 +2669,7 @@ row_drop_table_for_mysql_in_background( /* Try to drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx, FALSE, FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3767,6 +3767,9 @@ row_drop_table_for_mysql( const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ bool drop_db,/*!< in: true=dropping whole database */ + ibool create_failed,/*!foreign_table_name_lookup); - if (foreign->foreign_table != table && !ref_ok) { + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign->foreign_table != table && + !create_failed && !ref_ok) { FILE* ef = dict_foreign_err_file; @@ -4497,7 +4505,7 @@ row_mysql_drop_temp_tables(void) table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE); if (table) { - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, FALSE); trx_commit_for_mysql(trx); } @@ -4666,7 +4674,7 @@ row_drop_database_for_mysql( goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); if (err != DB_SUCCESS) { diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 95cab752c3260..c65d95a9817f7 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -641,7 +641,7 @@ trx_rollback_active( "in recovery", table->name, trx->table_id); - err = row_drop_table_for_mysql(table->name, trx, TRUE); + err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); ut_a(err == DB_SUCCESS); diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc index 37ebdbae54adf..b0a3263d097c4 100644 --- a/storage/xtradb/dict/dict0crea.cc +++ b/storage/xtradb/dict/dict0crea.cc @@ -1365,7 +1365,7 @@ dict_create_or_check_foreign_constraint_tables(void) ib_logf(IB_LOG_LEVEL_WARN, "Dropping incompletely created " "SYS_FOREIGN table."); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); } if (sys_foreign_cols_err == DB_CORRUPTION) { @@ -1373,7 +1373,7 @@ dict_create_or_check_foreign_constraint_tables(void) "Dropping incompletely created " "SYS_FOREIGN_COLS table."); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); } ib_logf(IB_LOG_LEVEL_WARN, @@ -1427,8 +1427,8 @@ dict_create_or_check_foreign_constraint_tables(void) ut_ad(err == DB_OUT_OF_FILE_SPACE || err == DB_TOO_MANY_CONCURRENT_TRXS); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); if (err == DB_OUT_OF_FILE_SPACE) { err = DB_MUST_GET_MORE_FILE_SPACE; @@ -1852,7 +1852,7 @@ dict_create_or_check_sys_tablespace(void) ib_logf(IB_LOG_LEVEL_WARN, "Dropping incompletely created " "SYS_TABLESPACES table."); - row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE); + row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE, TRUE); } if (sys_datafiles_err == DB_CORRUPTION) { @@ -1860,7 +1860,7 @@ dict_create_or_check_sys_tablespace(void) "Dropping incompletely created " "SYS_DATAFILES table."); - row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE); + row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE, TRUE); } ib_logf(IB_LOG_LEVEL_INFO, @@ -1896,8 +1896,8 @@ dict_create_or_check_sys_tablespace(void) ut_a(err == DB_OUT_OF_FILE_SPACE || err == DB_TOO_MANY_CONCURRENT_TRXS); - row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE); - row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE); + row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE, TRUE); if (err == DB_OUT_OF_FILE_SPACE) { err = DB_MUST_GET_MORE_FILE_SPACE; diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index fe97b9f7e1a57..695e1d25dbe42 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -1919,7 +1919,7 @@ fts_create_common_tables( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); trx->error_state = DB_SUCCESS; } @@ -2071,7 +2071,7 @@ fts_create_index_tables_low( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx->error_state = DB_SUCCESS; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 0bedadc63d961..82e44fe5af07b 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -11470,7 +11470,8 @@ ha_innobase::delete_table( /* Drop the table in InnoDB */ err = row_drop_table_for_mysql( - norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB); + norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB, + FALSE); if (err == DB_TABLE_NOT_FOUND @@ -11501,7 +11502,8 @@ ha_innobase::delete_table( #endif err = row_drop_table_for_mysql( par_case_name, trx, - thd_sql_command(thd) == SQLCOM_DROP_DB); + thd_sql_command(thd) == SQLCOM_DROP_DB, + FALSE); } } diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index 027d76317c426..a2f2a2e7371e6 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -488,6 +488,9 @@ row_drop_table_for_mysql( const char* name, /*!< in: table name */ trx_t* trx, /*!< in: dictionary transaction handle */ bool drop_db,/*!< in: true=dropping whole database */ + ibool create_failed,/*!n_ref_count == 0); - return(row_drop_table_for_mysql(table->name, trx, false, false)); + return(row_drop_table_for_mysql(table->name, trx, false, false, false)); } /*********************************************************************//** diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 999bfbd401ee1..446237078c221 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -2400,7 +2400,7 @@ row_create_table_for_mysql( dict_table_close(table, TRUE, FALSE); - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); if (commit) { trx_commit_for_mysql(trx); @@ -2560,7 +2560,7 @@ row_create_index_for_mysql( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2637,7 +2637,7 @@ row_table_add_foreign_constraints( trx_rollback_to_savepoint(trx, NULL); - row_drop_table_for_mysql(name, trx, FALSE); + row_drop_table_for_mysql(name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2678,7 +2678,7 @@ row_drop_table_for_mysql_in_background( /* Try to drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx, FALSE, FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3776,6 +3776,9 @@ row_drop_table_for_mysql( const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ bool drop_db,/*!< in: true=dropping whole database */ + ibool create_failed,/*!foreign_table_name_lookup); - if (foreign->foreign_table != table && !ref_ok) { + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign->foreign_table != table && + !create_failed && !ref_ok) { FILE* ef = dict_foreign_err_file; @@ -4507,7 +4515,7 @@ row_mysql_drop_temp_tables(void) table = dict_table_get_low(table_name); if (table) { - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, FALSE); trx_commit_for_mysql(trx); } @@ -4676,7 +4684,7 @@ row_drop_database_for_mysql( goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index e2c3c0b949ca7..0243507ddfb14 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -641,7 +641,7 @@ trx_rollback_active( "in recovery", table->name, trx->table_id); - err = row_drop_table_for_mysql(table->name, trx, TRUE); + err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); ut_a(err == DB_SUCCESS); From 4abeebeed78a962e5dd10ff53b53ffd4e8699700 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 23 Jun 2016 12:06:16 +0400 Subject: [PATCH 107/112] MDEV-9728 - Hard crash in metadata_lock_info Reverted APC based fix. APC subsystem is not ready to serve metadata_lock_info needs. --- .../metadata_lock_info/metadata_lock_info.cc | 167 ++++++------------ sql/mdl.h | 2 +- 2 files changed, 54 insertions(+), 115 deletions(-) diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index a7621cbda15a4..fcfdb59da3056 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -20,8 +20,6 @@ #include "sql_class.h" #include "sql_show.h" -I_List *thds; - static const LEX_STRING metadata_lock_info_lock_name[] = { { C_STRING_WITH_LEN("Global read lock") }, { C_STRING_WITH_LEN("Schema metadata lock") }, @@ -69,118 +67,65 @@ static ST_FIELD_INFO i_s_metadata_lock_info_fields_info[] = {NULL, 0, MYSQL_TYPE_STRING, 0, 0, NULL, 0} }; - -class Ticket_info: public Apc_target::Apc_call +struct st_i_s_metadata_param { -public: - bool timed_out; - THD *request_thd; - THD *target_thd; + THD *thd; TABLE *table; - int error; - - Ticket_info(THD *request_thd_arg, TABLE *table_arg): - request_thd(request_thd_arg), table(table_arg), error(0) - { } - - void call_in_target_thread() - { - MDL_ticket *ticket; - int i; - - for (i= 0; i < MDL_DURATION_END; i++) - { - MDL_context::Ticket_iterator it(request_thd->mdl_context.m_tickets[i]); - while ((ticket= it++)) - { - MDL_key *key= ticket->get_key(); - - table->field[0]->store((longlong) target_thd->thread_id, TRUE); - - table->field[1]->set_notnull(); - table->field[1]->store( - metadata_lock_info_lock_mode[(int) ticket->get_type()].str, - metadata_lock_info_lock_mode[(int) ticket->get_type()].length, - system_charset_info); - - table->field[2]->set_notnull(); - table->field[2]->store( - metadata_lock_info_duration[i].str, - metadata_lock_info_duration[i].length, - system_charset_info); - - table->field[3]->set_notnull(); - table->field[3]->store( - metadata_lock_info_lock_name[(int) key->mdl_namespace()].str, - metadata_lock_info_lock_name[(int) key->mdl_namespace()].length, - system_charset_info); - - table->field[4]->set_notnull(); - table->field[4]->store(key->db_name(), key->db_name_length(), - system_charset_info); - - table->field[5]->set_notnull(); - table->field[5]->store(key->name(), key->name_length(), - system_charset_info); - - if ((error= schema_table_store_record(request_thd, table))) - return; - } - } - } }; - -static THD *find_thread(my_thread_id id) -{ - THD *tmp; - - mysql_mutex_lock(&LOCK_thread_count); - I_List_iterator it(*thds); - while ((tmp= it++)) - { - if (id == tmp->thread_id) - { - mysql_mutex_lock(&tmp->LOCK_thd_data); - break; - } - } - mysql_mutex_unlock(&LOCK_thread_count); - return tmp; +int i_s_metadata_lock_info_fill_row( + MDL_ticket *mdl_ticket, + void *arg +) { + st_i_s_metadata_param *param = (st_i_s_metadata_param *) arg; + THD *thd = param->thd; + TABLE *table = param->table; + DBUG_ENTER("i_s_metadata_lock_info_fill_row"); + MDL_request mdl_request; + enum_mdl_duration mdl_duration; + MDL_context *mdl_ctx = mdl_ticket->get_ctx(); + enum_mdl_type mdl_ticket_type = mdl_ticket->get_type(); + MDL_key *mdl_key = mdl_ticket->get_key(); + MDL_key::enum_mdl_namespace mdl_namespace = mdl_key->mdl_namespace(); + mdl_request.init(mdl_key, mdl_ticket_type, MDL_STATEMENT); + mdl_ctx->find_ticket(&mdl_request, &mdl_duration); + table->field[0]->store((longlong) mdl_ctx->get_thread_id(), TRUE); + table->field[1]->set_notnull(); + table->field[1]->store( + metadata_lock_info_lock_mode[(int) mdl_ticket_type].str, + metadata_lock_info_lock_mode[(int) mdl_ticket_type].length, + system_charset_info); + table->field[2]->set_notnull(); + table->field[2]->store( + metadata_lock_info_duration[(int) mdl_duration].str, + metadata_lock_info_duration[(int) mdl_duration].length, + system_charset_info); + table->field[3]->set_notnull(); + table->field[3]->store( + metadata_lock_info_lock_name[(int) mdl_namespace].str, + metadata_lock_info_lock_name[(int) mdl_namespace].length, + system_charset_info); + table->field[4]->set_notnull(); + table->field[4]->store(mdl_key->db_name(), + mdl_key->db_name_length(), system_charset_info); + table->field[5]->set_notnull(); + table->field[5]->store(mdl_key->name(), + mdl_key->name_length(), system_charset_info); + if (schema_table_store_record(thd, table)) + DBUG_RETURN(1); + DBUG_RETURN(0); } - -static int i_s_metadata_lock_info_fill_table(THD *thd, TABLE_LIST *tables, - COND *cond) -{ - Ticket_info info(thd, tables->table); - DYNAMIC_ARRAY ids; - THD *tmp; - uint i; +int i_s_metadata_lock_info_fill_table( + THD *thd, + TABLE_LIST *tables, + COND *cond +) { + st_i_s_metadata_param param; DBUG_ENTER("i_s_metadata_lock_info_fill_table"); - - /* Gather thread identifiers */ - my_init_dynamic_array(&ids, sizeof(my_thread_id), 512, 1, MYF(0)); - mysql_mutex_lock(&LOCK_thread_count); - I_List_iterator it(*thds); - while ((tmp= it++)) - if (tmp != thd && (info.error= insert_dynamic(&ids, &tmp->thread_id))) - break; - mysql_mutex_unlock(&LOCK_thread_count); - - /* Let foreign threads fill info */ - for (i= 0; i < ids.elements && info.error == 0; i++) - if ((info.target_thd= find_thread(*dynamic_element(&ids, i, my_thread_id*)))) - info.target_thd->apc_target.make_apc_call(thd, &info, INT_MAX, - &info.timed_out); - - delete_dynamic(&ids); - if (info.error == 0) - { - info.target_thd= thd; - info.call_in_target_thread(); - } - DBUG_RETURN(info.error); + param.table = tables->table; + param.thd = thd; + DBUG_RETURN(mdl_iterate(i_s_metadata_lock_info_fill_row, ¶m)); } static int i_s_metadata_lock_info_init( @@ -188,16 +133,10 @@ static int i_s_metadata_lock_info_init( ) { ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p; DBUG_ENTER("i_s_metadata_lock_info_init"); -#ifdef _WIN32 - thds = (I_List*) - GetProcAddress(GetModuleHandle(NULL), "?threads@@3V?$I_List@VTHD@@@@A"); -#else - thds = &threads; -#endif schema->fields_info = i_s_metadata_lock_info_fields_info; schema->fill_table = i_s_metadata_lock_info_fill_table; schema->idx_field1 = 0; - DBUG_RETURN(thds == 0); + DBUG_RETURN(0); } static int i_s_metadata_lock_info_deinit( diff --git a/sql/mdl.h b/sql/mdl.h index ec7b633a67d9e..c4d792acd290e 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -953,7 +953,7 @@ class MDL_context MDL_context &operator=(MDL_context &rhs); /* not implemented */ /* metadata_lock_info plugin */ - friend class Ticket_info; + friend int i_s_metadata_lock_info_fill_row(MDL_ticket*, void*); }; From f289f3ee9c330bfa47f20c1016541cdd9dc8e354 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 23 Jun 2016 12:16:20 +0400 Subject: [PATCH 108/112] MDEV-9728 - Hard crash in metadata_lock_info Disable output of MDL lock duration since there is no facility to retreive it properly. --- mysql-test/r/create_or_replace.result | 68 +++++++++---------- .../metadata_lock_info/metadata_lock_info.cc | 10 +-- .../r/global_read_lock.result | 6 +- .../r/table_metadata_lock.result | 2 +- .../metadata_lock_info/r/user_lock.result | 2 +- .../t/global_read_lock.test | 3 +- 6 files changed, 42 insertions(+), 49 deletions(-) diff --git a/mysql-test/r/create_or_replace.result b/mysql-test/r/create_or_replace.result index a8348b8a5d07f..3a894e9fcb140 100644 --- a/mysql-test/r/create_or_replace.result +++ b/mysql-test/r/create_or_replace.result @@ -264,11 +264,11 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock mysqltest2 -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock mysqltest2 t2 -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 create or replace table test.t1; ERROR 42000: A table must have at least 1 column show tables; @@ -276,10 +276,10 @@ Tables_in_test t2 select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock mysqltest2 -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock mysqltest2 t2 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 create or replace table mysqltest2.t2; ERROR 42000: A table must have at least 1 column select * from information_schema.metadata_lock_info; @@ -291,11 +291,11 @@ create table mysqltest2.t2 like test.t1; lock table test.t1 write, mysqltest2.t2 write; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock mysqltest2 -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock mysqltest2 t2 -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a'; ERROR 42S21: Duplicate column name 'a' show tables; @@ -303,10 +303,10 @@ Tables_in_test t2 select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock mysqltest2 -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock mysqltest2 t2 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock mysqltest2 +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock mysqltest2 t2 create or replace table mysqltest2.t2 (a int) select 1 as 'a', 2 as 'a'; ERROR 42S21: Duplicate column name 'a' select * from information_schema.metadata_lock_info; @@ -400,31 +400,31 @@ create table t1 (a int); lock table t1 write, t2 read; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 -# MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 +# MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 (i int); select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 -# MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 +# MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 like t2; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 -# MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 +# MDL_SHARED_READ NULL Table metadata lock test t2 create or replace table t1 select 1 as f1; select * from information_schema.metadata_lock_info; THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Global read lock -# MDL_INTENTION_EXCLUSIVE MDL_EXPLICIT Schema metadata lock test -# MDL_SHARED_NO_READ_WRITE MDL_EXPLICIT Table metadata lock test t1 -# MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2 +# MDL_INTENTION_EXCLUSIVE NULL Global read lock +# MDL_INTENTION_EXCLUSIVE NULL Schema metadata lock test +# MDL_SHARED_NO_READ_WRITE NULL Table metadata lock test t1 +# MDL_SHARED_READ NULL Table metadata lock test t2 drop table t1; unlock tables; # diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index fcfdb59da3056..d434ed9a69371 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -81,25 +81,17 @@ int i_s_metadata_lock_info_fill_row( THD *thd = param->thd; TABLE *table = param->table; DBUG_ENTER("i_s_metadata_lock_info_fill_row"); - MDL_request mdl_request; - enum_mdl_duration mdl_duration; MDL_context *mdl_ctx = mdl_ticket->get_ctx(); enum_mdl_type mdl_ticket_type = mdl_ticket->get_type(); MDL_key *mdl_key = mdl_ticket->get_key(); MDL_key::enum_mdl_namespace mdl_namespace = mdl_key->mdl_namespace(); - mdl_request.init(mdl_key, mdl_ticket_type, MDL_STATEMENT); - mdl_ctx->find_ticket(&mdl_request, &mdl_duration); table->field[0]->store((longlong) mdl_ctx->get_thread_id(), TRUE); table->field[1]->set_notnull(); table->field[1]->store( metadata_lock_info_lock_mode[(int) mdl_ticket_type].str, metadata_lock_info_lock_mode[(int) mdl_ticket_type].length, system_charset_info); - table->field[2]->set_notnull(); - table->field[2]->store( - metadata_lock_info_duration[(int) mdl_duration].str, - metadata_lock_info_duration[(int) mdl_duration].length, - system_charset_info); + table->field[2]->set_null(); table->field[3]->set_notnull(); table->field[3]->store( metadata_lock_info_lock_name[(int) mdl_namespace].str, diff --git a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result index 61b0a913ca497..5803d7d129019 100644 --- a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result +++ b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/global_read_lock.result @@ -1,10 +1,10 @@ SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name FLUSH TABLES WITH READ LOCK; -SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info ORDER BY lock_type DESC; +SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name -MDL_SHARED MDL_EXPLICIT Global read lock -MDL_SHARED MDL_EXPLICIT Commit lock +MDL_SHARED NULL Commit lock +MDL_SHARED NULL Global read lock UNLOCK TABLES; SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name diff --git a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/table_metadata_lock.result b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/table_metadata_lock.result index 280c8284c5403..1b76b9e822272 100644 --- a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/table_metadata_lock.result +++ b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/table_metadata_lock.result @@ -6,7 +6,7 @@ SELECT * FROM t1; a SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name -MDL_SHARED_READ MDL_TRANSACTION Table metadata lock test t1 +MDL_SHARED_READ NULL Table metadata lock test t1 ROLLBACK; SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name diff --git a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/user_lock.result b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/user_lock.result index e1d690b566c4b..34d238cb43b25 100644 --- a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/user_lock.result +++ b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/r/user_lock.result @@ -5,7 +5,7 @@ GET_LOCK('LOCK1',0) 1 SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; lock_mode lock_duration lock_type table_schema table_name -MDL_SHARED_NO_WRITE MDL_EXPLICIT User lock LOCK1 +MDL_SHARED_NO_WRITE NULL User lock LOCK1 SELECT RELEASE_LOCK('LOCK1'); RELEASE_LOCK('LOCK1') 1 diff --git a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test index 74fa5e3e1fd3a..103050e3fb84e 100644 --- a/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test +++ b/plugin/metadata_lock_info/mysql-test/metadata_lock_info/t/global_read_lock.test @@ -1,5 +1,6 @@ SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; FLUSH TABLES WITH READ LOCK; -SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info ORDER BY lock_type DESC; +--sorted_result +SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; UNLOCK TABLES; SELECT lock_mode, lock_duration, lock_type, table_schema, table_name FROM information_schema.metadata_lock_info; From 9fc102b37ec45bf5a1010a9f660137304de482bc Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 23 Jun 2016 12:44:28 +0400 Subject: [PATCH 109/112] Fixed testcase check failure after db938.test --- storage/tokudb/mysql-test/tokudb_bugs/r/db938.result | 1 + storage/tokudb/mysql-test/tokudb_bugs/t/db938.test | 1 + 2 files changed, 2 insertions(+) diff --git a/storage/tokudb/mysql-test/tokudb_bugs/r/db938.result b/storage/tokudb/mysql-test/tokudb_bugs/r/db938.result index 6ec3a2c807943..779d458221bd1 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/r/db938.result +++ b/storage/tokudb/mysql-test/tokudb_bugs/r/db938.result @@ -32,3 +32,4 @@ set session tokudb_analyze_time = @orig_time; set global tokudb_cardinality_scale_percent = @orig_scale_percent; set session default_storage_engine = @orig_default_storage_engine; set global tokudb_debug_pause_background_job_manager = @orig_pause_background_job_manager; +set DEBUG_SYNC='reset'; diff --git a/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test b/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test index f1912faad0260..f56f93d1492c8 100644 --- a/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test +++ b/storage/tokudb/mysql-test/tokudb_bugs/t/db938.test @@ -74,3 +74,4 @@ set session tokudb_analyze_time = @orig_time; set global tokudb_cardinality_scale_percent = @orig_scale_percent; set session default_storage_engine = @orig_default_storage_engine; set global tokudb_debug_pause_background_job_manager = @orig_pause_background_job_manager; +set DEBUG_SYNC='reset'; From 79f852a069fb6ba5e18fd66ea2a24fa91c245c24 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 22 Jun 2016 14:17:06 +0200 Subject: [PATCH 110/112] MDEV-10050: Crash in subselect thd should not be taken earlier then fix_field and reset on fix_fields if it is needed. --- sql/item_subselect.cc | 58 ++++++++++++++++++++++++++----------------- sql/item_subselect.h | 34 +++++++++++-------------- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index ba6747437246d..690318c610a77 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -79,7 +79,6 @@ void Item_subselect::init(st_select_lex *select_lex, DBUG_PRINT("enter", ("select_lex: 0x%lx this: 0x%lx", (ulong) select_lex, (ulong) this)); unit= select_lex->master_unit(); - thd= unit->thd; if (unit->item) { @@ -90,7 +89,7 @@ void Item_subselect::init(st_select_lex *select_lex, engine= unit->item->engine; own_engine= FALSE; parsing_place= unit->item->parsing_place; - thd->change_item_tree((Item**)&unit->item, this); + unit->thd->change_item_tree((Item**)&unit->item, this); engine->change_result(this, result, TRUE); } else @@ -104,9 +103,9 @@ void Item_subselect::init(st_select_lex *select_lex, NO_MATTER : outer_select->parsing_place); if (unit->is_union()) - engine= new subselect_union_engine(thd, unit, result, this); + engine= new subselect_union_engine(unit, result, this); else - engine= new subselect_single_select_engine(thd, select_lex, result, this); + engine= new subselect_single_select_engine(select_lex, result, this); } { SELECT_LEX *upper= unit->outer_select(); @@ -220,6 +219,10 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) uint8 uncacheable; bool res; + thd= thd_param; + + DBUG_ASSERT(unit->thd == thd); + status_var_increment(thd_param->status_var.feature_subquery); DBUG_ASSERT(fixed == 0); @@ -242,7 +245,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref) return TRUE; - if (!(res= engine->prepare())) + if (!(res= engine->prepare(thd))) { // all transformation is done (used by prepared statements) changed= 1; @@ -2651,7 +2654,10 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref) { uint outer_cols_num; List *inner_cols; - char const *save_where= thd->where; + char const *save_where= thd_arg->where; + + thd= thd_arg; + DBUG_ASSERT(unit->thd == thd); if (test_strategy(SUBS_SEMI_JOIN)) return !( (*ref)= new Item_int(1)); @@ -2769,7 +2775,8 @@ bool Item_in_subselect::setup_mat_engine() if (!(mat_engine= new subselect_hash_sj_engine(thd, this, select_engine))) DBUG_RETURN(TRUE); - if (mat_engine->init(&select_engine->join->fields_list, + if (mat_engine->prepare(thd) || + mat_engine->init(&select_engine->join->fields_list, engine->get_identifier())) DBUG_RETURN(TRUE); @@ -2885,10 +2892,10 @@ void subselect_engine::set_thd(THD *thd_arg) subselect_single_select_engine:: -subselect_single_select_engine(THD *thd_arg, st_select_lex *select, +subselect_single_select_engine(st_select_lex *select, select_result_interceptor *result_arg, Item_subselect *item_arg) - :subselect_engine(thd_arg, item_arg, result_arg), + :subselect_engine(item_arg, result_arg), prepared(0), executed(0), select_lex(select), join(0) { @@ -2966,10 +2973,10 @@ void subselect_uniquesubquery_engine::cleanup() } -subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit *u, +subselect_union_engine::subselect_union_engine(st_select_lex_unit *u, select_result_interceptor *result_arg, Item_subselect *item_arg) - :subselect_engine(thd_arg, item_arg, result_arg) + :subselect_engine(item_arg, result_arg) { unit= u; unit->item= item_arg; @@ -3002,10 +3009,11 @@ subselect_union_engine::subselect_union_engine(THD *thd_arg, st_select_lex_unit @retval 1 if error */ -int subselect_single_select_engine::prepare() +int subselect_single_select_engine::prepare(THD *thd) { if (prepared) return 0; + set_thd(thd); if (select_lex->join) { select_lex->cleanup(); @@ -3034,12 +3042,13 @@ int subselect_single_select_engine::prepare() return 0; } -int subselect_union_engine::prepare() +int subselect_union_engine::prepare(THD *thd_arg) { + set_thd(thd_arg); return unit->prepare(thd, result, SELECT_NO_UNLOCK); } -int subselect_uniquesubquery_engine::prepare() +int subselect_uniquesubquery_engine::prepare(THD *) { /* Should never be called. */ DBUG_ASSERT(FALSE); @@ -4499,13 +4508,14 @@ subselect_hash_sj_engine::~subselect_hash_sj_engine() } -int subselect_hash_sj_engine::prepare() +int subselect_hash_sj_engine::prepare(THD *thd_arg) { /* Create and optimize the JOIN that will be used to materialize the subquery if not yet created. */ - return materialize_engine->prepare(); + set_thd(thd_arg); + return materialize_engine->prepare(thd); } @@ -4877,7 +4887,7 @@ int subselect_hash_sj_engine::exec() if (strategy == PARTIAL_MATCH_MERGE) { pm_engine= - new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*) + new subselect_rowid_merge_engine((subselect_uniquesubquery_engine*) lookup_engine, tmp_table, count_pm_keys, has_covering_null_row, @@ -4886,6 +4896,7 @@ int subselect_hash_sj_engine::exec() item, result, semi_join_conds->argument_list()); if (!pm_engine || + pm_engine->prepare(thd) || ((subselect_rowid_merge_engine*) pm_engine)-> init(nn_key_parts, &partial_match_key_parts)) { @@ -4903,13 +4914,14 @@ int subselect_hash_sj_engine::exec() if (strategy == PARTIAL_MATCH_SCAN) { if (!(pm_engine= - new subselect_table_scan_engine(thd, (subselect_uniquesubquery_engine*) + new subselect_table_scan_engine((subselect_uniquesubquery_engine*) lookup_engine, tmp_table, item, result, semi_join_conds->argument_list(), has_covering_null_row, has_covering_null_columns, - count_columns_with_nulls))) + count_columns_with_nulls)) || + pm_engine->prepare(thd)) { /* This is an irrecoverable error. */ res= 1; @@ -5356,14 +5368,14 @@ void Ordered_key::print(String *str) subselect_partial_match_engine::subselect_partial_match_engine( - THD *thd_arg, subselect_uniquesubquery_engine *engine_arg, + subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, List *equi_join_conds_arg, bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg) - :subselect_engine(thd_arg, item_arg, result_arg), + :subselect_engine(item_arg, result_arg), tmp_table(tmp_table_arg), lookup_engine(engine_arg), equi_join_conds(equi_join_conds_arg), has_covering_null_row(has_covering_null_row_arg), @@ -5976,7 +5988,7 @@ bool subselect_rowid_merge_engine::partial_match() subselect_table_scan_engine::subselect_table_scan_engine( - THD *thd_arg, subselect_uniquesubquery_engine *engine_arg, + subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, @@ -5984,7 +5996,7 @@ subselect_table_scan_engine::subselect_table_scan_engine( bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg) - :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg, + :subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg, result_arg, equi_join_conds_arg, has_covering_null_row_arg, has_covering_null_columns_arg, diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 0ee5f73eb35e8..0abfe0d5abcba 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -715,7 +715,7 @@ class subselect_engine: public Sql_alloc INDEXSUBQUERY_ENGINE, HASH_SJ_ENGINE, ROWID_MERGE_ENGINE, TABLE_SCAN_ENGINE}; - subselect_engine(THD *thd_arg, Item_subselect *si, + subselect_engine(Item_subselect *si, select_result_interceptor *res) { result= res; @@ -723,7 +723,6 @@ class subselect_engine: public Sql_alloc cmp_type= res_type= STRING_RESULT; res_field_type= MYSQL_TYPE_VAR_STRING; maybe_null= 0; - set_thd(thd_arg); } virtual ~subselect_engine() {}; // to satisfy compiler virtual void cleanup()= 0; @@ -734,7 +733,7 @@ class subselect_engine: public Sql_alloc */ void set_thd(THD *thd_arg); THD * get_thd() { return thd; } - virtual int prepare()= 0; + virtual int prepare(THD *)= 0; virtual void fix_length_and_dec(Item_cache** row)= 0; /* Execute the engine @@ -789,11 +788,11 @@ class subselect_single_select_engine: public subselect_engine st_select_lex *select_lex; /* corresponding select_lex */ JOIN * join; /* corresponding JOIN structure */ public: - subselect_single_select_engine(THD *thd_arg, st_select_lex *select, + subselect_single_select_engine(st_select_lex *select, select_result_interceptor *result, Item_subselect *item); void cleanup(); - int prepare(); + int prepare(THD *thd); void fix_length_and_dec(Item_cache** row); int exec(); uint cols(); @@ -823,11 +822,11 @@ class subselect_union_engine: public subselect_engine { st_select_lex_unit *unit; /* corresponding unit structure */ public: - subselect_union_engine(THD *thd_arg, st_select_lex_unit *u, + subselect_union_engine(st_select_lex_unit *u, select_result_interceptor *result, Item_subselect *item); void cleanup(); - int prepare(); + int prepare(THD *); void fix_length_and_dec(Item_cache** row); int exec(); uint cols(); @@ -880,11 +879,11 @@ class subselect_uniquesubquery_engine: public subselect_engine // constructor can assign THD because it will be called after JOIN::prepare subselect_uniquesubquery_engine(THD *thd_arg, st_join_table *tab_arg, Item_subselect *subs, Item *where) - :subselect_engine(thd_arg, subs, 0), tab(tab_arg), cond(where) + :subselect_engine(subs, 0), tab(tab_arg), cond(where) {} ~subselect_uniquesubquery_engine(); void cleanup(); - int prepare(); + int prepare(THD *); void fix_length_and_dec(Item_cache** row); int exec(); uint cols() { return 1; } @@ -1012,7 +1011,7 @@ class subselect_hash_sj_engine : public subselect_engine subselect_hash_sj_engine(THD *thd, Item_subselect *in_predicate, subselect_single_select_engine *old_engine) - : subselect_engine(thd, in_predicate, NULL), + : subselect_engine(in_predicate, NULL), tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine), materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL), count_partial_match_columns(0), count_null_only_columns(0), @@ -1022,7 +1021,7 @@ class subselect_hash_sj_engine : public subselect_engine bool init(List *tmp_columns, uint subquery_id); void cleanup(); - int prepare(); + int prepare(THD *); int exec(); virtual void print(String *str, enum_query_type query_type); uint cols() @@ -1301,15 +1300,14 @@ class subselect_partial_match_engine : public subselect_engine protected: virtual bool partial_match()= 0; public: - subselect_partial_match_engine(THD *thd_arg, - subselect_uniquesubquery_engine *engine_arg, + subselect_partial_match_engine(subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, List *equi_join_conds_arg, bool has_covering_null_row_arg, bool has_covering_null_columns_arg, uint count_columns_with_nulls_arg); - int prepare() { return 0; } + int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; } int exec(); void fix_length_and_dec(Item_cache**) {} uint cols() { /* TODO: what is the correct value? */ return 1; } @@ -1396,8 +1394,7 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine bool exists_complementing_null_row(MY_BITMAP *keys_to_complement); bool partial_match(); public: - subselect_rowid_merge_engine(THD *thd_arg, - subselect_uniquesubquery_engine *engine_arg, + subselect_rowid_merge_engine(subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, uint merge_keys_count_arg, bool has_covering_null_row_arg, bool has_covering_null_columns_arg, @@ -1405,7 +1402,7 @@ class subselect_rowid_merge_engine: public subselect_partial_match_engine Item_subselect *item_arg, select_result_interceptor *result_arg, List *equi_join_conds_arg) - :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, + :subselect_partial_match_engine(engine_arg, tmp_table_arg, item_arg, result_arg, equi_join_conds_arg, has_covering_null_row_arg, has_covering_null_columns_arg, @@ -1424,8 +1421,7 @@ class subselect_table_scan_engine: public subselect_partial_match_engine protected: bool partial_match(); public: - subselect_table_scan_engine(THD *thd_arg, - subselect_uniquesubquery_engine *engine_arg, + subselect_table_scan_engine(subselect_uniquesubquery_engine *engine_arg, TABLE *tmp_table_arg, Item_subselect *item_arg, select_result_interceptor *result_arg, List *equi_join_conds_arg, From 214f5078f951aeaab1fdece8358b5a284e311f9d Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Fri, 24 Jun 2016 11:08:09 -0400 Subject: [PATCH 111/112] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 14d24a318d196..e748b1bda54d4 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=0 -MYSQL_VERSION_PATCH=26 +MYSQL_VERSION_PATCH=27 From 6dfe3fb2bb6903524966b6e51df05f317e714814 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 28 Jun 2016 10:23:24 +0200 Subject: [PATCH 112/112] remove incorrect .gitattributes --- storage/connect/.gitattributes | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 storage/connect/.gitattributes diff --git a/storage/connect/.gitattributes b/storage/connect/.gitattributes deleted file mode 100644 index d21fdf8f212f6..0000000000000 --- a/storage/connect/.gitattributes +++ /dev/null @@ -1,25 +0,0 @@ -# Set the default behavior, in case people don't have core.autocrlf set. -* text=auto - -# Explicitly declare text files you want to always be normalized and converted -# to native line endings on checkout. -*.c text -*.cc text -*.cpp text -*.h text -*.test text - -# Declare files that will always have LF line endings on checkout. -*.result text eol=lf -mysql-test/connect/std_data/*.txt text eol=lf -mysql-test/connect/std_data/*.dat text eol=lf - -# Denote all files that are truly binary and should not be modified. -*.png binary -*.jpg binary - -*.c diff=cpp -*.h diff=cpp -*.cc diff=cpp -*.ic diff=cpp -*.cpp diff=cpp