summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--CMakeLists.txt8
-rw-r--r--VERSION2
-rw-r--r--appveyor.yml22
-rw-r--r--client/client_priv.h1
-rw-r--r--client/mysql.cc10
-rw-r--r--client/mysql_plugin.c4
-rw-r--r--client/mysql_upgrade.c2
-rw-r--r--client/mysqlbinlog.cc29
-rw-r--r--client/mysqldump.c60
-rw-r--r--client/mysqlimport.c2
-rw-r--r--client/mysqlslap.c2
-rw-r--r--client/mysqltest.cc94
-rw-r--r--cmake/build_configurations/mysql_release.cmake2
-rw-r--r--cmake/check_linker_flag.cmake27
-rw-r--r--cmake/configure.pl2
-rw-r--r--cmake/cpack_rpm.cmake8
-rw-r--r--cmake/dtrace.cmake3
-rw-r--r--cmake/install_macros.cmake10
-rw-r--r--cmake/maintainer.cmake12
-rw-r--r--cmake/os/WindowsCache.cmake1
-rw-r--r--config.h.cmake1
-rw-r--r--configure.cmake8
-rw-r--r--dbug/dbug.c9
-rwxr-xr-xdbug/dbug_add_tags.pl2
-rwxr-xr-xdbug/remove_function_from_trace.pl2
-rw-r--r--debian/additions/innotop/innotop2
-rwxr-xr-xdebian/additions/mysqlreport2
-rw-r--r--extra/mariabackup/CMakeLists.txt2
-rw-r--r--extra/mariabackup/innobackupex.cc9
-rw-r--r--extra/mariabackup/xbstream.c1
-rw-r--r--extra/mariabackup/xtrabackup.cc5
-rwxr-xr-xextra/yassl/include/openssl/generate_prefix_files.pl2
-rw-r--r--include/mysql/psi/mysql_file.h13
-rw-r--r--include/mysql/psi/mysql_idle.h13
-rw-r--r--include/mysql/psi/mysql_socket.h42
-rw-r--r--include/mysql/psi/mysql_stage.h13
-rw-r--r--include/mysql/psi/mysql_statement.h13
-rw-r--r--include/mysql/psi/mysql_table.h13
-rw-r--r--include/mysql/psi/mysql_thread.h13
-rw-r--r--include/mysql/psi/psi.h13
-rw-r--r--include/mysql/psi/psi_abi_v0.h13
-rw-r--r--include/mysql/psi/psi_abi_v1.h13
-rw-r--r--include/mysql/psi/psi_abi_v2.h13
-rw-r--r--include/queues.h10
-rw-r--r--man/CMakeLists.txt5
-rw-r--r--man/mysql_upgrade.14
-rw-r--r--man/mysqlimport.126
-rw-r--r--mysql-test/disabled.def2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_binlog_errors.inc1
-rw-r--r--mysql-test/include/ctype_utf8mb4.inc2
-rw-r--r--mysql-test/include/icp_debug_kill.inc50
-rw-r--r--mysql-test/include/innodb_prefix_index_cluster_optimization.combinations5
-rw-r--r--mysql-test/include/innodb_prefix_index_cluster_optimization.inc1
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process_win.cc2
-rw-r--r--mysql-test/lib/My/Tee.pm2
-rw-r--r--mysql-test/lib/mtr_report.pm106
-rwxr-xr-xmysql-test/lib/process-purecov-annotations.pl2
-rwxr-xr-xmysql-test/lib/t/SafeProcessStress.pl2
-rw-r--r--mysql-test/lib/t/copytree.t2
-rw-r--r--mysql-test/lib/t/dummyd.pl2
-rw-r--r--mysql-test/lib/t/rmtree.t2
-rwxr-xr-xmysql-test/lib/t/testMyConfig.t2
-rwxr-xr-xmysql-test/lib/t/testMyConfigFactory.t2
-rwxr-xr-xmysql-test/lib/t/test_child.pl2
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl2
-rw-r--r--mysql-test/mtr.out-of-source2
-rwxr-xr-xmysql-test/mysql-stress-test.pl2
-rwxr-xr-xmysql-test/mysql-test-run.pl115
-rw-r--r--mysql-test/r/connect_debug.result8
-rw-r--r--mysql-test/r/create_drop_function.result17
-rw-r--r--mysql-test/r/ctype_binary.result93
-rw-r--r--mysql-test/r/ctype_cp932_binlog_stm.result2
-rw-r--r--mysql-test/r/ctype_utf16.result2
-rw-r--r--mysql-test/r/ctype_utf16le.result2
-rw-r--r--mysql-test/r/ctype_utf32.result2
-rw-r--r--mysql-test/r/ctype_utf8.result16
-rw-r--r--mysql-test/r/ctype_utf8mb4.result4
-rw-r--r--mysql-test/r/ctype_utf8mb4_heap.result4
-rw-r--r--mysql-test/r/ctype_utf8mb4_innodb.result4
-rw-r--r--mysql-test/r/ctype_utf8mb4_myisam.result4
-rw-r--r--mysql-test/r/fast_prefix_index_fetch_innodb.result57
-rw-r--r--mysql-test/r/func_group.result4
-rw-r--r--mysql-test/r/func_math.result784
-rw-r--r--mysql-test/r/grant.result13
-rw-r--r--mysql-test/r/grant5.result10
-rw-r--r--mysql-test/r/index_merge_innodb.result30
-rw-r--r--mysql-test/r/index_merge_myisam.result53
-rw-r--r--mysql-test/r/information_schema.result10
-rw-r--r--mysql-test/r/innodb_ext_key,off.rdiff295
-rw-r--r--mysql-test/r/innodb_ext_key.result422
-rw-r--r--mysql-test/r/insert_debug.result25
-rw-r--r--mysql-test/r/limit_rows_examined.result15
-rw-r--r--mysql-test/r/log_tables.result8
-rw-r--r--mysql-test/r/mysql_tzinfo_to_sql_symlink.result6
-rw-r--r--mysql-test/r/mysqlbinlog_row_minimal.result40
-rw-r--r--mysql-test/r/mysqld--defaults-file.result10
-rw-r--r--mysql-test/r/mysqld--help,win.rdiff31
-rw-r--r--mysql-test/r/mysqld--help.result3
-rw-r--r--mysql-test/r/mysqldump.result19
-rw-r--r--mysql-test/r/nested_profiling.result16
-rw-r--r--mysql-test/r/order_by.result135
-rw-r--r--mysql-test/r/parser_precedence.result2
-rw-r--r--mysql-test/r/partition.result51
-rw-r--r--mysql-test/r/processlist_notembedded.result4
-rw-r--r--mysql-test/r/query_cache.result12
-rw-r--r--mysql-test/r/range.result20
-rw-r--r--mysql-test/r/range_innodb.result28
-rw-r--r--mysql-test/r/range_mrr_icp.result20
-rw-r--r--mysql-test/r/range_vs_index_merge.result2
-rw-r--r--mysql-test/r/selectivity.result15
-rw-r--r--mysql-test/r/selectivity_innodb.result15
-rw-r--r--mysql-test/r/stat_tables_innodb.result24
-rw-r--r--mysql-test/r/stat_tables_partition.result34
-rw-r--r--mysql-test/r/stat_tables_rbr.result1
-rw-r--r--mysql-test/r/subselect4.result115
-rw-r--r--mysql-test/r/subselect_exists2in.result127
-rw-r--r--mysql-test/r/subselect_innodb.result14
-rw-r--r--mysql-test/r/temp_table_symlink.result13
-rw-r--r--mysql-test/r/type_date.result2
-rw-r--r--mysql-test/r/type_datetime.result4
-rw-r--r--mysql-test/r/type_float.result21
-rw-r--r--mysql-test/r/type_newdecimal.result49
-rw-r--r--mysql-test/r/type_ranges.result6
-rw-r--r--mysql-test/r/type_set.result2
-rw-r--r--mysql-test/r/udf.result6
-rw-r--r--mysql-test/r/uniques_crash-7912.result11
-rwxr-xr-xmysql-test/std_data/checkDBI_DBD-mysql.pl2
-rw-r--r--mysql-test/suite.pm5
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result56
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result3
-rw-r--r--mysql-test/suite/binlog/r/binlog_no_uniqfile_crash.result44
-rw-r--r--mysql-test/suite/binlog/r/binlog_recover_checksum_error.result7
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_annotate.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result3
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test14
-rw-r--r--mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test7
-rw-r--r--mysql-test/suite/binlog/t/binlog_no_uniqfile_crash.test85
-rw-r--r--mysql-test/suite/binlog/t/binlog_recover_checksum_error.test37
-rw-r--r--mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test5
-rw-r--r--mysql-test/suite/binlog_encryption/binlog_row_annotate.result1
-rw-r--r--mysql-test/suite/binlog_encryption/rpl_binlog_errors.result1
-rw-r--r--mysql-test/suite/engines/iuds/r/insert_decimal.result4
-rwxr-xr-xmysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl2
-rwxr-xr-xmysql-test/suite/funcs_1/lib/DataGen_local.pl2
-rwxr-xr-xmysql-test/suite/funcs_1/lib/DataGen_modify.pl2
-rwxr-xr-xmysql-test/suite/funcs_2/lib/gen_charset_utf8.pl2
-rw-r--r--mysql-test/suite/galera/r/MDEV-20225.result16
-rw-r--r--mysql-test/suite/galera/r/galera_sp_bf_abort.result294
-rw-r--r--mysql-test/suite/galera/t/MDEV-20225.test52
-rw-r--r--mysql-test/suite/galera/t/MW-388.test2
-rw-r--r--mysql-test/suite/galera/t/MW-86-wait1.test2
-rw-r--r--mysql-test/suite/galera/t/MW-86-wait8.test2
-rw-r--r--mysql-test/suite/galera/t/galera_query_cache_sync_wait.test2
-rw-r--r--mysql-test/suite/galera/t/galera_sp_bf_abort.inc36
-rw-r--r--mysql-test/suite/galera/t/galera_sp_bf_abort.test350
-rw-r--r--mysql-test/suite/galera/t/galera_var_retry_autocommit.test2
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result40
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result50
-rw-r--r--mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result55
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test262
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test273
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test299
-rw-r--r--mysql-test/suite/innodb/r/foreign-keys.result126
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result166
-rw-r--r--mysql-test/suite/innodb/r/foreign_key_debug.result60
-rw-r--r--mysql-test/suite/innodb/r/innodb-64k.result7
-rw-r--r--mysql-test/suite/innodb/r/innodb_stats_drop_locked.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result73
-rw-r--r--mysql-test/suite/innodb/r/read_only_recover_committed.result1
-rw-r--r--mysql-test/suite/innodb/t/foreign-keys.test160
-rw-r--r--mysql-test/suite/innodb/t/foreign_key.test203
-rw-r--r--mysql-test/suite/innodb/t/foreign_key_debug.test78
-rw-r--r--mysql-test/suite/innodb/t/innodb-64k.test10
-rw-r--r--mysql-test/suite/innodb/t/innodb_stats_drop_locked.test2
-rw-r--r--mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test70
-rw-r--r--mysql-test/suite/innodb/t/read_only_recover_committed.test1
-rw-r--r--mysql-test/suite/innodb_fts/r/basic.result21
-rw-r--r--mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result42
-rw-r--r--mysql-test/suite/innodb_fts/r/misc_debug2.result6
-rw-r--r--mysql-test/suite/innodb_fts/r/stopword.result735
-rw-r--r--mysql-test/suite/innodb_fts/t/basic.test20
-rw-r--r--mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test42
-rw-r--r--mysql-test/suite/innodb_fts/t/misc_debug2.test11
-rw-r--r--mysql-test/suite/innodb_fts/t/stopword.opt1
-rw-r--r--mysql-test/suite/innodb_fts/t/stopword.test657
-rw-r--r--mysql-test/suite/maria/encrypt-no-key.result15
-rw-r--r--mysql-test/suite/maria/encrypt-no-key.test14
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.result4
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.test8
-rw-r--r--mysql-test/suite/parts/r/partition_debug.result1
-rw-r--r--mysql-test/suite/parts/t/partition_debug.test4
-rw-r--r--mysql-test/suite/perfschema/t/ddl_esms_by_digest.test13
-rw-r--r--mysql-test/suite/perfschema/t/dml_esms_by_digest.test13
-rw-r--r--mysql-test/suite/roles/drop_current_role.result5
-rw-r--r--mysql-test/suite/roles/drop_current_role.test9
-rw-r--r--mysql-test/suite/roles/set_default_role_for.result4
-rw-r--r--mysql-test/suite/roles/set_default_role_invalid.result87
-rw-r--r--mysql-test/suite/roles/set_default_role_invalid.test107
-rw-r--r--mysql-test/suite/roles/set_role-recursive.result2
-rwxr-xr-xmysql-test/suite/rpl/extension/checksum.pl2
-rw-r--r--mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result34
-rw-r--r--mysql-test/suite/rpl/r/rpl_binlog_errors.result1
-rw-r--r--mysql-test/suite/rpl/r/rpl_binlog_index.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_conditional_comments.result15
-rw-r--r--mysql-test/suite/rpl/r/rpl_fail_register.result16
-rw-r--r--mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_gtid_crash.result3
-rw-r--r--mysql-test/suite/rpl/r/rpl_mysql_upgrade.result54
-rw-r--r--mysql-test/suite/rpl/r/rpl_parallel2.result3
-rw-r--r--mysql-test/suite/rpl/r/rpl_parallel_optimistic_until.result238
-rw-r--r--mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test121
-rw-r--r--mysql-test/suite/rpl/t/rpl_binlog_index.test18
-rw-r--r--mysql-test/suite/rpl/t/rpl_conditional_comments.test12
-rw-r--r--mysql-test/suite/rpl/t/rpl_fail_register.test32
-rw-r--r--mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_crash.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_mysql_upgrade.test34
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel2.test3
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test466
-rw-r--r--mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test2
-rw-r--r--mysql-test/suite/sys_vars/inc/sysvars_server.inc1
-rw-r--r--mysql-test/suite/sys_vars/r/div_precision_increment_func.result16
-rw-r--r--mysql-test/suite/sys_vars/r/max_sort_length_basic.result36
-rw-r--r--mysql-test/suite/sys_vars/r/replicate_do_db_basic.result4
-rw-r--r--mysql-test/suite/sys_vars/r/rpl_init_slave_func.result15
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff4
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff4
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result8
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result2
-rw-r--r--mysql-test/suite/sys_vars/r/table_open_cache_basic.result12
-rw-r--r--mysql-test/suite/sys_vars/t/max_sort_length_basic.test8
-rw-r--r--mysql-test/suite/sys_vars/t/replicate_do_db_basic.test3
-rw-r--r--mysql-test/suite/sys_vars/t/rpl_init_slave_func.test33
-rw-r--r--mysql-test/suite/sys_vars/t/table_open_cache_basic.test4
-rw-r--r--mysql-test/suite/vcol/r/not_supported.result2
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result20
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test30
-rw-r--r--mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result4
-rw-r--r--mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result4
-rw-r--r--mysql-test/t/aria_icp_debug.result34
-rw-r--r--mysql-test/t/aria_icp_debug.test5
-rw-r--r--mysql-test/t/connect_debug.test15
-rw-r--r--mysql-test/t/create_drop_function.test24
-rw-r--r--mysql-test/t/ctype_binary.test60
-rw-r--r--mysql-test/t/ctype_utf16.test2
-rw-r--r--mysql-test/t/ctype_utf16le.test2
-rw-r--r--mysql-test/t/ctype_utf32.test2
-rw-r--r--mysql-test/t/ctype_utf8.test14
-rw-r--r--mysql-test/t/ctype_utf8mb4.test2
-rw-r--r--mysql-test/t/fast_prefix_index_fetch_innodb.test52
-rw-r--r--mysql-test/t/func_math.test88
-rw-r--r--mysql-test/t/grant.test13
-rw-r--r--mysql-test/t/grant5.test22
-rw-r--r--mysql-test/t/index_merge_innodb.test27
-rw-r--r--mysql-test/t/index_merge_myisam.test51
-rw-r--r--mysql-test/t/information_schema.test12
-rw-r--r--mysql-test/t/innodb_ext_key.combinations5
-rw-r--r--mysql-test/t/innodb_ext_key.test222
-rw-r--r--mysql-test/t/innodb_icp_debug.result34
-rw-r--r--mysql-test/t/innodb_icp_debug.test6
-rw-r--r--mysql-test/t/insert_debug-master.opt1
-rw-r--r--mysql-test/t/insert_debug.test54
-rw-r--r--mysql-test/t/limit_rows_examined.test17
-rw-r--r--mysql-test/t/log_tables.test20
-rw-r--r--mysql-test/t/myisam_icp_debug.result32
-rw-r--r--mysql-test/t/myisam_icp_debug.test1
-rw-r--r--mysql-test/t/mysqlbinlog_row_minimal.test34
-rw-r--r--mysql-test/t/mysqld--defaults-file.test16
-rw-r--r--mysql-test/t/mysqld--help.test3
-rw-r--r--mysql-test/t/mysqldump.test36
-rw-r--r--mysql-test/t/nested_profiling.test42
-rw-r--r--mysql-test/t/order_by.test54
-rw-r--r--mysql-test/t/partition.test44
-rw-r--r--mysql-test/t/processlist_notembedded.test12
-rw-r--r--mysql-test/t/query_cache.test17
-rw-r--r--mysql-test/t/range.test16
-rw-r--r--mysql-test/t/range_innodb.test28
-rw-r--r--mysql-test/t/selectivity.test12
-rw-r--r--mysql-test/t/stat_tables_innodb.test20
-rw-r--r--mysql-test/t/stat_tables_partition.test30
-rw-r--r--mysql-test/t/subselect4.test88
-rw-r--r--mysql-test/t/subselect_exists2in.test112
-rw-r--r--mysql-test/t/subselect_innodb.test16
-rw-r--r--mysql-test/t/temp_table_symlink.test32
-rw-r--r--mysql-test/t/type_date.test6
-rw-r--r--mysql-test/t/type_datetime.test5
-rw-r--r--mysql-test/t/type_float.test14
-rw-r--r--mysql-test/t/type_newdecimal.test22
-rw-r--r--mysql-test/t/type_set.test2
-rw-r--r--mysql-test/t/udf.test2
-rw-r--r--mysql-test/t/uniques_crash-7912.test26
-rw-r--r--mysql-test/unstable-tests369
-rw-r--r--mysys/list.c4
-rw-r--r--mysys/mf_iocache.c8
-rw-r--r--mysys/my_addr_resolve.c12
-rw-r--r--mysys/my_alloc.c4
-rw-r--r--mysys/my_default.c10
-rw-r--r--mysys/queues.c169
-rw-r--r--mysys/stacktrace.c122
-rw-r--r--pcre/AUTHORS6
-rw-r--r--pcre/ChangeLog29
-rw-r--r--pcre/LICENCE6
-rw-r--r--pcre/NEWS6
-rw-r--r--pcre/README9
-rw-r--r--pcre/configure.ac17
-rw-r--r--pcre/doc/html/README.txt9
-rw-r--r--pcre/doc/html/pcre.html2
-rw-r--r--pcre/doc/html/pcreapi.html6
-rw-r--r--pcre/doc/html/pcretest.html24
-rw-r--r--pcre/doc/pcre-config.txt42
-rw-r--r--pcre/doc/pcre.32
-rw-r--r--pcre/doc/pcre.txt3927
-rw-r--r--pcre/doc/pcreapi.36
-rw-r--r--pcre/doc/pcregrep.txt232
-rw-r--r--pcre/doc/pcretest.126
-rw-r--r--pcre/doc/pcretest.txt650
-rw-r--r--pcre/pcre_compile.c30
-rw-r--r--pcre/pcre_jit_compile.c6
-rw-r--r--pcre/pcrecpp.cc4
-rw-r--r--pcre/pcreposix.c5
-rw-r--r--pcre/pcretest.c12
-rw-r--r--pcre/testdata/testinput22
-rw-r--r--pcre/testdata/testoutput23
-rw-r--r--plugin/auth_gssapi/CMakeLists.txt6
-rw-r--r--plugin/auth_gssapi/gssapi_server.cc2
-rw-r--r--plugin/disks/information_schema_disks.cc13
-rw-r--r--plugin/disks/mysql-test/disks/disks.result6
-rwxr-xr-xplugin/handler_socket/client/hspool_test.pl2
-rwxr-xr-xplugin/handler_socket/client/hstest.pl2
-rwxr-xr-xplugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test01.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test02.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test03.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test04.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test05.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test06.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test07.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test08.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test09.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test10.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test11.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test12.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test13.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test14.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test15.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test16.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test17.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test18.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test19.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test20.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test21.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test22.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test23.pl2
-rw-r--r--plugin/handler_socket/regtest/test_01_lib/test24.pl2
-rw-r--r--scripts/CMakeLists.txt59
-rw-r--r--scripts/galera_recovery.sh3
-rw-r--r--scripts/mysql_install_db.sh3
-rw-r--r--scripts/mysqld_multi.sh14
-rw-r--r--scripts/mytop.sh2
-rw-r--r--scripts/wsrep_sst_mariabackup.sh29
-rw-r--r--scripts/wsrep_sst_rsync.sh8
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh3
-rw-r--r--sql-bench/as3ap.sh2
-rw-r--r--sql-bench/bench-count-distinct.sh2
-rw-r--r--sql-bench/bench-init.pl.sh2
-rw-r--r--sql-bench/compare-results.sh2
-rw-r--r--sql-bench/copy-db.sh2
-rw-r--r--sql-bench/crash-me.sh2
-rwxr-xr-xsql-bench/graph-compare-results.sh2
-rw-r--r--sql-bench/innotest1.sh2
-rw-r--r--sql-bench/innotest1a.sh2
-rw-r--r--sql-bench/innotest1b.sh2
-rw-r--r--sql-bench/innotest2.sh2
-rw-r--r--sql-bench/innotest2a.sh2
-rw-r--r--sql-bench/innotest2b.sh2
-rw-r--r--sql-bench/run-all-tests.sh2
-rw-r--r--sql-bench/server-cfg.sh2
-rw-r--r--sql-bench/test-ATIS.sh2
-rw-r--r--sql-bench/test-alter-table.sh2
-rw-r--r--sql-bench/test-big-tables.sh2
-rw-r--r--sql-bench/test-connect.sh2
-rw-r--r--sql-bench/test-create.sh2
-rw-r--r--sql-bench/test-insert.sh2
-rw-r--r--sql-bench/test-select.sh2
-rwxr-xr-xsql-bench/test-table-elimination.sh2
-rw-r--r--sql-bench/test-transactions.sh2
-rw-r--r--sql-bench/test-wisconsin.sh2
-rw-r--r--sql-common/client.c25
-rw-r--r--sql/compat56.cc2
-rw-r--r--sql/debug_sync.cc8
-rw-r--r--sql/derror.cc2
-rw-r--r--sql/encryption.cc4
-rw-r--r--sql/event_data_objects.cc2
-rw-r--r--sql/event_db_repository.cc2
-rw-r--r--sql/event_parse_data.cc6
-rw-r--r--sql/event_queue.cc2
-rw-r--r--sql/event_scheduler.cc4
-rw-r--r--sql/events.cc2
-rw-r--r--sql/field.cc106
-rw-r--r--sql/field.h37
-rw-r--r--sql/field_conv.cc2
-rw-r--r--sql/filesort.cc11
-rw-r--r--sql/filesort_utils.cc1
-rw-r--r--sql/gcalc_slicescan.cc2
-rw-r--r--sql/gcalc_slicescan.h6
-rw-r--r--sql/gcalc_tools.cc4
-rw-r--r--sql/gen_win_tzname_data.ps12
-rw-r--r--sql/ha_partition.cc32
-rw-r--r--sql/ha_partition.h6
-rw-r--r--sql/handler.cc13
-rw-r--r--sql/handler.h22
-rw-r--r--sql/item.cc18
-rw-r--r--sql/item.h27
-rw-r--r--sql/item_buff.cc2
-rw-r--r--sql/item_cmpfunc.cc18
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_func.cc80
-rw-r--r--sql/item_inetfunc.cc8
-rw-r--r--sql/item_strfunc.cc6
-rw-r--r--sql/item_strfunc.h10
-rw-r--r--sql/item_subselect.cc67
-rw-r--r--sql/item_subselect.h12
-rw-r--r--sql/item_sum.cc16
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/item_timefunc.cc24
-rw-r--r--sql/item_xmlfunc.cc23
-rw-r--r--sql/key.cc6
-rw-r--r--sql/lex.h2
-rw-r--r--sql/lock.cc2
-rw-r--r--sql/log.cc72
-rw-r--r--sql/log.h13
-rw-r--r--sql/log_event.cc85
-rw-r--r--sql/log_event.h34
-rw-r--r--sql/log_event_old.cc10
-rw-r--r--sql/mysql_install_db.cc22
-rw-r--r--sql/mysqld.cc21
-rw-r--r--sql/net_serv.cc5
-rw-r--r--sql/opt_range.cc28
-rw-r--r--sql/opt_range_mrr.cc1
-rw-r--r--sql/rpl_filter.cc52
-rw-r--r--sql/rpl_parallel.cc33
-rw-r--r--sql/rpl_rli.cc71
-rw-r--r--sql/rpl_rli.h19
-rw-r--r--sql/set_var.cc16
-rw-r--r--sql/set_var.h1
-rw-r--r--sql/signal_handler.cc2
-rw-r--r--sql/slave.cc44
-rw-r--r--sql/sp.cc4
-rw-r--r--sql/sp_cache.cc2
-rw-r--r--sql/sp_head.cc151
-rw-r--r--sql/sp_head.h17
-rw-r--r--sql/sql_acl.cc280
-rw-r--r--sql/sql_acl.h2
-rw-r--r--sql/sql_admin.cc10
-rw-r--r--sql/sql_base.cc33
-rw-r--r--sql/sql_binlog.cc3
-rw-r--r--sql/sql_cache.cc16
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h20
-rw-r--r--sql/sql_lex.cc25
-rw-r--r--sql/sql_parse.cc19
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_repl.cc65
-rw-r--r--sql/sql_select.cc22
-rw-r--r--sql/sql_show.cc48
-rw-r--r--sql/sql_statistics.cc319
-rw-r--r--sql/sql_statistics.h19
-rw-r--r--sql/sql_string.h5
-rw-r--r--sql/sql_table.cc4
-rw-r--r--sql/sql_time.cc4
-rw-r--r--sql/sql_trigger.cc18
-rw-r--r--sql/sql_type_int.h20
-rw-r--r--sql/sql_union.cc19
-rw-r--r--sql/sql_update.cc5
-rw-r--r--sql/sql_view.cc5
-rw-r--r--sql/sql_yacc.yy2
-rw-r--r--sql/sys_vars.cc2
-rw-r--r--sql/sys_vars.ic6
-rw-r--r--sql/table.cc175
-rw-r--r--sql/table.h107
-rw-r--r--sql/tztime.cc3
-rw-r--r--sql/uniques.cc11
-rw-r--r--sql/unireg.cc23
-rw-r--r--sql/win_tzname_data.h8
-rw-r--r--sql/winservice.c65
-rw-r--r--sql/wsrep_dummy.cc4
-rw-r--r--sql/wsrep_hton.cc22
-rw-r--r--sql/wsrep_mysqld.cc26
-rw-r--r--sql/wsrep_mysqld.h17
-rw-r--r--sql/wsrep_sst.cc51
-rw-r--r--sql/wsrep_thd.cc111
-rw-r--r--sql/wsrep_thd.h1
-rw-r--r--storage/innobase/btr/btr0cur.cc18
-rw-r--r--storage/innobase/btr/btr0defragment.cc3
-rw-r--r--storage/innobase/buf/buf0buf.cc10
-rw-r--r--storage/innobase/buf/buf0dblwr.cc18
-rw-r--r--storage/innobase/buf/buf0dump.cc8
-rw-r--r--storage/innobase/buf/buf0flu.cc9
-rw-r--r--storage/innobase/buf/buf0lru.cc4
-rw-r--r--storage/innobase/buf/buf0rea.cc68
-rw-r--r--storage/innobase/dict/dict0dict.cc7
-rw-r--r--storage/innobase/dict/dict0mem.cc66
-rw-r--r--storage/innobase/fil/fil0crypt.cc181
-rw-r--r--storage/innobase/fil/fil0fil.cc160
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc14
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc99
-rw-r--r--storage/innobase/fts/fts0fts.cc87
-rw-r--r--storage/innobase/fts/fts0que.cc19
-rw-r--r--storage/innobase/handler/ha_innodb.cc269
-rw-r--r--storage/innobase/handler/handler0alter.cc6
-rw-r--r--storage/innobase/handler/i_s.cc32
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc71
-rw-r--r--storage/innobase/include/buf0buf.h4
-rw-r--r--storage/innobase/include/dict0dict.ic8
-rw-r--r--storage/innobase/include/dict0mem.h4
-rw-r--r--storage/innobase/include/fil0fil.h51
-rw-r--r--storage/innobase/include/fts0ast.h15
-rw-r--r--storage/innobase/include/fts0fts.h12
-rw-r--r--storage/innobase/include/lock0lock.h5
-rw-r--r--storage/innobase/include/mtr0mtr.h13
-rw-r--r--storage/innobase/include/mtr0mtr.ic15
-rw-r--r--storage/innobase/include/page0page.h17
-rw-r--r--storage/innobase/include/page0types.h4
-rw-r--r--storage/innobase/include/sync0rw.h8
-rw-r--r--storage/innobase/include/trx0trx.h14
-rw-r--r--storage/innobase/include/univ.i2
-rw-r--r--storage/innobase/lock/lock0lock.cc13
-rw-r--r--storage/innobase/lock/lock0wait.cc7
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc11
-rw-r--r--storage/innobase/os/os0file.cc1
-rw-r--r--storage/innobase/page/page0cur.cc47
-rw-r--r--storage/innobase/page/page0page.cc40
-rw-r--r--storage/innobase/page/page0zip.cc40
-rw-r--r--storage/innobase/row/row0import.cc28
-rw-r--r--storage/innobase/row/row0ins.cc45
-rw-r--r--storage/innobase/row/row0mysql.cc20
-rw-r--r--storage/innobase/row/row0sel.cc50
-rw-r--r--storage/innobase/row/row0upd.cc4
-rw-r--r--storage/innobase/srv/srv0conc.cc11
-rw-r--r--storage/innobase/srv/srv0srv.cc3
-rw-r--r--storage/innobase/srv/srv0start.cc10
-rw-r--r--storage/innobase/sync/sync0arr.cc4
-rw-r--r--storage/innobase/trx/trx0rseg.cc6
-rw-r--r--storage/innobase/trx/trx0sys.cc4
-rw-r--r--storage/innobase/trx/trx0trx.cc8
-rw-r--r--storage/maria/ha_maria.cc2
-rw-r--r--storage/maria/ma_check.c1
-rw-r--r--storage/maria/ma_create.c6
-rw-r--r--storage/maria/ma_page.c3
-rw-r--r--storage/maria/ma_pagecrc.c3
-rw-r--r--storage/mroonga/mrn_table.cpp2
-rwxr-xr-xstorage/myisam/ftbench/Ecompare.pl2
-rwxr-xr-xstorage/myisam/ftbench/Ecreate.pl2
-rwxr-xr-xstorage/myisam/ftbench/Ereport.pl2
-rw-r--r--storage/myisam/mi_create.c6
-rw-r--r--storage/myisammrg/myrg_extra.c2
-rw-r--r--storage/perfschema/CMakeLists.txt15
-rw-r--r--storage/perfschema/cursor_by_account.cc13
-rw-r--r--storage/perfschema/cursor_by_account.h13
-rw-r--r--storage/perfschema/cursor_by_host.cc13
-rw-r--r--storage/perfschema/cursor_by_host.h13
-rw-r--r--storage/perfschema/cursor_by_thread.cc13
-rw-r--r--storage/perfschema/cursor_by_thread.h13
-rw-r--r--storage/perfschema/cursor_by_thread_connect_attr.cc13
-rw-r--r--storage/perfschema/cursor_by_thread_connect_attr.h13
-rw-r--r--storage/perfschema/cursor_by_user.cc13
-rw-r--r--storage/perfschema/cursor_by_user.h13
-rw-r--r--storage/perfschema/gen_pfs_lex_token.cc13
-rw-r--r--storage/perfschema/ha_perfschema.cc13
-rw-r--r--storage/perfschema/ha_perfschema.h13
-rw-r--r--storage/perfschema/pfs.cc13
-rw-r--r--storage/perfschema/pfs.h13
-rw-r--r--storage/perfschema/pfs_account.cc13
-rw-r--r--storage/perfschema/pfs_account.h13
-rw-r--r--storage/perfschema/pfs_atomic.h13
-rw-r--r--storage/perfschema/pfs_autosize.cc13
-rw-r--r--storage/perfschema/pfs_column_types.h13
-rw-r--r--storage/perfschema/pfs_column_values.cc13
-rw-r--r--storage/perfschema/pfs_column_values.h13
-rw-r--r--storage/perfschema/pfs_con_slice.cc13
-rw-r--r--storage/perfschema/pfs_con_slice.h13
-rw-r--r--storage/perfschema/pfs_defaults.cc13
-rw-r--r--storage/perfschema/pfs_defaults.h13
-rw-r--r--storage/perfschema/pfs_digest.cc13
-rw-r--r--storage/perfschema/pfs_digest.h13
-rw-r--r--storage/perfschema/pfs_engine_table.cc13
-rw-r--r--storage/perfschema/pfs_engine_table.h13
-rw-r--r--storage/perfschema/pfs_events.h13
-rw-r--r--storage/perfschema/pfs_events_stages.cc13
-rw-r--r--storage/perfschema/pfs_events_stages.h13
-rw-r--r--storage/perfschema/pfs_events_statements.cc13
-rw-r--r--storage/perfschema/pfs_events_statements.h13
-rw-r--r--storage/perfschema/pfs_events_waits.cc13
-rw-r--r--storage/perfschema/pfs_events_waits.h13
-rw-r--r--storage/perfschema/pfs_global.cc13
-rw-r--r--storage/perfschema/pfs_global.h13
-rw-r--r--storage/perfschema/pfs_host.cc13
-rw-r--r--storage/perfschema/pfs_host.h13
-rw-r--r--storage/perfschema/pfs_instr.cc13
-rw-r--r--storage/perfschema/pfs_instr.h13
-rw-r--r--storage/perfschema/pfs_instr_class.cc13
-rw-r--r--storage/perfschema/pfs_instr_class.h13
-rw-r--r--storage/perfschema/pfs_lock.h13
-rw-r--r--storage/perfschema/pfs_server.cc13
-rw-r--r--storage/perfschema/pfs_server.h13
-rw-r--r--storage/perfschema/pfs_setup_actor.cc13
-rw-r--r--storage/perfschema/pfs_setup_actor.h13
-rw-r--r--storage/perfschema/pfs_setup_object.cc13
-rw-r--r--storage/perfschema/pfs_setup_object.h13
-rw-r--r--storage/perfschema/pfs_stat.h13
-rw-r--r--storage/perfschema/pfs_timer.cc13
-rw-r--r--storage/perfschema/pfs_timer.h13
-rw-r--r--storage/perfschema/pfs_user.cc13
-rw-r--r--storage/perfschema/pfs_user.h13
-rw-r--r--storage/perfschema/pfs_visitor.cc13
-rw-r--r--storage/perfschema/pfs_visitor.h13
-rw-r--r--storage/perfschema/table_accounts.cc13
-rw-r--r--storage/perfschema/table_accounts.h13
-rw-r--r--storage/perfschema/table_all_instr.cc13
-rw-r--r--storage/perfschema/table_all_instr.h13
-rw-r--r--storage/perfschema/table_esgs_by_account_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_account_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_by_host_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_host_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_by_thread_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_thread_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_by_user_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_by_user_by_event_name.h13
-rw-r--r--storage/perfschema/table_esgs_global_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esgs_global_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_account_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_account_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_digest.cc13
-rw-r--r--storage/perfschema/table_esms_by_digest.h13
-rw-r--r--storage/perfschema/table_esms_by_host_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_host_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_thread_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_thread_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_by_user_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_by_user_by_event_name.h13
-rw-r--r--storage/perfschema/table_esms_global_by_event_name.cc13
-rw-r--r--storage/perfschema/table_esms_global_by_event_name.h13
-rw-r--r--storage/perfschema/table_events_stages.cc13
-rw-r--r--storage/perfschema/table_events_stages.h13
-rw-r--r--storage/perfschema/table_events_statements.cc13
-rw-r--r--storage/perfschema/table_events_statements.h13
-rw-r--r--storage/perfschema/table_events_waits.cc13
-rw-r--r--storage/perfschema/table_events_waits.h13
-rw-r--r--storage/perfschema/table_events_waits_summary.cc13
-rw-r--r--storage/perfschema/table_events_waits_summary.h13
-rw-r--r--storage/perfschema/table_ews_by_account_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_account_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_by_host_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_host_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_by_thread_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_thread_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_by_user_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_by_user_by_event_name.h13
-rw-r--r--storage/perfschema/table_ews_global_by_event_name.cc13
-rw-r--r--storage/perfschema/table_ews_global_by_event_name.h13
-rw-r--r--storage/perfschema/table_file_instances.cc13
-rw-r--r--storage/perfschema/table_file_instances.h13
-rw-r--r--storage/perfschema/table_file_summary_by_event_name.cc13
-rw-r--r--storage/perfschema/table_file_summary_by_event_name.h13
-rw-r--r--storage/perfschema/table_file_summary_by_instance.cc13
-rw-r--r--storage/perfschema/table_file_summary_by_instance.h13
-rw-r--r--storage/perfschema/table_helper.cc13
-rw-r--r--storage/perfschema/table_helper.h13
-rw-r--r--storage/perfschema/table_host_cache.cc13
-rw-r--r--storage/perfschema/table_host_cache.h13
-rw-r--r--storage/perfschema/table_hosts.cc13
-rw-r--r--storage/perfschema/table_hosts.h13
-rw-r--r--storage/perfschema/table_os_global_by_type.cc13
-rw-r--r--storage/perfschema/table_os_global_by_type.h13
-rw-r--r--storage/perfschema/table_performance_timers.cc13
-rw-r--r--storage/perfschema/table_performance_timers.h13
-rw-r--r--storage/perfschema/table_session_account_connect_attrs.cc13
-rw-r--r--storage/perfschema/table_session_account_connect_attrs.h13
-rw-r--r--storage/perfschema/table_session_connect.cc13
-rw-r--r--storage/perfschema/table_session_connect.h13
-rw-r--r--storage/perfschema/table_session_connect_attrs.cc13
-rw-r--r--storage/perfschema/table_session_connect_attrs.h13
-rw-r--r--storage/perfschema/table_setup_actors.cc13
-rw-r--r--storage/perfschema/table_setup_actors.h13
-rw-r--r--storage/perfschema/table_setup_consumers.cc13
-rw-r--r--storage/perfschema/table_setup_consumers.h13
-rw-r--r--storage/perfschema/table_setup_instruments.cc13
-rw-r--r--storage/perfschema/table_setup_instruments.h13
-rw-r--r--storage/perfschema/table_setup_objects.cc13
-rw-r--r--storage/perfschema/table_setup_objects.h13
-rw-r--r--storage/perfschema/table_setup_timers.cc13
-rw-r--r--storage/perfschema/table_setup_timers.h13
-rw-r--r--storage/perfschema/table_socket_instances.cc13
-rw-r--r--storage/perfschema/table_socket_instances.h13
-rw-r--r--storage/perfschema/table_socket_summary_by_event_name.cc13
-rw-r--r--storage/perfschema/table_socket_summary_by_event_name.h13
-rw-r--r--storage/perfschema/table_socket_summary_by_instance.cc13
-rw-r--r--storage/perfschema/table_socket_summary_by_instance.h13
-rw-r--r--storage/perfschema/table_sync_instances.cc13
-rw-r--r--storage/perfschema/table_sync_instances.h13
-rw-r--r--storage/perfschema/table_threads.cc13
-rw-r--r--storage/perfschema/table_threads.h13
-rw-r--r--storage/perfschema/table_tiws_by_index_usage.cc13
-rw-r--r--storage/perfschema/table_tiws_by_index_usage.h13
-rw-r--r--storage/perfschema/table_tiws_by_table.cc13
-rw-r--r--storage/perfschema/table_tiws_by_table.h13
-rw-r--r--storage/perfschema/table_tlws_by_table.cc13
-rw-r--r--storage/perfschema/table_tlws_by_table.h13
-rw-r--r--storage/perfschema/table_users.cc13
-rw-r--r--storage/perfschema/table_users.h13
-rw-r--r--storage/perfschema/unittest/CMakeLists.txt15
-rw-r--r--storage/perfschema/unittest/conf.txt13
-rw-r--r--storage/perfschema/unittest/pfs-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_account-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_connect_attr-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_host-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr_class-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_instr_class-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_misc-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_server_stubs.cc13
-rw-r--r--storage/perfschema/unittest/pfs_timer-t.cc13
-rw-r--r--storage/perfschema/unittest/pfs_user-oom-t.cc13
-rw-r--r--storage/perfschema/unittest/stub_pfs_defaults.h13
-rw-r--r--storage/perfschema/unittest/stub_pfs_global.h13
-rw-r--r--storage/perfschema/unittest/stub_print_error.h13
-rw-r--r--storage/spider/ha_spider.cc179
-rw-r--r--storage/spider/spd_conn.cc22
-rw-r--r--storage/spider/spd_db_conn.cc772
-rw-r--r--storage/spider/spd_db_mysql.cc597
-rw-r--r--storage/spider/spd_db_oracle.cc492
-rw-r--r--storage/spider/spd_include.h4
-rw-r--r--storage/spider/spd_table.cc7
-rw-r--r--storage/tokudb/CMakeLists.txt3
-rw-r--r--storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake2
-rw-r--r--storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake29
-rw-r--r--storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc10
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-flusher.cc44
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-internal.h21
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.cc56
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-ops.h4
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-recount-rows.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-test-helpers.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/ft-verify.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/ft.cc28
-rw-r--r--storage/tokudb/PerconaFT/ft/ft.h10
-rw-r--r--storage/tokudb/PerconaFT/ft/logger/logger.cc15
-rw-r--r--storage/tokudb/PerconaFT/ft/node.cc18
-rw-r--r--storage/tokudb/PerconaFT/ft/node.h21
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/block_table.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc12
-rw-r--r--storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h1
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc10
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc14
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/make-tree.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/mempool-115.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/msnfilter.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc8
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc6
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc20
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/test3884.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc2
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/rollback.cc4
-rw-r--r--storage/tokudb/PerconaFT/ft/txn/txn.cc4
-rw-r--r--storage/tokudb/PerconaFT/ftcxx/cursor.hpp4
-rw-r--r--storage/tokudb/PerconaFT/locktree/lock_request.cc4
-rw-r--r--storage/tokudb/PerconaFT/locktree/lock_request.h1
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc2
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc2
-rw-r--r--storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/portability.cc2
-rw-r--r--storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc9
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test.h4
-rw-r--r--storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc2
-rw-r--r--storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h6
-rw-r--r--storage/tokudb/PerconaFT/src/ydb.cc56
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.cc8
-rw-r--r--storage/tokudb/PerconaFT/src/ydb_db.h1
-rw-r--r--storage/tokudb/PerconaFT/tools/tokuftdump.cc2
-rw-r--r--storage/tokudb/ha_tokudb.cc4
-rw-r--r--storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt4
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result5
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_ranges.result6
-rw-r--r--storage/tokudb/tokudb_status.h4
-rw-r--r--storage/xtradb/btr/btr0cur.cc18
-rw-r--r--storage/xtradb/buf/buf0buf.cc10
-rw-r--r--storage/xtradb/buf/buf0dblwr.cc18
-rw-r--r--storage/xtradb/buf/buf0dump.cc8
-rw-r--r--storage/xtradb/buf/buf0flu.cc9
-rw-r--r--storage/xtradb/buf/buf0lru.cc4
-rw-r--r--storage/xtradb/buf/buf0rea.cc65
-rw-r--r--storage/xtradb/dict/dict0dict.cc7
-rw-r--r--storage/xtradb/dict/dict0mem.cc66
-rw-r--r--storage/xtradb/fil/fil0crypt.cc181
-rw-r--r--storage/xtradb/fil/fil0fil.cc160
-rw-r--r--storage/xtradb/fil/fil0pagecompress.cc14
-rw-r--r--storage/xtradb/fsp/fsp0fsp.cc99
-rw-r--r--storage/xtradb/fts/fts0fts.cc87
-rw-r--r--storage/xtradb/fts/fts0que.cc19
-rw-r--r--storage/xtradb/handler/ha_innodb.cc270
-rw-r--r--storage/xtradb/handler/handler0alter.cc6
-rw-r--r--storage/xtradb/handler/i_s.cc30
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc71
-rw-r--r--storage/xtradb/include/buf0buf.h4
-rw-r--r--storage/xtradb/include/dict0dict.ic8
-rw-r--r--storage/xtradb/include/dict0mem.h4
-rw-r--r--storage/xtradb/include/fil0fil.h51
-rw-r--r--storage/xtradb/include/fts0ast.h15
-rw-r--r--storage/xtradb/include/fts0fts.h12
-rw-r--r--storage/xtradb/include/lock0lock.h3
-rw-r--r--storage/xtradb/include/mtr0mtr.h12
-rw-r--r--storage/xtradb/include/mtr0mtr.ic15
-rw-r--r--storage/xtradb/include/page0page.h17
-rw-r--r--storage/xtradb/include/sync0rw.h8
-rw-r--r--storage/xtradb/include/trx0trx.h14
-rw-r--r--storage/xtradb/include/univ.i4
-rw-r--r--storage/xtradb/lock/lock0lock.cc13
-rw-r--r--storage/xtradb/lock/lock0wait.cc7
-rw-r--r--storage/xtradb/mtr/mtr0mtr.cc10
-rw-r--r--storage/xtradb/os/os0file.cc1
-rw-r--r--storage/xtradb/page/page0cur.cc47
-rw-r--r--storage/xtradb/page/page0page.cc40
-rw-r--r--storage/xtradb/page/page0zip.cc37
-rw-r--r--storage/xtradb/row/row0import.cc32
-rw-r--r--storage/xtradb/row/row0ins.cc45
-rw-r--r--storage/xtradb/row/row0mysql.cc17
-rw-r--r--storage/xtradb/row/row0sel.cc32
-rw-r--r--storage/xtradb/row/row0upd.cc4
-rw-r--r--storage/xtradb/srv/srv0conc.cc11
-rw-r--r--storage/xtradb/srv/srv0srv.cc3
-rw-r--r--storage/xtradb/srv/srv0start.cc10
-rw-r--r--storage/xtradb/sync/sync0arr.cc4
-rw-r--r--storage/xtradb/trx/trx0roll.cc11
-rw-r--r--storage/xtradb/trx/trx0rseg.cc6
-rw-r--r--storage/xtradb/trx/trx0sys.cc4
-rw-r--r--storage/xtradb/trx/trx0trx.cc8
-rw-r--r--strings/decimal.c18
-rw-r--r--support-files/CMakeLists.txt35
-rw-r--r--support-files/mariadb.pc.in2
-rw-r--r--support-files/mariadb.service.in6
-rw-r--r--support-files/mariadb@.service.in8
-rw-r--r--support-files/rpm/my.cnf4
-rw-r--r--support-files/use_galera_new_cluster.conf5
-rwxr-xr-xtests/big_record.pl2
-rwxr-xr-xtests/drop_test.pl2
-rwxr-xr-xtests/export.pl2
-rwxr-xr-xtests/fork2_test.pl2
-rwxr-xr-xtests/fork_big.pl2
-rw-r--r--tests/fork_big2.pl2
-rwxr-xr-xtests/grant.pl2
-rwxr-xr-xtests/index_corrupt.pl2
-rwxr-xr-xtests/insert_and_repair.pl2
-rwxr-xr-xtests/lock_test.pl2
-rwxr-xr-xtests/mail_to_db.pl2
-rwxr-xr-xtests/pmail.pl2
-rwxr-xr-xtests/rename_test.pl2
-rwxr-xr-xtests/table_types.pl2
-rwxr-xr-xtests/test_delayed_insert.pl2
-rwxr-xr-xtests/truncate.pl2
-rw-r--r--unittest/mysys/CMakeLists.txt2
-rw-r--r--unittest/mysys/queues-t.c139
-rw-r--r--unittest/mysys/stacktrace-t.c67
-rw-r--r--unittest/unit.pl2
-rw-r--r--vio/viosocket.c2
-rw-r--r--win/packaging/heidisql.cmake2
-rw-r--r--win/packaging/heidisql.wxi.in28
889 files changed, 20093 insertions, 8614 deletions
diff --git a/.gitignore b/.gitignore
index 4a633f79f04..da399198eb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -226,6 +226,8 @@ support-files/mysqld_multi.server
support-files/wsrep.cnf
support-files/wsrep_notify
support-files/policy/selinux/mysqld-safe.pp
+support-files/sysusers.conf
+support-files/tmpfiles.conf
tags
tests/async_queries
tests/bug25714
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 083fa753b88..660b3ee46bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -144,8 +144,6 @@ INCLUDE(mysql_version)
INCLUDE(cpack_source_ignore_files)
INCLUDE(install_layout)
INCLUDE(wsrep)
-INCLUDE(cpack_rpm)
-INCLUDE(cpack_deb)
# Add macros
INCLUDE(character_sets)
@@ -188,6 +186,7 @@ ENDIF()
OPTION(NOT_FOR_DISTRIBUTION "Allow linking with GPLv2-incompatible system libraries. Only set it you never plan to distribute the resulting binaries" OFF)
INCLUDE(check_compiler_flag)
+INCLUDE(check_linker_flag)
OPTION(WITH_ASAN "Enable address sanitizer" OFF)
IF (WITH_ASAN)
@@ -236,7 +235,7 @@ IF(SECURITY_HARDENED)
ENDIF()
# security-enhancing flags
MY_CHECK_AND_SET_COMPILER_FLAG("-pie -fPIC")
- MY_CHECK_AND_SET_COMPILER_FLAG("-Wl,-z,relro,-z,now")
+ MY_CHECK_AND_SET_LINKER_FLAG("-Wl,-z,relro,-z,now")
MY_CHECK_AND_SET_COMPILER_FLAG("-fstack-protector --param=ssp-buffer-size=4")
MY_CHECK_AND_SET_COMPILER_FLAG("-D_FORTIFY_SOURCE=2" RELEASE RELWITHDEBINFO)
ENDIF()
@@ -395,6 +394,9 @@ IF(WITH_UNIT_TESTS)
ENDIF()
ENDIF()
+INCLUDE(cpack_rpm)
+INCLUDE(cpack_deb)
+
SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
# Add storage engines and plugins.
CONFIGURE_PLUGINS()
diff --git a/VERSION b/VERSION
index c4402b8a39e..1c88e2091d0 100644
--- a/VERSION
+++ b/VERSION
@@ -1,3 +1,3 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=1
-MYSQL_VERSION_PATCH=44
+MYSQL_VERSION_PATCH=48
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 00000000000..d94b58b524e
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,22 @@
+version: build-{build}~branch-{branch}
+
+before_build:
+ - md %APPVEYOR_BUILD_FOLDER%\win_build
+ - cd %APPVEYOR_BUILD_FOLDER%\win_build
+ - cmake .. -G "Visual Studio 15 2017 Win64" -DWITH_UNIT_TESTS=0 -DWITH_MARIABACKUP=0 -DMYSQL_MAINTAINER_MODE=ERR -DPLUGIN_ROCKSDB=NO -DPLUGIN_CONNECT=NO -DBISON_EXECUTABLE=C:\cygwin64\bin\bison -DCMAKE_CXX_FLAGS='/W0' -DCMAKE_C_FLAGS='/W0'
+# note, don't merge /W0 to 10.2
+
+build:
+ project: win_build\MySQL.sln
+ parallel: true
+ verbosity: minimal
+
+configuration: RelWithDebInfo
+platform: x64
+
+test_script:
+ - set PATH=%PATH%;C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
+ - cd %APPVEYOR_BUILD_FOLDER%\win_build\mysql-test
+ - perl mysql-test-run.pl --force --max-test-fail=10 --parallel=4 --testcase-timeout=10 --skip-test-list=unstable-tests --suite=main
+
+image: Visual Studio 2017
diff --git a/client/client_priv.h b/client/client_priv.h
index 1668227cc96..34c44e41a08 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -93,6 +93,7 @@ enum options_client
OPT_REPORT_PROGRESS,
OPT_SKIP_ANNOTATE_ROWS_EVENTS,
OPT_SSL_CRL, OPT_SSL_CRLPATH,
+ OPT_IGNORE_DATA,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};
diff --git a/client/mysql.cc b/client/mysql.cc
index 47268887fbf..1686ba54b64 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1298,8 +1298,8 @@ sig_handler mysql_end(int sig)
{
#ifndef _WIN32
/*
- Ingnoring SIGQUIT and SIGINT signals when cleanup process starts.
- This will help in resolving the double free issues, which occures in case
+ Ignoring SIGQUIT and SIGINT signals when cleanup process starts.
+ This will help in resolving the double free issues, which occurs in case
the signal handler function is started in between the clean up function.
*/
signal(SIGQUIT, SIG_IGN);
@@ -4721,7 +4721,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
mysql.reconnect= debug_info_flag; // We want to know if this happens
/*
- CLIENT_PROGRESS is set only if we requsted it in mysql_real_connect()
+ CLIENT_PROGRESS is set only if we requested it in mysql_real_connect()
and the server also supports it
*/
if (mysql.client_flag & CLIENT_PROGRESS)
@@ -4789,7 +4789,7 @@ com_status(String *buffer __attribute__((unused)),
tee_fprintf(stdout, "\nConnection id:\t\t%lu\n",mysql_thread_id(&mysql));
/*
Don't remove "limit 1",
- it is protection againts SQL_SELECT_LIMIT=0
+ it is protection against SQL_SELECT_LIMIT=0
*/
if (!mysql_store_result_for_lazy(&result))
{
@@ -5162,7 +5162,7 @@ static const char *construct_prompt()
time_t lclock = time(NULL); // Get the date struct
struct tm *t = localtime(&lclock);
- /* parse thru the settings for the prompt */
+ /* parse through the settings for the prompt */
for (char *c = current_prompt; *c ; c++)
{
if (*c != PROMPT_CHAR)
diff --git a/client/mysql_plugin.c b/client/mysql_plugin.c
index 682a2365a92..f50c3388b70 100644
--- a/client/mysql_plugin.c
+++ b/client/mysql_plugin.c
@@ -1019,7 +1019,7 @@ static int find_plugin(char *tp_path)
/**
- Build the boostrap file.
+ Build the bootstrap file.
Create a new file and populate it with SQL commands to ENABLE or DISABLE
the plugin via REPLACE and DELETE operations on the mysql.plugin table.
@@ -1148,7 +1148,7 @@ exit:
Create a command line sequence to launch mysqld in bootstrap mode. This
will allow mysqld to launch a minimal server instance to read and
- execute SQL commands from a file piped in (the boostrap file). We use
+ execute SQL commands from a file piped in (the bootstrap file). We use
the --no-defaults option to skip reading values from the config file.
The bootstrap mode skips loading of plugins and many other subsystems.
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index d18dc97c9b8..8da7a4b01f2 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -18,7 +18,7 @@
#include "client_priv.h"
#include <sslopt-vars.h>
-#include "../scripts/mysql_fix_privilege_tables_sql.c"
+#include <../scripts/mysql_fix_privilege_tables_sql.c>
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 11dc98943dd..449e4f0e8a9 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
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
@@ -161,7 +161,7 @@ enum Exit_status {
*/
static Annotate_rows_log_event *annotate_event= NULL;
-void free_annotate_event()
+static void free_annotate_event()
{
if (annotate_event)
{
@@ -725,7 +725,7 @@ static bool shall_skip_database(const char *log_dbname)
/**
Print "use <db>" statement when current db is to be changed.
- We have to control emiting USE statements according to rewrite-db options.
+ We have to control emitting USE statements according to rewrite-db options.
We have to do it here (see process_event() below) and to suppress
producing USE statements by corresponding log event print-functions.
*/
@@ -757,7 +757,7 @@ print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev)
// In case of rewrite rule print USE statement for db_to
my_fprintf(result_file, "use %`s%s\n", db_to, pinfo->delimiter);
- // Copy the *original* db to pinfo to suppress emiting
+ // Copy the *original* db to pinfo to suppress emitting
// of USE stmts by log_event print-functions.
memcpy(pinfo->db, db, db_len + 1);
}
@@ -860,7 +860,8 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev)
ev->print(result_file, print_event_info);
return
print_event_info->head_cache.error == -1 ||
- print_event_info->body_cache.error == -1;
+ print_event_info->body_cache.error == -1 ||
+ print_event_info->tail_cache.error == -1;
}
@@ -871,7 +872,7 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
print_event_info->m_table_map_ignored.get_table(table_id);
bool skip_event= (ignored_map != NULL);
- /*
+ /*
end of statement check:
i) destroy/free ignored maps
ii) if skip event
@@ -882,21 +883,21 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
*/
if (is_stmt_end)
{
- /*
+ /*
Now is safe to clear ignored map (clear_tables will also
delete original table map events stored in the map).
*/
if (print_event_info->m_table_map_ignored.count() > 0)
print_event_info->m_table_map_ignored.clear_tables();
- /*
+ /*
If there is a kept Annotate event and all corresponding
rbr-events were filtered away, the Annotate event was not
freed and it is just the time to do it.
*/
- free_annotate_event();
+ free_annotate_event();
- /*
+ /*
One needs to take into account an event that gets
filtered but was last event in the statement. If this is
the case, previous rows events that were written into
@@ -912,8 +913,12 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
my_b_printf(body_cache, "'%s\n", print_event_info->delimiter);
// flush cache
- if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
- copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
+ if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
+ result_file) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->body_cache,
+ result_file) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->tail_cache,
+ result_file)))
return 1;
}
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 44f9849306f..44643c8262b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -32,7 +32,7 @@
** master/autocommit code by Brian Aker <brian@tangent.org>
** SSL by
** Andrei Errapart <andreie@no.spam.ee>
-** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
+** Tõnu Samuel <tonu@please.do.not.remove.this.spam.ee>
** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up
** and adapted to mysqldump 05/11/01 by Jani Tolonen
** Added --single-transaction option 06/06/2002 by Peter Zaitsev
@@ -90,6 +90,7 @@
/* Max length GTID position that we will output. */
#define MAX_GTID_LENGTH 1024
+static my_bool ignore_table_data(const uchar *hash_key, size_t len);
static void add_load_option(DYNAMIC_STRING *str, const char *option,
const char *option_value);
static ulong find_set(TYPELIB *, const char *, size_t, char **, uint *);
@@ -142,7 +143,7 @@ static char * opt_mysql_unix_port=0;
static int first_error=0;
/*
multi_source is 0 if old server or 2 if server that support multi source
- This is choosen this was as multi_source has 2 extra columns first in
+ This is chosen this was as multi_source has 2 extra columns first in
SHOW ALL SLAVES STATUS.
*/
static uint multi_source= 0;
@@ -210,7 +211,7 @@ TYPELIB compatible_mode_typelib= {array_elements(compatible_mode_names) - 1,
#define MED_ENGINES "MRG_MyISAM, MRG_ISAM, CONNECT, OQGRAPH, SPIDER, VP, FEDERATED"
-HASH ignore_table;
+HASH ignore_table, ignore_data;
static struct my_option my_long_options[] =
{
@@ -371,6 +372,12 @@ static struct my_option my_long_options[] =
&opt_hex_blob, &opt_hex_blob, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Connect to host.", &current_host,
&current_host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"ignore-table-data", OPT_IGNORE_DATA,
+ "Do not dump the specified table data. To specify more than one table "
+ "to ignore, use the directive multiple times, once for each table. "
+ "Each table must be specified with both database and table names, e.g., "
+ "--ignore-table-data=database.table.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"ignore-table", OPT_IGNORE_TABLE,
"Do not dump the specified table. To specify more than one table to ignore, "
"use the directive multiple times, once for each table. Each table must "
@@ -895,6 +902,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case (int) OPT_TABLES:
opt_databases=0;
break;
+ case (int) OPT_IGNORE_DATA:
+ {
+ if (!strchr(argument, '.'))
+ {
+ fprintf(stderr,
+ "Illegal use of option --ignore-table-data=<database>.<table>\n");
+ exit(1);
+ }
+ if (my_hash_insert(&ignore_data, (uchar*)my_strdup(argument, MYF(0))))
+ exit(EX_EOM);
+ break;
+ }
case (int) OPT_IGNORE_TABLE:
{
if (!strchr(argument, '.'))
@@ -993,6 +1012,10 @@ static int get_options(int *argc, char ***argv)
(uchar*) my_strdup("mysql.slow_log", MYF(MY_WME))))
return(EX_EOM);
+ if (my_hash_init(&ignore_data, charset_info, 16, 0, 0,
+ (my_hash_get_key) get_table_key, my_free, 0))
+ return(EX_EOM);
+
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
return(ho_error);
@@ -1637,6 +1660,8 @@ static void free_resources()
free_root(&glob_root, MYF(0));
if (my_hash_inited(&ignore_table))
my_hash_free(&ignore_table);
+ if (my_hash_inited(&ignore_data))
+ my_hash_free(&ignore_data);
dynstr_free(&extended_row);
dynstr_free(&dynamic_where);
dynstr_free(&insert_pat);
@@ -2010,7 +2035,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg,
<stag_atr="sval" xsi:nil="true"/>
NOTE
sval MUST be a NULL terminated string.
- sval string will be qouted before output.
+ sval string will be quoted before output.
*/
static void print_xml_null_tag(FILE * xml_file, const char* sbeg,
@@ -2082,7 +2107,7 @@ static void print_xml_cdata(FILE *xml_file, const char *str, ulong len)
Print tag with many attribute to the xml_file. Format is:
\t\t<row_name Atr1="Val1" Atr2="Val2"... />
NOTE
- All atributes and values will be quoted before output.
+ All attributes and values will be quoted before output.
*/
static void print_xml_row(FILE *xml_file, const char *row_name,
@@ -2553,7 +2578,7 @@ static uint dump_routines_for_db(char *db)
print_comment(sql_file, 1,
"-- does %s have permissions on mysql.proc?\n\n",
fix_for_comment(current_user));
- maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!",
+ maybe_die(EX_MYSQLERR,"%s has insufficient privileges to %s!",
current_user, query_buff);
}
else if (strlen(row[2]))
@@ -3601,7 +3626,7 @@ static char *alloc_query_str(ulong size)
*/
-static void dump_table(char *table, char *db)
+static void dump_table(char *table, char *db, const uchar *hash_key, size_t len)
{
char ignore_flag;
char buf[200], table_buff[NAME_LEN+3];
@@ -3629,7 +3654,7 @@ static void dump_table(char *table, char *db)
DBUG_VOID_RETURN;
/* Check --no-data flag */
- if (opt_no_data)
+ if (opt_no_data || (hash_key && ignore_table_data(hash_key, len)))
{
verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n",
table);
@@ -4046,7 +4071,7 @@ static void dump_table(char *table, char *db)
}
}
- /* XML - close table tag and supress regular output */
+ /* XML - close table tag and suppress regular output */
if (opt_xml)
fputs("\t</table_data>\n", md_result_file);
else if (extended_insert && row_break)
@@ -4452,7 +4477,7 @@ static int dump_databases(char **db_names)
/*
-View Specific database initalization.
+View Specific database initialization.
SYNOPSIS
init_dumping_views
@@ -4469,7 +4494,7 @@ int init_dumping_views(char *qdatabase __attribute__((unused)))
/*
-Table Specific database initalization.
+Table Specific database initialization.
SYNOPSIS
init_dumping_tables
@@ -4557,10 +4582,14 @@ static int init_dumping(char *database, int init_func(char*))
/* Return 1 if we should copy the table */
-my_bool include_table(const uchar *hash_key, size_t len)
+static my_bool include_table(const uchar *hash_key, size_t len)
{
return ! my_hash_search(&ignore_table, hash_key, len);
}
+static my_bool ignore_table_data(const uchar *hash_key, size_t len)
+{
+ return my_hash_search(&ignore_data, hash_key, len) != NULL;
+}
static int dump_all_tables_in_db(char *database)
@@ -4625,7 +4654,7 @@ static int dump_all_tables_in_db(char *database)
char *end= strmov(afterdot, table);
if (include_table((uchar*) hash_key, end - hash_key))
{
- dump_table(table,database);
+ dump_table(table, database, (uchar*) hash_key, end - hash_key);
my_free(order_by);
order_by= 0;
if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009)
@@ -5014,7 +5043,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
for (pos= dump_tables; pos < end; pos++)
{
DBUG_PRINT("info",("Dumping table %s", *pos));
- dump_table(*pos, db);
+ dump_table(*pos, db, NULL, 0);
if (opt_dump_triggers &&
mysql_get_server_version(mysql) >= 50009)
{
@@ -5995,6 +6024,7 @@ int main(int argc, char **argv)
compatible_mode_normal_str[0]= 0;
default_charset= (char *)mysql_universal_client_charset;
bzero((char*) &ignore_table, sizeof(ignore_table));
+ bzero((char*) &ignore_data, sizeof(ignore_data));
exit_code= get_options(&argc, &argv);
if (exit_code)
@@ -6149,7 +6179,7 @@ int main(int argc, char **argv)
goto err;
/*
- No reason to explicitely COMMIT the transaction, neither to explicitely
+ No reason to explicitly COMMIT the transaction, neither to explicitly
UNLOCK TABLES: these will be automatically be done by the server when we
disconnect now. Saves some code here, some network trips, adds nothing to
server.
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 4cd51477e32..22e549d8d9c 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -589,7 +589,7 @@ static char *field_escape(char *to,const char *from,uint length)
else
{
if (*from == '\'' && !end_backslashes)
- *to++= *from; /* We want a dublicate of "'" for MySQL */
+ *to++= *from; /* We want a duplicate of "'" for MySQL */
end_backslashes=0;
}
}
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 5dca3fae2cb..a1db7c887eb 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -2302,7 +2302,7 @@ slap_connect(MYSQL *mysql)
opt_mysql_unix_port,
connect_flags))
{
- /* Connect suceeded */
+ /* Connect succeeded */
connect_error= 0;
break;
}
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 1f17f75e1b8..598fb54e72e 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -145,7 +145,7 @@ struct property {
my_bool *var; /* Actual variable */
my_bool set; /* Has been set for ONE command */
my_bool old; /* If set, thus is the old value */
- my_bool reverse; /* Varible is true if disabled */
+ my_bool reverse; /* Variable is true if disabled */
const char *env_name; /* Env. variable name */
};
@@ -555,7 +555,7 @@ DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */
Temporary storage areas for substitutions. To reduce unnessary copying
and memory freeing/allocation, we pre-allocate two buffers, and alternate
their use, one for input/one for output, the roles changing on the next
-st_regex substition. At the end of substitutions buf points to the
+st_regex substitution. At the end of substitutions buf points to the
one containing the final result.
*/
char* buf;
@@ -1103,71 +1103,6 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query,
/*
- Run query and dump the result to stderr in vertical format
-
- NOTE! This function should be safe to call when an error
- has occurred and thus any further errors will be ignored (although logged)
-
- SYNOPSIS
- show_query
- mysql - connection to use
- query - query to run
-
-*/
-
-static void show_query(MYSQL* mysql, const char* query)
-{
- MYSQL_RES* res;
- DBUG_ENTER("show_query");
-
- if (!mysql)
- DBUG_VOID_RETURN;
-
- if (mysql_query(mysql, query))
- {
- log_msg("Error running query '%s': %d %s",
- query, mysql_errno(mysql), mysql_error(mysql));
- DBUG_VOID_RETURN;
- }
-
- if ((res= mysql_store_result(mysql)) == NULL)
- {
- /* No result set returned */
- DBUG_VOID_RETURN;
- }
-
- {
- MYSQL_ROW row;
- unsigned int i;
- unsigned int row_num= 0;
- unsigned int num_fields= mysql_num_fields(res);
- MYSQL_FIELD *fields= mysql_fetch_fields(res);
-
- fprintf(stderr, "=== %s ===\n", query);
- while ((row= mysql_fetch_row(res)))
- {
- unsigned long *lengths= mysql_fetch_lengths(res);
- row_num++;
-
- fprintf(stderr, "---- %d. ----\n", row_num);
- for(i= 0; i < num_fields; i++)
- {
- fprintf(stderr, "%s\t%.*s\n",
- fields[i].name,
- (int)lengths[i], row[i] ? row[i] : "NULL");
- }
- }
- for (i= 0; i < strlen(query)+8; i++)
- fprintf(stderr, "=");
- fprintf(stderr, "\n\n");
- }
- mysql_free_result(res);
-
- DBUG_VOID_RETURN;
-}
-
-
-/*
Show any warnings just before the error. Since the last error
is added to the warning stack, only print @@warning_count-1 warnings.
@@ -3121,7 +3056,7 @@ void open_file(const char *name)
strxnmov(buff, sizeof(buff), opt_overlay_dir, suffix, name, NullS);
/*
- Overlayed rty/include/thing.inc can contain the line
+ Overlaid rty/include/thing.inc can contain the line
--source thing.inc
which would mean to include qwe/include/thing.inc.
But it looks like including "itself", so don't try to open the file,
@@ -4023,7 +3958,7 @@ static int rmtree(const char *dir)
#ifdef _WIN32
/*
On Windows, check and possible reset readonly attribute.
- my_delete(), or DeleteFile does not remove theses files.
+ my_delete(), or DeleteFile does not remove these files.
*/
if (err)
{
@@ -4829,9 +4764,6 @@ void do_sync_with_master2(struct st_command *command, long offset,
if (!result_str || result < 0)
{
/* master_pos_wait returned NULL or < 0 */
- show_query(mysql, "SHOW MASTER STATUS");
- show_query(mysql, "SHOW SLAVE STATUS");
- show_query(mysql, "SHOW PROCESSLIST");
fprintf(stderr, "analyze: sync_with_master\n");
if (!result_str)
@@ -4908,7 +4840,7 @@ int do_save_master_pos()
mysql_errno(mysql), mysql_error(mysql));
if (!(res = mysql_store_result(mysql)))
- die("mysql_store_result() retuned NULL for '%s'", query);
+ die("mysql_store_result() returned NULL for '%s'", query);
if (!(row = mysql_fetch_row(res)))
die("empty result in show master status");
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
@@ -5426,7 +5358,7 @@ void do_get_errcodes(struct st_command *command)
p++;
}
- /* Convert the sting to int */
+ /* Convert the string to int */
if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val))
die("Invalid argument to error: '%s'", command->first_argument);
@@ -5834,7 +5766,7 @@ int connect_n_handle_errors(struct st_command *command,
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1);
}
- /* Simlified logging if enabled */
+ /* Simplified logging if enabled */
if (!disable_connect_log && !disable_query_log)
{
replace_dynstr_append(ds, command->query);
@@ -8198,7 +8130,7 @@ void handle_no_error(struct st_command *command)
SYNPOSIS
run_query_stmt
mysql - mysql handle
- command - currrent command pointer
+ command - current command pointer
query - query string to execute
query_len - length query string to execute
ds - output buffer where to store result form query
@@ -8426,7 +8358,7 @@ end:
/*
Create a util connection if one does not already exists
and use that to run the query
- This is done to avoid implict commit when creating/dropping objects such
+ This is done to avoid implicit commit when creating/dropping objects such
as view, sp etc.
*/
@@ -8467,7 +8399,7 @@ int util_query(MYSQL* org_mysql, const char* query){
SYNPOSIS
run_query()
mysql mysql handle
- command currrent command pointer
+ command current command pointer
flags control the phased/stages of query execution to be performed
if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG
@@ -10223,7 +10155,7 @@ int multi_reg_replace(struct st_replace_regex* r,char* val)
if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace,
in_buf, re.icase))
{
- /* if the buffer has been reallocated, make adjustements */
+ /* if the buffer has been reallocated, make adjustments */
if (save_out_buf != out_buf)
{
if (save_out_buf == r->even_buf)
@@ -10488,7 +10420,7 @@ typedef struct st_rep_set {
uint found_len; /* Best match to date */
int found_offset;
uint table_offset;
- uint size_of_bits; /* For convinience */
+ uint size_of_bits; /* For convenience */
} REP_SET;
typedef struct st_rep_sets {
@@ -10591,7 +10523,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
DBUG_RETURN(0);
}
(void) make_new_set(&sets); /* Set starting set */
- make_sets_invisible(&sets); /* Hide previus sets */
+ make_sets_invisible(&sets); /* Hide previous sets */
used_sets=-1;
word_states=make_new_set(&sets); /* Start of new word */
start_states=make_new_set(&sets); /* This is first state */
diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake
index 2a8461bf370..5af197c7f11 100644
--- a/cmake/build_configurations/mysql_release.cmake
+++ b/cmake/build_configurations/mysql_release.cmake
@@ -118,7 +118,7 @@ ENDIF()
IF(UNIX)
SET(WITH_EXTRA_CHARSETS all CACHE STRING "")
- SET(PLUGIN_AUTH_PAM YES)
+ SET(PLUGIN_AUTH_PAM YES CACHE BOOL "")
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
IF(NOT IGNORE_AIO_CHECK)
diff --git a/cmake/check_linker_flag.cmake b/cmake/check_linker_flag.cmake
new file mode 100644
index 00000000000..1ea1772d79e
--- /dev/null
+++ b/cmake/check_linker_flag.cmake
@@ -0,0 +1,27 @@
+include(CheckCXXSourceCompiles)
+
+FUNCTION(MY_CHECK_AND_SET_LINKER_FLAG flag_to_set)
+ # Let's avoid expensive compiler tests on Windows:
+ IF(WIN32)
+ RETURN()
+ ENDIF()
+ STRING(REGEX REPLACE "[-,= +]" "_" result "HAVE_LINK_FLAG_${flag_to_set}")
+ SET(SAVE_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
+ STRING(REGEX REPLACE "^-Wno-" "-W" flag_to_check ${flag_to_set})
+ SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${flag_to_check})
+ CHECK_CXX_SOURCE_COMPILES("int main(void) { return 0; }" ${result})
+ SET(CMAKE_REQUIRED_LIBRARIES "${SAVE_CMAKE_REQUIRED_LIBRARIES}")
+ IF (${result})
+ FOREACH(linktype SHARED MODULE EXE)
+ IF(ARGN)
+ FOREACH(type ${ARGN})
+ SET(CMAKE_${linktype}_LINKER_FLAGS_${type}
+ "${CMAKE_${linktype}_LINKER_FLAGS_${type}} ${flag_to_set}" PARENT_SCOPE)
+ ENDFOREACH()
+ ELSE()
+ SET(CMAKE_${linktype}_LINKER_FLAGS
+ "${CMAKE_${linktype}_LINKER_FLAGS} ${flag_to_set}" PARENT_SCOPE)
+ ENDIF()
+ ENDFOREACH()
+ ENDIF()
+ENDFUNCTION()
diff --git a/cmake/configure.pl b/cmake/configure.pl
index 70122664ad4..45847aa576f 100644
--- a/cmake/configure.pl
+++ b/cmake/configure.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake
index ae9e3b904b3..a0449b5918d 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -232,6 +232,14 @@ ELSEIF(RPM MATCHES "fedora" OR RPM MATCHES "(rhel|centos)7")
ALTERNATIVE_NAME("shared" "mysql-libs")
ALTERNATIVE_NAME("test" "mariadb-test")
SET(CPACK_RPM_common_PACKAGE_CONFLICTS "mariadb-libs < 1:%{version}-%{release}")
+ELSEIF(RPM MATCHES "sles")
+ ALTERNATIVE_NAME("server" "mariadb")
+ SETA(CPACK_RPM_server_PACKAGE_PROVIDES
+ "mysql = %{version}-%{release}"
+ "mariadb_${MAJOR_VERSION}${MINOR_VERSION} = %{version}-%{release}"
+ "mariadb-${MAJOR_VERSION}${MINOR_VERSION} = %{version}-%{release}"
+ "mariadb-server = %{version}-%{release}"
+ )
ENDIF()
# If we want to build build MariaDB-shared-compat,
diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake
index 4e0f7501045..d3dded99497 100644
--- a/cmake/dtrace.cmake
+++ b/cmake/dtrace.cmake
@@ -43,7 +43,8 @@ MACRO(CHECK_DTRACE)
IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD"
AND NOT BUGGY_GCC_NO_DTRACE_MODULES
AND NOT BUGGY_LINUX_DTRACE
- AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS")
+ AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS"
+ AND NOT WIN32)
SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace")
ENDIF()
# On GNU/Hurd, dtrace is not supported
diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake
index 0c05b06208f..bb89a57ab11 100644
--- a/cmake/install_macros.cmake
+++ b/cmake/install_macros.cmake
@@ -162,17 +162,13 @@ ENDFUNCTION()
# and extension will be the same as for target file.
MACRO(INSTALL_SYMLINK linkname target destination component)
IF(UNIX)
- GET_TARGET_PROPERTY(location ${target} LOCATION)
- GET_FILENAME_COMPONENT(path ${location} PATH)
- GET_FILENAME_COMPONENT(name ${location} NAME)
- SET(output ${path}/${linkname})
+ SET(output ${CMAKE_CURRENT_BINARY_DIR}/${linkname})
ADD_CUSTOM_COMMAND(
OUTPUT ${output}
- COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${output}
+ COMMAND ${CMAKE_COMMAND} ARGS -E remove -f ${linkname}
COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink
- ${name}
+ $<TARGET_FILE_NAME:${target}>
${linkname}
- WORKING_DIRECTORY ${path}
DEPENDS ${target}
)
diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake
index 8c2deeb8e40..9c51cb797bb 100644
--- a/cmake/maintainer.cmake
+++ b/cmake/maintainer.cmake
@@ -1,4 +1,5 @@
# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, MariaDB
#
# 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
@@ -28,11 +29,16 @@ SET(MY_WARNING_FLAGS
-Woverloaded-virtual
-Wvla
-Wwrite-strings
- -Werror
)
+FOREACH(F ${MY_WARNING_FLAGS})
+ MY_CHECK_AND_SET_COMPILER_FLAG(${F} DEBUG RELWITHDEBINFO)
+ENDFOREACH()
+
+SET(MY_ERROR_FLAGS -Werror)
+
IF(CMAKE_COMPILER_IS_GNUCC AND CMAKE_C_COMPILER_VERSION VERSION_LESS "6.0.0")
- SET(MY_WARNING_FLAGS ${MY_WARNING_FLAGS} -Wno-error=maybe-uninitialized)
+ SET(MY_ERROR_FLAGS ${MY_ERROR_FLAGS} -Wno-error=maybe-uninitialized)
ENDIF()
IF(MYSQL_MAINTAINER_MODE MATCHES "OFF")
@@ -41,7 +47,7 @@ ELSEIF(MYSQL_MAINTAINER_MODE MATCHES "AUTO")
SET(WHERE DEBUG)
ENDIF()
-FOREACH(F ${MY_WARNING_FLAGS})
+FOREACH(F ${MY_ERROR_FLAGS})
MY_CHECK_AND_SET_COMPILER_FLAG(${F} ${WHERE})
ENDFOREACH()
diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake
index a4d46df2af6..742f374e99f 100644
--- a/cmake/os/WindowsCache.cmake
+++ b/cmake/os/WindowsCache.cmake
@@ -35,7 +35,6 @@ SET(HAVE_BFILL CACHE INTERNAL "")
SET(HAVE_BMOVE CACHE INTERNAL "")
SET(HAVE_BSD_SIGNALS CACHE INTERNAL "")
SET(HAVE_BSEARCH 1 CACHE INTERNAL "")
-SET(HAVE_BSS_START CACHE INTERNAL "")
SET(HAVE_BZERO CACHE INTERNAL "")
SET(HAVE_CHOWN CACHE INTERNAL "")
SET(HAVE_CLOCK_GETTIME CACHE INTERNAL "")
diff --git a/config.h.cmake b/config.h.cmake
index eb3e6228bf7..17e449fbab2 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -312,7 +312,6 @@
/* Symbols we may use */
#cmakedefine HAVE_SYS_ERRLIST 1
/* used by stacktrace functions */
-#cmakedefine HAVE_BSS_START 1
#cmakedefine HAVE_BACKTRACE 1
#cmakedefine HAVE_BACKTRACE_SYMBOLS 1
#cmakedefine HAVE_BACKTRACE_SYMBOLS_FD 1
diff --git a/configure.cmake b/configure.cmake
index 8d477abc91b..36655fd4348 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -936,14 +936,6 @@ CHECK_CXX_SOURCE_COMPILES("
ENDIF()
CHECK_C_SOURCE_COMPILES("
- int main(int argc, char **argv)
- {
- extern char *__bss_start;
- return __bss_start ? 1 : 0;
- }"
-HAVE_BSS_START)
-
-CHECK_C_SOURCE_COMPILES("
int main()
{
extern void __attribute__((weak)) foo(void);
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 21f86ded0a5..007769c3c37 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -330,10 +330,13 @@ static void LockMutex(CODE_STATE *cs)
{
if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug);
+ cs->locked++;
}
static void UnlockMutex(CODE_STATE *cs)
{
- if (!cs->locked)
+ --cs->locked;
+ assert(cs->locked >= 0);
+ if (cs->locked == 0)
pthread_mutex_unlock(&THR_LOCK_dbug);
}
static void LockIfInitSettings(CODE_STATE *cs)
@@ -483,6 +486,7 @@ static int DbugParse(CODE_STATE *cs, const char *control)
rel= control[0] == '+' || control[0] == '-';
if ((!rel || (!stack->out_file && !stack->next)))
{
+ LockIfInitSettings(cs);
FreeState(cs, 0);
stack->flags= 0;
stack->delay= 0;
@@ -490,10 +494,9 @@ static int DbugParse(CODE_STATE *cs, const char *control)
stack->sub_level= 0;
stack->out_file= sstderr;
stack->functions= NULL;
- LockIfInitSettings(cs);
stack->keywords= NULL;
- UnlockIfInitSettings(cs);
stack->processes= NULL;
+ UnlockIfInitSettings(cs);
}
else if (!stack->out_file)
{
diff --git a/dbug/dbug_add_tags.pl b/dbug/dbug_add_tags.pl
index 7be8fb9b18d..f117bdcd65b 100755
--- a/dbug/dbug_add_tags.pl
+++ b/dbug/dbug_add_tags.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2002 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/dbug/remove_function_from_trace.pl b/dbug/remove_function_from_trace.pl
index 380df168caf..67d7fa54b6a 100755
--- a/dbug/remove_function_from_trace.pl
+++ b/dbug/remove_function_from_trace.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
die <<EEE unless @ARGV;
Usage: $0 func1 [func2 [ ...] ]
diff --git a/debian/additions/innotop/innotop b/debian/additions/innotop/innotop
index ee0488580f6..b995f44a007 100644
--- a/debian/additions/innotop/innotop
+++ b/debian/additions/innotop/innotop
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
# vim: tw=160:nowrap:expandtab:tabstop=3:shiftwidth=3:softtabstop=3
diff --git a/debian/additions/mysqlreport b/debian/additions/mysqlreport
index 64eaf93783a..86a57bff19c 100755
--- a/debian/additions/mysqlreport
+++ b/debian/additions/mysqlreport
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/perl
# mysqlreport v4.0 Oct 23 2015
# http://hackmysql.com/mysqlreport
diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt
index 9e5b8506658..edbb4e28ab2 100644
--- a/extra/mariabackup/CMakeLists.txt
+++ b/extra/mariabackup/CMakeLists.txt
@@ -94,7 +94,7 @@ ENDIF()
########################################################################
-# xbstream binary
+# mbstream binary
########################################################################
MYSQL_ADD_EXECUTABLE(mbstream
ds_buffer.c
diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc
index 5382f876f74..e3cb7fa5cde 100644
--- a/extra/mariabackup/innobackupex.cc
+++ b/extra/mariabackup/innobackupex.cc
@@ -600,8 +600,8 @@ static struct my_option ibx_long_options[] =
{"stream", OPT_STREAM, "This option specifies the format in which to "
"do the streamed backup. The option accepts a string argument. The "
"backup will be done to STDOUT in the specified format. Currently, "
- "the only supported formats are tar and xbstream. This option is "
- "passed directly to xtrabackup's --stream option.",
+ "the only supported formats are tar and mbstream/xbstream. This "
+ "option is passed directly to xtrabackup's --stream option.",
(uchar*) &ibx_xtrabackup_stream_str,
(uchar*) &ibx_xtrabackup_stream_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -669,7 +669,7 @@ innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chu
[--include=REGEXP] [--user=NAME]\n\
[--password=WORD] [--port=PORT] [--socket=SOCKET]\n\
[--no-timestamp] [--ibbackup=IBBACKUP-BINARY]\n\
- [--slave-info] [--galera-info] [--stream=tar|xbstream]\n\
+ [--slave-info] [--galera-info] [--stream=tar|mbstream|xbstream]\n\
[--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME]\n\
[--databases=LIST] [--no-lock] \n\
[--tmpdir=DIRECTORY] [--tables-file=FILE]\n\
@@ -765,7 +765,8 @@ ibx_get_one_option(int optid,
}
break;
case OPT_STREAM:
- if (!strcasecmp(argument, "xbstream"))
+ if (!strcasecmp(argument, "mbstream") ||
+ !strcasecmp(argument, "xbstream"))
xtrabackup_stream_fmt = XB_STREAM_FMT_XBSTREAM;
else {
ibx_msg("Invalid --stream argument: %s\n", argument);
diff --git a/extra/mariabackup/xbstream.c b/extra/mariabackup/xbstream.c
index 59e0095f63c..6a4b203a684 100644
--- a/extra/mariabackup/xbstream.c
+++ b/extra/mariabackup/xbstream.c
@@ -45,7 +45,6 @@ datasink_t datasink_archive;
datasink_t datasink_xbstream;
datasink_t datasink_compress;
datasink_t datasink_tmpfile;
-datasink_t datasink_buffer;
static run_mode_t opt_mode;
static char * opt_directory = NULL;
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index b9cb8a8007a..137ae021381 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -675,7 +675,7 @@ struct my_option xb_client_options[] =
{"stream", OPT_XTRA_STREAM, "Stream all backup files to the standard output "
"in the specified format."
- "Supported format is 'xbstream'."
+ "Supported format is 'mbstream' or 'xbstream'."
,
(G_PTR*) &xtrabackup_stream_str, (G_PTR*) &xtrabackup_stream_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1398,7 +1398,8 @@ xb_get_one_option(int optid,
xtrabackup_target_dir= xtrabackup_real_target_dir;
break;
case OPT_XTRA_STREAM:
- if (!strcasecmp(argument, "xbstream"))
+ if (!strcasecmp(argument, "mbstream") ||
+ !strcasecmp(argument, "xbstream"))
xtrabackup_stream_fmt = XB_STREAM_FMT_XBSTREAM;
else
{
diff --git a/extra/yassl/include/openssl/generate_prefix_files.pl b/extra/yassl/include/openssl/generate_prefix_files.pl
index d7609aebaf3..b66ffae6642 100755
--- a/extra/yassl/include/openssl/generate_prefix_files.pl
+++ b/extra/yassl/include/openssl/generate_prefix_files.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2006 MySQL AB
# Use is subject to license terms
diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h
index 0b7d73e5953..bd01cff69e4 100644
--- a/include/mysql/psi/mysql_file.h
+++ b/include/mysql/psi/mysql_file.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/mysql_idle.h b/include/mysql/psi/mysql_idle.h
index 1d054e644ac..64ac1a0503b 100644
--- a/include/mysql/psi/mysql_idle.h
+++ b/include/mysql/psi/mysql_idle.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h
index bf057c661bc..2ab6932e396 100644
--- a/include/mysql/psi/mysql_socket.h
+++ b/include/mysql/psi/mysql_socket.h
@@ -1,14 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the
-License.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License, version 2.0,
+as published by the Free Software Foundation.
+
+This program is also distributed with certain software (including
+but not limited to OpenSSL) that is licensed under separate terms,
+as designated in a particular file or component or in included license
+documentation. The authors of MySQL hereby grant you an additional
+permission to link the program and your derivative works with the
+separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -1042,10 +1048,14 @@ inline_mysql_socket_accept
#else
socket_accept.fd= accept(socket_listen.fd, addr, &addr_length);
#ifdef FD_CLOEXEC
- flags= fcntl(socket_accept.fd, F_GETFD);
- if (flags != -1) {
- flags |= FD_CLOEXEC;
- fcntl(socket_accept.fd, F_SETFD, flags);
+ if (socket_accept.fd != INVALID_SOCKET)
+ {
+ flags= fcntl(socket_accept.fd, F_GETFD);
+ if (flags != -1)
+ {
+ flags |= FD_CLOEXEC;
+ fcntl(socket_accept.fd, F_SETFD, flags);
+ }
}
#endif
#endif
@@ -1064,10 +1074,14 @@ inline_mysql_socket_accept
#else
socket_accept.fd= accept(socket_listen.fd, addr, &addr_length);
#ifdef FD_CLOEXEC
- flags= fcntl(socket_accept.fd, F_GETFD);
- if (flags != -1) {
- flags |= FD_CLOEXEC;
- fcntl(socket_accept.fd, F_SETFD, flags);
+ if (socket_accept.fd != INVALID_SOCKET)
+ {
+ flags= fcntl(socket_accept.fd, F_GETFD);
+ if (flags != -1)
+ {
+ flags |= FD_CLOEXEC;
+ fcntl(socket_accept.fd, F_SETFD, flags);
+ }
}
#endif
#endif
diff --git a/include/mysql/psi/mysql_stage.h b/include/mysql/psi/mysql_stage.h
index b6ab09fef55..1dbaed6c682 100644
--- a/include/mysql/psi/mysql_stage.h
+++ b/include/mysql/psi/mysql_stage.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/include/mysql/psi/mysql_statement.h b/include/mysql/psi/mysql_statement.h
index 767337dac9d..c6a49338312 100644
--- a/include/mysql/psi/mysql_statement.h
+++ b/include/mysql/psi/mysql_statement.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/include/mysql/psi/mysql_table.h b/include/mysql/psi/mysql_table.h
index 7b9ebcedd93..65666e9a550 100644
--- a/include/mysql/psi/mysql_table.h
+++ b/include/mysql/psi/mysql_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
index bea43943bb1..1408c06916d 100644
--- a/include/mysql/psi/mysql_thread.h
+++ b/include/mysql/psi/mysql_thread.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2013, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/psi.h b/include/mysql/psi/psi.h
index 6feb1f87fa7..3f7b04b0841 100644
--- a/include/mysql/psi/psi.h
+++ b/include/mysql/psi/psi.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/psi_abi_v0.h b/include/mysql/psi/psi_abi_v0.h
index 0601b61a5c7..ca4373f847b 100644
--- a/include/mysql/psi/psi_abi_v0.h
+++ b/include/mysql/psi/psi_abi_v0.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/psi_abi_v1.h b/include/mysql/psi/psi_abi_v1.h
index 2d5e81f5972..488e832c3ed 100644
--- a/include/mysql/psi/psi_abi_v1.h
+++ b/include/mysql/psi/psi_abi_v1.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/mysql/psi/psi_abi_v2.h b/include/mysql/psi/psi_abi_v2.h
index 420cc63fc13..67c054848a1 100644
--- a/include/mysql/psi/psi_abi_v2.h
+++ b/include/mysql/psi/psi_abi_v2.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/include/queues.h b/include/queues.h
index f341bbb8148..99e640413e3 100644
--- a/include/queues.h
+++ b/include/queues.h
@@ -55,7 +55,7 @@ typedef struct st_queue {
#define queue_top(queue) ((queue)->root[1])
#define queue_element(queue,index) ((queue)->root[index])
#define queue_end(queue) ((queue)->root[(queue)->elements])
-#define queue_replace_top(queue) _downheap(queue, 1, (queue)->root[1])
+#define queue_replace_top(queue) _downheap(queue, 1)
#define queue_set_cmp_arg(queue, set_arg) (queue)->first_cmp_arg= set_arg
#define queue_set_max_at_top(queue, set_arg) \
(queue)->max_at_top= set_arg ? -1 : 1
@@ -63,23 +63,23 @@ typedef struct st_queue {
typedef int (*queue_compare)(void *,uchar *, uchar *);
int init_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
+ my_bool max_at_top, queue_compare compare,
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent);
int reinit_queue(QUEUE *queue,uint max_elements,uint offset_to_key,
- pbool max_at_top, queue_compare compare,
+ my_bool max_at_top, queue_compare compare,
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent);
int resize_queue(QUEUE *queue, uint max_elements);
void delete_queue(QUEUE *queue);
-void queue_insert(QUEUE *queue,uchar *element);
+void queue_insert(QUEUE *queue, uchar *element);
int queue_insert_safe(QUEUE *queue, uchar *element);
uchar *queue_remove(QUEUE *queue,uint idx);
void queue_replace(QUEUE *queue,uint idx);
#define queue_remove_all(queue) { (queue)->elements= 0; }
#define queue_is_full(queue) (queue->elements == queue->max_elements)
-void _downheap(QUEUE *queue, uint idx, uchar *element);
+void _downheap(QUEUE *queue, uint idx);
void queue_fix(QUEUE *queue);
#define is_queue_inited(queue) ((queue)->root != 0)
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index 6580820a835..3ea3bfd57eb 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -21,7 +21,7 @@ SET(MAN1_SERVER innochecksum.1 my_print_defaults.1 myisam_ftdump.1 myisamchk.1
mysql_secure_installation.1 mysql_setpermission.1
mysql_tzinfo_to_sql.1 mysql_upgrade.1 mysql_zap.1
mysqld_multi.1 mysqld_safe.1 mysqldumpslow.1 mysqlhotcopy.1
- mysqltest.1 perror.1 replace.1 resolve_stack_dump.1
+ perror.1 replace.1 resolve_stack_dump.1
resolveip.1 mysqlbug.1 mariadb-service-convert.1
mysqld_safe_helper.1 tokuftdump.1 wsrep_sst_common.1
wsrep_sst_mysqldump.1 wsrep_sst_rsync.1
@@ -36,7 +36,8 @@ SET(MAN1_CLIENT msql2mysql.1 mysql.1 mysql_find_rows.1 mysql_waitpid.1
mysql_plugin.1 mysql_embedded.1)
SET(MAN1_DEVEL mysql_config.1)
SET(MAN1_TEST mysql-stress-test.pl.1 mysql-test-run.pl.1 mysql_client_test.1
- mysqltest_embedded.1 mysql_client_test_embedded.1 my_safe_process.1)
+ mysqltest.1 mysqltest_embedded.1 mysql_client_test_embedded.1
+ my_safe_process.1)
INSTALL(FILES ${MAN1_SERVER} DESTINATION ${INSTALL_MANDIR}/man1 COMPONENT ManPagesServer)
INSTALL(FILES ${MAN8_SERVER} DESTINATION ${INSTALL_MANDIR}/man8 COMPONENT ManPagesServer)
diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1
index 0d4d15d84d2..a083be5ce85 100644
--- a/man/mysql_upgrade.1
+++ b/man/mysql_upgrade.1
@@ -1,6 +1,6 @@
'\" t
.\"
-.TH "\FBMYSQL_UPGRADE\FR" "1" "14/12/2015" "MariaDB 10\&.1" "MariaDB Database System"
+.TH "\FBMYSQL_UPGRADE\FR" "1" "20 July 2020" "MariaDB 10\&.1" "MariaDB Database System"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@@ -165,6 +165,8 @@ in the data directory\&. This is used to quickly check whether all tables have b
\fB\-\-force\fR
option\&.
.PP
+For this reason, \fBmysql_upgrade\fR needs to be run as a user with write access to the data directory\&.
+.PP
If you install MariaDB from RPM packages on Linux, you must install the server and client RPMs\&.
\fBmysql_upgrade\fR
is included in the server RPM but requires the client RPM because the latter includes
diff --git a/man/mysqlimport.1 b/man/mysqlimport.1
index 61d270d7057..449c59cb648 100644
--- a/man/mysqlimport.1
+++ b/man/mysqlimport.1
@@ -57,13 +57,13 @@ all would be imported into a table named
patient\&.
.PP
.PP
-\fBmysqldump\fR
+\fBmysqlimport\fR
supports the following options, which can be specified on the command line or in the
-[mysqldump]
+[mysqlimport]
and
[client]
option file groups\&.
-\fBmysqldump\fR
+\fBmysqlimport\fR
also supports the options for processing option files\&.
.sp
.RS 4
@@ -267,17 +267,17 @@ Empty the table before importing the text file\&.
.sp -1
.IP \(bu 2.3
.\}
-.\" mysqldump: fields-terminated-by option
-.\" fields-terminated-by option: mysqldump
+.\" mysqlimport: fields-terminated-by option
+.\" fields-terminated-by option: mysqlimport
\fB\-\-fields\-terminated\-by=\&.\&.\&.\fR,
-.\" mysqldump: fields-enclosed-by option
-.\" fields-enclosed-by option: mysqldump
+.\" mysqlimport: fields-enclosed-by option
+.\" fields-enclosed-by option: mysqlimport
\fB\-\-fields\-enclosed\-by=\&.\&.\&.\fR,
-.\" mysqldump: fields-optionally-enclosed-by option
-.\" fields-optionally-enclosed-by option: mysqldump
+.\" mysqlimport: fields-optionally-enclosed-by option
+.\" fields-optionally-enclosed-by option: mysqlimport
\fB\-\-fields\-optionally\-enclosed\-by=\&.\&.\&.\fR,
-.\" mysqldump: fields-escaped-by option
-.\" fields-escaped-by option: mysqldump
+.\" mysqlimport: fields-escaped-by option
+.\" fields-escaped-by option: mysqlimport
\fB\-\-fields\-escaped\-by=\&.\&.\&.\fR
.sp
These options have the same meaning as the corresponding clauses for
@@ -379,8 +379,8 @@ lines of the data file\&.
.sp -1
.IP \(bu 2.3
.\}
-.\" mysqldump: lines-terminated-by option
-.\" lines-terminated-by option: mysqldump
+.\" mysqlimport: lines-terminated-by option
+.\" lines-terminated-by option: mysqlimport
\fB\-\-lines\-terminated\-by=\&.\&.\&.\fR
.sp
This option has the same meaning as the corresponding clause for
diff --git a/mysql-test/disabled.def b/mysql-test/disabled.def
index b6991cc1d37..ee30c4f4d3c 100644
--- a/mysql-test/disabled.def
+++ b/mysql-test/disabled.def
@@ -17,8 +17,6 @@ mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 chang
ssl_crl_clients_valid : broken upstream
ssl_crl : broken upstream
ssl_crl_clrpath : broken upstream
-innodb-wl5522-debug-zip : broken upstream
-innodb_bug12902967 : broken upstream
file_contents : MDEV-6526 these files are not installed anymore
max_statement_time : cannot possibly work, depends on timing
partition_open_files_limit : open_files_limit check broken by MDEV-18360
diff --git a/mysql-test/extra/rpl_tests/rpl_binlog_errors.inc b/mysql-test/extra/rpl_tests/rpl_binlog_errors.inc
index c595d70daa1..f78965ef9d6 100644
--- a/mysql-test/extra/rpl_tests/rpl_binlog_errors.inc
+++ b/mysql-test/extra/rpl_tests/rpl_binlog_errors.inc
@@ -49,6 +49,7 @@
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
call mtr.add_suppression("Error writing file .*");
+call mtr.add_suppression("Could not use master-bin for logging");
SET @old_debug= @@global.debug;
diff --git a/mysql-test/include/ctype_utf8mb4.inc b/mysql-test/include/ctype_utf8mb4.inc
index 71993a946b3..aa06cd97e4c 100644
--- a/mysql-test/include/ctype_utf8mb4.inc
+++ b/mysql-test/include/ctype_utf8mb4.inc
@@ -1576,7 +1576,7 @@ drop table t1;
--echo #
--echo # Check strnxfrm() with odd length
--echo #
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
eval create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine $engine;
insert into t1 values ('a'),('b'),('c');
diff --git a/mysql-test/include/icp_debug_kill.inc b/mysql-test/include/icp_debug_kill.inc
new file mode 100644
index 00000000000..d0ecc842869
--- /dev/null
+++ b/mysql-test/include/icp_debug_kill.inc
@@ -0,0 +1,50 @@
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/count_sessions.inc
+
+--disable_warnings
+drop table if exists t0,t1,t2;
+--enable_warnings
+
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int primary key);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+
+create table t2 (
+ kp1 int,
+ kp2 int,
+ col char(100),
+ key(kp1, kp2)
+);
+insert into t2 select a, a, a from t1;
+
+select engine from information_schema.tables
+where table_schema=database() and table_name='t2';
+
+explain
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+
+let $target_id= `select connection_id()`;
+
+set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
+send
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+
+connect (con1, localhost, root,,);
+connection con1;
+set debug_sync='now WAIT_FOR at_icp_check';
+evalp kill query $target_id;
+set debug_sync='now SIGNAL go';
+
+connection default;
+
+--error ER_QUERY_INTERRUPTED
+reap;
+set debug_sync='RESET';
+
+disconnect con1;
+drop table t0,t1,t2;
+--source include/wait_until_count_sessions.inc
+
diff --git a/mysql-test/include/innodb_prefix_index_cluster_optimization.combinations b/mysql-test/include/innodb_prefix_index_cluster_optimization.combinations
new file mode 100644
index 00000000000..ad82f82aa9d
--- /dev/null
+++ b/mysql-test/include/innodb_prefix_index_cluster_optimization.combinations
@@ -0,0 +1,5 @@
+[covering]
+innodb_prefix_index_cluster_optimization=on
+
+[unoptimized]
+innodb_prefix_index_cluster_optimization=off
diff --git a/mysql-test/include/innodb_prefix_index_cluster_optimization.inc b/mysql-test/include/innodb_prefix_index_cluster_optimization.inc
new file mode 100644
index 00000000000..c841fece702
--- /dev/null
+++ b/mysql-test/include/innodb_prefix_index_cluster_optimization.inc
@@ -0,0 +1 @@
+--source include/have_innodb.inc
diff --git a/mysql-test/lib/My/SafeProcess/safe_process_win.cc b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
index 7d81bf1a1b4..4dd4e24f30d 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process_win.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process_win.cc
@@ -206,7 +206,7 @@ int main(int argc, const char** argv )
} else {
if (strcmp(arg, "--verbose") == 0)
verbose++;
- else if (strncmp(arg, "--parent-pid", 10) == 0)
+ else if (strncmp(arg, "--parent-pid", 12) == 0)
{
/* Override parent_pid with a value provided by user */
const char* start;
diff --git a/mysql-test/lib/My/Tee.pm b/mysql-test/lib/My/Tee.pm
index 5985fe33739..8d6b4ddd52f 100644
--- a/mysql-test/lib/My/Tee.pm
+++ b/mysql-test/lib/My/Tee.pm
@@ -10,7 +10,7 @@ sub PUSHED
open($copyfh, '>', "$::opt_vardir/log/stdout.log")
or die "open(>$::opt_vardir/log/stdout.log): $!"
unless $copyfh;
- bless { }, shift;
+ bless { }, shift;
}
sub WRITE
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index 3701ad79b15..e553b0305b4 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -20,7 +20,9 @@
# same name.
package mtr_report;
+
use strict;
+use Sys::Hostname;
use base qw(Exporter);
our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line
@@ -253,6 +255,7 @@ sub mtr_report_stats ($$$$) {
# Find out how we where doing
# ----------------------------------------------------------------------
+ my $tot_disabled = 0;
my $tot_skipped= 0;
my $tot_skipdetect= 0;
my $tot_passed= 0;
@@ -273,6 +276,7 @@ sub mtr_report_stats ($$$$) {
{
# Test was skipped (disabled not counted)
$tot_skipped++ unless $tinfo->{'disable'};
+ $tot_disabled++ if $tinfo->{'disable'};
$tot_skipdetect++ if $tinfo->{'skip_detected_by_test'};
}
elsif ( $tinfo->{'result'} eq 'MTR_RES_PASSED' )
@@ -402,6 +406,106 @@ sub mtr_report_stats ($$$$) {
print "All $tot_tests tests were successful.\n\n";
}
+ if ($::opt_xml_report) {
+ my $xml_report = "";
+ my @sorted_tests = sort {$a->{'name'} cmp $b->{'name'}} @$tests;
+ my $last_suite = "";
+ my $current_suite = "";
+ my $timest = isotime(time);
+ my %suite_totals;
+ my %suite_time;
+ my %suite_tests;
+ my %suite_failed;
+ my %suite_disabled;
+ my %suite_skipped;
+ my $host = hostname;
+ my $suiteNo = 0;
+
+ # loop through test results to count totals
+ foreach my $test ( @sorted_tests ) {
+ $current_suite = $test->{'suite'}->{'name'};
+
+ if ($test->{'timer'} eq "") {
+ $test->{'timer'} = 0;
+ }
+
+ $suite_time{$current_suite} = $suite_time{$current_suite} + $test->{'timer'};
+ $suite_tests{$current_suite} = $suite_tests{$current_suite} + 1;
+
+ if ($test->{'result'} eq "MTR_RES_FAILED") {
+ $suite_failed{$current_suite} = $suite_failed{$current_suite} + 1;
+ } elsif ($test->{'result'} eq "MTR_RES_SKIPPED" && $test->{'disable'}) {
+ $suite_disabled{$current_suite} = $suite_disabled{$current_suite} + 1;
+ } elsif ($test->{'result'} eq "MTR_RES_SKIPPED") {
+ $suite_skipped{$current_suite} = $suite_skipped{$current_suite} + 1;
+ }
+
+ $suite_totals{"all_time"} = $suite_totals{"all_time"} + $test->{'timer'};
+ }
+
+ my $all_time = sprintf("%.3f", $suite_totals{"all_time"} / 1000);
+ my $suite_time = 0;
+ my $test_time = 0;
+
+ # generate xml
+ $xml_report = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ $xml_report .= qq(<testsuites disabled="$tot_disabled" errors="" failures="$tot_failed" name="" tests="$tot_tests" time="$all_time">\n);
+
+ foreach my $test ( @sorted_tests ) {
+ $current_suite = $test->{'suite'}->{'name'};
+
+ if ($current_suite ne $last_suite) {
+ if ($last_suite ne "") {
+ $xml_report .= "\t</testsuite>\n";
+ $suiteNo++;
+ }
+
+ $suite_time = sprintf("%.3f", $suite_time{$current_suite} / 1000);
+ $xml_report .= qq(\t<testsuite disabled="$suite_disabled{$current_suite}" errors="" failures="$suite_failed{$current_suite}" hostname="$host" id="$suiteNo" name="$current_suite" package="" skipped="$suite_skipped{$current_suite}" tests="$suite_tests{$current_suite}" time="$suite_time" timestamp="$timest">\n);
+ $last_suite = $current_suite;
+ }
+
+ $test_time = sprintf("%.3f", $test->{timer} / 1000);
+ $test->{'name'} =~ s/$current_suite\.//;
+
+ my $test_result;
+
+ # if a test case has to be retried it should have the result MTR_RES_FAILED in jUnit XML
+ if ($test->{'retries'} > 0) {
+ $test_result = "MTR_RES_FAILED";
+ } else {
+ $test_result = $test->{'result'};
+ }
+
+ $xml_report .= qq(\t\t<testcase assertions="" classname="$current_suite" name="$test->{'name'}" status="$test_result" time="$test_time");
+
+ my $comment = $test->{'comment'};
+ $comment =~ s/[\"]//g;
+
+ # if a test case has to be retried it should have the result MTR_RES_FAILED in jUnit XML
+ if ($test->{'result'} eq "MTR_RES_FAILED" || $test->{'retries'} > 0) {
+ my $logcontents = $test->{'logfile-failed'} || $test->{'logfile'};
+
+ $xml_report .= qq(>\n\t\t\t<failure message="" type="MTR_RES_FAILED">\n<![CDATA[$logcontents]]>\n\t\t\t</failure>\n\t\t</testcase>\n);
+ } elsif ($test->{'result'} eq "MTR_RES_SKIPPED" && $test->{'disable'}) {
+ $xml_report .= qq(>\n\t\t\t<disabled message="$comment" type="MTR_RES_SKIPPED"/>\n\t\t</testcase>\n);
+ } elsif ($test->{'result'} eq "MTR_RES_SKIPPED") {
+ $xml_report .= qq(>\n\t\t\t<skipped message="$comment" type="MTR_RES_SKIPPED"/>\n\t\t</testcase>\n);
+ } else {
+ $xml_report .= " />\n";
+ }
+ }
+
+ $xml_report .= "\t</testsuite>\n</testsuites>\n";
+
+ # save to file
+ my $xml_file = $::opt_xml_report;
+
+ open XML_FILE, ">", $xml_file or die "Cannot create file $xml_file: $!";
+ print XML_FILE $xml_report;
+ close XML_FILE;
+ }
+
if (@$extra_warnings)
{
print <<MSG;
@@ -545,6 +649,8 @@ sub mtr_error (@) {
}
else
{
+ use Carp qw(cluck);
+ cluck "Error happened" if $verbose > 0;
exit(1);
}
}
diff --git a/mysql-test/lib/process-purecov-annotations.pl b/mysql-test/lib/process-purecov-annotations.pl
index d533bd02fd6..4381aae4c64 100755
--- a/mysql-test/lib/process-purecov-annotations.pl
+++ b/mysql-test/lib/process-purecov-annotations.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# This script processes a .gcov coverage report to honor purecov
diff --git a/mysql-test/lib/t/SafeProcessStress.pl b/mysql-test/lib/t/SafeProcessStress.pl
index f591e9665dd..352b956d803 100755
--- a/mysql-test/lib/t/SafeProcessStress.pl
+++ b/mysql-test/lib/t/SafeProcessStress.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007, 2008 MySQL AB
diff --git a/mysql-test/lib/t/copytree.t b/mysql-test/lib/t/copytree.t
index 15a41081b24..76a3d644751 100644
--- a/mysql-test/lib/t/copytree.t
+++ b/mysql-test/lib/t/copytree.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/dummyd.pl b/mysql-test/lib/t/dummyd.pl
index 15164428b95..e78648cfacf 100644
--- a/mysql-test/lib/t/dummyd.pl
+++ b/mysql-test/lib/t/dummyd.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/rmtree.t b/mysql-test/lib/t/rmtree.t
index 40c9e96eabd..033bc59ad21 100644
--- a/mysql-test/lib/t/rmtree.t
+++ b/mysql-test/lib/t/rmtree.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/testMyConfig.t b/mysql-test/lib/t/testMyConfig.t
index 9f7067f436b..b373db0141a 100755
--- a/mysql-test/lib/t/testMyConfig.t
+++ b/mysql-test/lib/t/testMyConfig.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/t/testMyConfigFactory.t b/mysql-test/lib/t/testMyConfigFactory.t
index f38f660e85a..5ba63b3d823 100755
--- a/mysql-test/lib/t/testMyConfigFactory.t
+++ b/mysql-test/lib/t/testMyConfigFactory.t
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB, 2009 Sun Microsystems, Inc.
diff --git a/mysql-test/lib/t/test_child.pl b/mysql-test/lib/t/test_child.pl
index efbec4a9620..8a23c3d7541 100755
--- a/mysql-test/lib/t/test_child.pl
+++ b/mysql-test/lib/t/test_child.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2007 MySQL AB
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index b3d8f1e62fa..2bc46e09025 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
diff --git a/mysql-test/mtr.out-of-source b/mysql-test/mtr.out-of-source
index 51713517ae1..30e2e65c569 100644
--- a/mysql-test/mtr.out-of-source
+++ b/mysql-test/mtr.out-of-source
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Call mtr in out-of-source build
$ENV{MTR_BINDIR} = '@CMAKE_BINARY_DIR@';
chdir('@CMAKE_SOURCE_DIR@/mysql-test');
diff --git a/mysql-test/mysql-stress-test.pl b/mysql-test/mysql-stress-test.pl
index 79511273e6f..1df44f6b511 100755
--- a/mysql-test/mysql-stress-test.pl
+++ b/mysql-test/mysql-stress-test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 07cd4fa5392..e76712cc079 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- cperl -*-
# Copyright (c) 2004, 2014, Oracle and/or its affiliates.
@@ -129,6 +129,8 @@ our $path_testlog;
our $default_vardir;
our $opt_vardir; # Path to use for var/ dir
our $plugindir;
+our $opt_xml_report; # XML output
+
my $path_vardir_trace; # unix formatted opt_vardir for trace files
my $opt_tmpdir; # Path to use for tmp/ dir
my $opt_tmpdir_pid;
@@ -279,7 +281,7 @@ my $current_config_name; # The currently running config file template
our @opt_experimentals;
our $experimental_test_cases= [];
-my $baseport;
+our $baseport;
# $opt_build_thread may later be set from $opt_port_base
my $opt_build_thread= $ENV{'MTR_BUILD_THREAD'} || "auto";
my $opt_port_base= $ENV{'MTR_PORT_BASE'} || "auto";
@@ -366,6 +368,32 @@ my $opt_stop_keep_alive= $ENV{MTR_STOP_KEEP_ALIVE};
select(STDOUT);
$| = 1; # Automatically flush STDOUT
+my $set_titlebar;
+
+
+ BEGIN {
+ if (IS_WINDOWS) {
+ my $have_win32_console= 0;
+ eval {
+ require Win32::Console;
+ Win32::Console->import();
+ $have_win32_console = 1;
+ };
+ eval 'sub HAVE_WIN32_CONSOLE { $have_win32_console }';
+ } else {
+ eval 'sub HAVE_WIN32_CONSOLE { 0 }';
+ }
+}
+
+if (-t STDOUT) {
+ if (IS_WINDOWS and HAVE_WIN32_CONSOLE) {
+ $set_titlebar = sub {Win32::Console::Title $_[0];};
+ } elsif (defined $ENV{TERM} and $ENV{TERM} =~ /xterm/) {
+ $set_titlebar = sub { syswrite STDOUT, "\e];$_[0]\a"; };
+ }
+}
+
+
main();
@@ -441,11 +469,8 @@ sub main {
if ( $opt_parallel eq "auto" ) {
# Try to find a suitable value for number of workers
my $sys_info= My::SysInfo->new();
+ $opt_parallel= $sys_info->num_cpus() + int($sys_info->min_bogomips()/500)-4;
- $opt_parallel= $sys_info->num_cpus();
- for my $limit (2000, 1500, 1000, 500){
- $opt_parallel-- if ($sys_info->min_bogomips() < $limit);
- }
my $max_par= $ENV{MTR_MAX_PARALLEL} || 8;
$opt_parallel= $max_par if ($opt_parallel > $max_par);
$opt_parallel= $num_tests if ($opt_parallel > $num_tests);
@@ -542,6 +567,7 @@ sub main {
# Create minimalistic "test" for the reporting
my $tinfo = My::Test->new
(
+ suite => { name => 'valgrind', },
name => 'valgrind_report',
);
# Set dummy worker id to align report with normal tests
@@ -566,7 +592,6 @@ sub main {
}
print_total_times($opt_parallel) if $opt_report_times;
-
mtr_report_stats($prefix, $fail, $completed, $extra_warnings);
if ( @$completed != $num_tests)
@@ -672,8 +697,7 @@ sub run_test_server ($$$) {
My::CoreDump->show($core_file, $exe_mysqld, $opt_parallel);
# Limit number of core files saved
- if ($opt_max_save_core > 0 &&
- $num_saved_cores >= $opt_max_save_core)
+ if ($num_saved_cores >= $opt_max_save_core)
{
mtr_report(" - deleting it, already saved",
"$opt_max_save_core");
@@ -689,8 +713,7 @@ sub run_test_server ($$$) {
},
$worker_savedir);
- if ($opt_max_save_datadir > 0 &&
- $num_saved_datadir >= $opt_max_save_datadir)
+ if ($num_saved_datadir >= $opt_max_save_datadir)
{
mtr_report(" - skipping '$worker_savedir/'");
rmtree($worker_savedir);
@@ -699,9 +722,9 @@ sub run_test_server ($$$) {
{
mtr_report(" - saving '$worker_savedir/' to '$savedir/'");
rename($worker_savedir, $savedir);
+ $num_saved_datadir++;
}
resfile_print_test();
- $num_saved_datadir++;
$num_failed_test++ unless ($result->{retries} ||
$result->{exp_fail});
@@ -745,7 +768,14 @@ sub run_test_server ($$$) {
if ( $result->is_failed() ) {
my $worker_logdir= $result->{savedir};
my $log_file_name=dirname($worker_logdir)."/".$result->{shortname}.".log";
- rename $log_file_name,$log_file_name.".failed";
+
+ if (-e $log_file_name) {
+ $result->{'logfile-failed'} = mtr_lastlinesfromfile($log_file_name, 20);
+ } else {
+ $result->{'logfile-failed'} = "";
+ }
+
+ rename $log_file_name, $log_file_name.".failed";
}
delete($result->{result});
$result->{retries}= $retries+1;
@@ -867,7 +897,7 @@ sub run_test_server ($$$) {
delete $next->{reserved};
}
- xterm_stat(scalar(@$tests));
+ titlebar_stat(scalar(@$tests)) if $set_titlebar;
if ($next) {
# We don't need this any more
@@ -1062,6 +1092,7 @@ sub print_global_resfile {
resfile_global("warnings", $opt_warnings ? 1 : 0);
resfile_global("max-connections", $opt_max_connections);
resfile_global("product", "MySQL");
+ resfile_global("xml-report", $opt_xml_report);
# Somewhat hacky code to convert numeric version back to dot notation
my $v1= int($mysql_version_id / 10000);
my $v2= int(($mysql_version_id % 10000)/100);
@@ -1228,7 +1259,8 @@ sub command_line_setup {
'help|h' => \$opt_usage,
# list-options is internal, not listed in help
'list-options' => \$opt_list_options,
- 'skip-test-list=s' => \@opt_skip_test_list
+ 'skip-test-list=s' => \@opt_skip_test_list,
+ 'xml-report=s' => \$opt_xml_report
);
# fix options (that take an optional argument and *only* after = sign
@@ -1245,6 +1277,17 @@ sub command_line_setup {
report_option('verbose', $opt_verbose);
}
+ # Negative values aren't meaningful on integer options
+ foreach(grep(/=i$/, keys %options))
+ {
+ if (defined ${$options{$_}} &&
+ do { no warnings "numeric"; int ${$options{$_}} < 0})
+ {
+ my $v= (split /=/)[0];
+ die("$v doesn't accept a negative value:");
+ }
+ }
+
# Find the absolute path to the test directory
$glob_mysql_test_dir= cwd();
if ($glob_mysql_test_dir =~ / /)
@@ -3167,7 +3210,8 @@ sub mysql_install_db {
# ----------------------------------------------------------------------
# export MYSQLD_BOOTSTRAP_CMD variable containing <path>/mysqld <args>
# ----------------------------------------------------------------------
- $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args);
+ $ENV{'MYSQLD_BOOTSTRAP_CMD'}= "$exe_mysqld_bootstrap " . join(" ", @$args)
+ unless defined $ENV{'MYSQLD_BOOTSTRAP_CMD'};
# Extra options can come not only from the command line, but also
# from option files or combinations. We want them on a command line
@@ -3385,8 +3429,11 @@ sub do_before_run_mysqltest($)
# to be able to distinguish them from manually created
# version-controlled results, and to ignore them in git.
my $dest = "$base_file$suites.result~";
- my @cmd = ($exe_patch, qw/--binary -r - -f -s -o/,
- $dest, $base_result, $resfile);
+ my @cmd = ($exe_patch);
+ if ($^O eq "MSWin32") {
+ push @cmd, '--binary';
+ }
+ push @cmd, (qw/-r - -f -s -o/, $dest, $base_result, $resfile);
if (-w $resdir) {
# don't rebuild a file if it's up to date
unless (-e $dest and -M $dest < -M $resfile
@@ -6041,7 +6088,7 @@ Examples:
alias
main.alias 'main' is the name of the suite for the 't' directory.
-rpl.rpl_invoked_features,mix,xtradb_plugin
+rpl.rpl_invoked_features,mix,innodb_plugin
suite/rpl/t/rpl.rpl_invoked_features
Options to control what engine/variation to run:
@@ -6169,7 +6216,7 @@ Options for debugging the product
debug-server Use debug version of server, but without turning on
tracing
debugger=NAME Start mysqld in the selected debugger
- gdb Start the mysqld(s) in gdb
+ gdb[=gdb_arguments] Start the mysqld(s) in gdb
manual-debug Let user manually start mysqld in debugger, before
running test(s)
manual-gdb Let user manually start mysqld in gdb, before running
@@ -6182,12 +6229,12 @@ Options for debugging the product
test(s)
max-save-core Limit the number of core files saved (to avoid filling
up disks for heavily crashing server). Defaults to
- $opt_max_save_core, set to 0 for no limit. Set
- it's default with MTR_MAX_SAVE_CORE
+ $opt_max_save_core. Set its default with
+ MTR_MAX_SAVE_CORE
max-save-datadir Limit the number of datadir saved (to avoid filling
up disks for heavily crashing server). Defaults to
- $opt_max_save_datadir, set to 0 for no limit. Set
- it's default with MTR_MAX_SAVE_DATADIR
+ $opt_max_save_datadir. Set its default with
+ MTR_MAX_SAVE_DATADIR
max-test-fail Limit the number of test failures before aborting
the current test run. Defaults to
$opt_max_test_fail, set to 0 for no limit. Set
@@ -6284,6 +6331,7 @@ Misc options
phases of test execution.
stress=ARGS Run stress test, providing options to
mysql-stress-test.pl. Options are separated by comma.
+ xml-report=<file> Output jUnit xml file of the results.
Some options that control enabling a feature for normal test runs,
can be turned off by prepending 'no' to the option, e.g. --notimer.
@@ -6312,19 +6360,16 @@ sub time_format($) {
our $num_tests;
-sub xterm_stat {
- if (-t STDOUT and defined $ENV{TERM} and $ENV{TERM} =~ /xterm/) {
- my ($left) = @_;
+sub titlebar_stat {
+ my ($left) = @_;
- # 2.5 -> best by test
- $num_tests = $left + 2.5 unless $num_tests;
+ # 2.5 -> best by test
+ $num_tests = $left + 2.5 unless $num_tests;
- my $done = $num_tests - $left;
- my $spent = time - $^T;
+ my $done = $num_tests - $left;
+ my $spent = time - $^T;
- syswrite STDOUT, sprintf
- "\e];mtr: spent %s on %d tests. %s (%d tests) left\a",
+ &$set_titlebar(sprintf "mtr: spent %s on %d tests. %s (%d tests) left",
time_format($spent), $done,
- time_format($spent/$done * $left), $left;
- }
+ time_format($spent/$done * $left), $left);
}
diff --git a/mysql-test/r/connect_debug.result b/mysql-test/r/connect_debug.result
index 3151166a0e6..c455363eb41 100644
--- a/mysql-test/r/connect_debug.result
+++ b/mysql-test/r/connect_debug.result
@@ -8,3 +8,11 @@ create user 'bad' identified by 'worse';
ERROR 2059 (HY000): Authentication plugin 'foo/bar' cannot be loaded: invalid plugin name
set global debug_dbug=@old_dbug;
drop user bad;
+set global debug_dbug='+d,increase_srv_handshake_scramble_len';
+connect(localhost,root,,test,MASTER_MYPORT,MYSQL_TMP_DIR/mysqld.1.sock);
+ERROR HY000: Malformed packet
+set global debug_dbug=@old_dbug;
+set global debug_dbug='+d,poison_srv_handshake_scramble_len';
+connect(localhost,root,,test,MASTER_MYPORT,MYSQL_TMP_DIR/mysqld.1.sock);
+ERROR HY000: Malformed packet
+set global debug_dbug=@old_dbug;
diff --git a/mysql-test/r/create_drop_function.result b/mysql-test/r/create_drop_function.result
index e9db636ab87..bdac57751b8 100644
--- a/mysql-test/r/create_drop_function.result
+++ b/mysql-test/r/create_drop_function.result
@@ -52,3 +52,20 @@ body
DROP FUNCTION IF EXISTS f1;
Warnings:
Note 1305 FUNCTION test.f1 does not exist
+#
+# 10.1 Test
+#
+# MDEV-22654: Assertion `!is_set() || (m_status == DA_OK_BULK &&
+# is_bulk_op())' failed in Diagnostics_area::set_ok_status on FUNCTION replace
+#
+SET GLOBAL log_bin_trust_function_creators=0;
+CREATE FUNCTION f(c INT) RETURNS NUMERIC NO SQL RETURN 0;
+CREATE OR REPLACE FUNCTION f(c INT) RETURNS INT RETURN 0;
+ERROR HY000: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
+CREATE OR REPLACE FUNCTION sp1_thisisaveryverylongnamelongnameverylongname_thisisaveryverylongname234872934(a INT) RETURNS INT RETURN 0;
+ERROR 42000: Identifier name 'sp1_thisisaveryverylongnamelongnameverylongname_thisisaveryverylongname234872934' is too long
+DROP FUNCTION IF EXISTS f;
+Warnings:
+Note 1305 FUNCTION test.f does not exist
+SET GLOBAL log_bin_trust_function_creators=1;
+# End of 10.1 Test
diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result
index 15b44d07ddf..aad9621966f 100644
--- a/mysql-test/r/ctype_binary.result
+++ b/mysql-test/r/ctype_binary.result
@@ -3171,5 +3171,98 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 'a') and (weight_string(`test`.`t1`.`a`) = 'a'))
DROP TABLE t1;
#
+# MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
+#
+CREATE TABLE t1(a ENUM(0x6100,0x6200,0x6300) CHARACTER SET 'Binary');
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a\0','b\0','c\0') CHARACTER SET binary DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1),(2),(3);
+SELECT HEX(a) FROM t1 ORDER BY a;
+HEX(a)
+6100
+6200
+6300
+DROP TABLE t1;
+0x00 in the middle or in the end of a value
+CREATE TABLE t1 (a ENUM(0x6100));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a\0') DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1);
+SELECT HEX(a) FROM t1;
+HEX(a)
+6100
+DROP TABLE t1;
+CREATE TABLE t1 (a ENUM(0x610062));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a\0b') DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1);
+SELECT HEX(a) FROM t1;
+HEX(a)
+610062
+DROP TABLE t1;
+0x00 in the beginning of the first value:
+CREATE TABLE t1 (a ENUM(0x0061));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('\0a') DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(1);
+SELECT * FROM t1;
+a
+
+DROP TABLE t1;
+CREATE TABLE t1 (a ENUM(0x0061), b ENUM('b'));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('\0a') DEFAULT NULL,
+ `b` enum('b') DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1,1);
+SELECT HEX(a), HEX(b) FROM t1;
+HEX(a) HEX(b)
+0061 62
+DROP TABLE t1;
+# 0x00 in the beginning of the second (and following) value of the *last* ENUM/SET in the table:
+CREATE TABLE t1 (a ENUM('a',0x0061));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a','\0a') DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1),(2);
+SELECT HEX(a) FROM t1 ORDER BY a;
+HEX(a)
+61
+0061
+DROP TABLE t1;
+CREATE TABLE t1 (a ENUM('a'), b ENUM('b',0x0061));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` enum('a') DEFAULT NULL,
+ `b` enum('b','\0a') DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t1 VALUES (1,2);
+SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
+HEX(a) HEX(b)
+61 62
+61 0061
+DROP TABLE t1;
+0x00 in the beginning of a value of a non-last ENUM/SET causes an error:
+CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b'));
+ERROR HY000: Incorrect information in file: 'DIR/t1.frm'
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/ctype_cp932_binlog_stm.result b/mysql-test/r/ctype_cp932_binlog_stm.result
index 75d05aa9f0a..c92026cf5a4 100644
--- a/mysql-test/r/ctype_cp932_binlog_stm.result
+++ b/mysql-test/r/ctype_cp932_binlog_stm.result
@@ -56,7 +56,7 @@ master-bin.000001 # Query # # use `test`; DROP TABLE `t4` /* generated by server
End of 5.0 tests
call mtr.add_suppression("Error in Log_event::read_log_event\\\(\\\): 'Found invalid");
SHOW BINLOG EVENTS FROM 504;
-ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Invalid input pos specified please provide valid one.
Bug#44352 UPPER/LOWER function doesn't work correctly on cp932 and sjis environment.
CREATE TABLE t1 (a varchar(16)) character set cp932;
INSERT INTO t1 VALUES (0x8372835E),(0x8352835E);
diff --git a/mysql-test/r/ctype_utf16.result b/mysql-test/r/ctype_utf16.result
index c826a93809d..7c3d18a6cfc 100644
--- a/mysql-test/r/ctype_utf16.result
+++ b/mysql-test/r/ctype_utf16.result
@@ -1489,7 +1489,7 @@ ab
ab
AE
AE
-SET max_sort_length=4;
+SET max_sort_length=8;
SELECT * FROM t1 ORDER BY s1;
s1
ab
diff --git a/mysql-test/r/ctype_utf16le.result b/mysql-test/r/ctype_utf16le.result
index e1a71e02bb6..d129323bae0 100644
--- a/mysql-test/r/ctype_utf16le.result
+++ b/mysql-test/r/ctype_utf16le.result
@@ -1762,7 +1762,7 @@ ab
ab
AE
AE
-SET max_sort_length=4;
+SET max_sort_length=8;
SELECT * FROM t1 ORDER BY s1;
s1
ab
diff --git a/mysql-test/r/ctype_utf32.result b/mysql-test/r/ctype_utf32.result
index 4a44147e945..a4f7571d972 100644
--- a/mysql-test/r/ctype_utf32.result
+++ b/mysql-test/r/ctype_utf32.result
@@ -1503,7 +1503,7 @@ ab
ab
AE
AE
-SET max_sort_length=4;
+SET max_sort_length=8;
SELECT * FROM t1 ORDER BY s1;
s1
ab
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 9ff12870d75..b614444fd2a 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -6807,10 +6807,10 @@ DFFFDFFF9CFF9DFF9EFF
#
# Checking strnxfrm() with odd length
#
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
@@max_sort_length
-5
+9
create table t1 (a varchar(128) character set utf8 collate utf8_general_ci);
insert into t1 values ('a'),('b'),('c');
select * from t1 order by a;
@@ -10583,5 +10583,17 @@ SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
CONVERT(1, CHAR) IN ('100', '10', '1')
1
#
+# MDEV-23535 SIGSEGV, SIGABRT and SIGILL in typeinfo for Item_func_set_collation (on optimized builds)
+#
+SET NAMES utf8;
+CREATE OR REPLACE TABLE t1(a DATETIME) ENGINE=MYISAM;
+INSERT INTO t1 VALUES ('2019-03-10 02:55:05');
+CREATE OR REPLACE TABLE t2(a VARCHAR(50) CHARACTER SET latin1) ENGINE=MYISAM;
+INSERT INTO t2 VALUES ('2019-03-10 02:55:05');
+SELECT * FROM t1 WHERE (SELECT 1,CONCAT(a) FROM t1) = (SELECT 1,CONCAT(a) FROM t2);
+a
+2019-03-10 02:55:05
+DROP TABLE t1, t2;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result
index fa1cf3b1d19..d7bc36119ec 100644
--- a/mysql-test/r/ctype_utf8mb4.result
+++ b/mysql-test/r/ctype_utf8mb4.result
@@ -2364,10 +2364,10 @@ drop table t1;
#
# Check strnxfrm() with odd length
#
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
@@max_sort_length
-5
+9
create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci);
insert into t1 values ('a'),('b'),('c');
select * from t1 order by a;
diff --git a/mysql-test/r/ctype_utf8mb4_heap.result b/mysql-test/r/ctype_utf8mb4_heap.result
index ef134641ff8..9933c659ae3 100644
--- a/mysql-test/r/ctype_utf8mb4_heap.result
+++ b/mysql-test/r/ctype_utf8mb4_heap.result
@@ -2196,10 +2196,10 @@ drop table t1;
#
# Check strnxfrm() with odd length
#
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
@@max_sort_length
-5
+9
create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine heap;
insert into t1 values ('a'),('b'),('c');
select * from t1 order by a;
diff --git a/mysql-test/r/ctype_utf8mb4_innodb.result b/mysql-test/r/ctype_utf8mb4_innodb.result
index 9c58dc87126..ff8fe980247 100644
--- a/mysql-test/r/ctype_utf8mb4_innodb.result
+++ b/mysql-test/r/ctype_utf8mb4_innodb.result
@@ -2324,10 +2324,10 @@ drop table t1;
#
# Check strnxfrm() with odd length
#
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
@@max_sort_length
-5
+9
create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine InnoDB;
insert into t1 values ('a'),('b'),('c');
select * from t1 order by a;
diff --git a/mysql-test/r/ctype_utf8mb4_myisam.result b/mysql-test/r/ctype_utf8mb4_myisam.result
index 18bec51358d..b2e717a0737 100644
--- a/mysql-test/r/ctype_utf8mb4_myisam.result
+++ b/mysql-test/r/ctype_utf8mb4_myisam.result
@@ -2324,10 +2324,10 @@ drop table t1;
#
# Check strnxfrm() with odd length
#
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
@@max_sort_length
-5
+9
create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci) engine MyISAM;
insert into t1 values ('a'),('b'),('c');
select * from t1 order by a;
diff --git a/mysql-test/r/fast_prefix_index_fetch_innodb.result b/mysql-test/r/fast_prefix_index_fetch_innodb.result
index c6d96389b08..885ee000c28 100644
--- a/mysql-test/r/fast_prefix_index_fetch_innodb.result
+++ b/mysql-test/r/fast_prefix_index_fetch_innodb.result
@@ -1,4 +1,4 @@
-drop table if exists prefixinno;
+SET @save_opt= @@GLOBAL.innodb_prefix_index_cluster_optimization;
set global innodb_prefix_index_cluster_optimization = ON;
show variables like 'innodb_prefix_index_cluster_optimization';
Variable_name Value
@@ -346,10 +346,10 @@ f1
🐱🌑
select @cluster_lookups;
@cluster_lookups
-2
+1
select @cluster_lookups_avoided;
@cluster_lookups_avoided
-0
+1
# Eligible - record length is shorter than prefix length
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌑%';
f1
@@ -366,10 +366,10 @@ f1
🌒
select @cluster_lookups;
@cluster_lookups
-1
+0
select @cluster_lookups_avoided;
@cluster_lookups_avoided
-1
+2
DROP TABLE t1;
CREATE TABLE t1(
col1 INT,
@@ -398,4 +398,49 @@ select @cluster_lookups_avoided;
@cluster_lookups_avoided
0
DROP TABLE t1;
-set global innodb_prefix_index_cluster_optimization = OFF;
+#
+# MDEV-23600 Division by 0 in row_search_with_covering_prefix()
+#
+CREATE TABLE t(c POINT UNIQUE) ENGINE=InnoDB;
+INSERT t SET c=POINT(1,1);
+SELECT * FROM t WHERE c > (SELECT MAX(c) FROM t);
+c
+DROP TABLE t;
+#
+# MDEV-12486 Wrong results with innodb_prefix_index_cluster_optimization
+#
+CREATE TABLE wp_blogs (
+blog_id bigint(20) NOT NULL auto_increment,
+site_id bigint(20) NOT NULL default '0',
+domain varchar(200) NOT NULL default '',
+path varchar(100) NOT NULL default '',
+registered datetime NOT NULL default '0000-00-00 00:00:00',
+last_updated datetime NOT NULL default '0000-00-00 00:00:00',
+public tinyint(2) NOT NULL default '1',
+archived tinyint(2) NOT NULL default '0',
+mature tinyint(2) NOT NULL default '0',
+spam tinyint(2) NOT NULL default '0',
+deleted tinyint(2) NOT NULL default '0',
+lang_id int(11) NOT NULL default '0',
+PRIMARY KEY (blog_id),
+KEY domain (domain(50),path(5)),
+KEY lang_id (lang_id)
+) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
+INSERT INTO wp_blogs (domain, path) VALUES
+('domain.no', '/fondsinvesteringer/'), ('domain.no', '/'),
+('foo', 'bar'), ('bar', 'foo'), ('foo', 'foo'), ('bar', 'bar'),
+('foo', 'foobar'), ('bar', 'foobar'), ('foobar', 'foobar');
+SET GLOBAL innodb_prefix_index_cluster_optimization=off;
+SELECT blog_id FROM wp_blogs WHERE domain IN ('domain.no')
+AND path IN ( '/fondsinvesteringer/', '/' );
+blog_id
+2
+1
+SET GLOBAL innodb_prefix_index_cluster_optimization=on;
+SELECT blog_id FROM wp_blogs WHERE domain IN ('domain.no')
+AND path IN ( '/fondsinvesteringer/', '/' );
+blog_id
+2
+1
+DROP TABLE wp_blogs;
+SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 06323f5b3bb..d0d413331df 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1186,13 +1186,13 @@ i count(*) std(e1/e2)
3 4 0.00000000
select std(s1/s2) from bug22555;
std(s1/s2)
-0.21325764
+0.21328517
select std(o1/o2) from bug22555;
std(o1/o2)
0.2132576358664934
select std(e1/e2) from bug22555;
std(e1/e2)
-0.21325764
+0.21328517
set @saved_div_precision_increment=@@div_precision_increment;
set div_precision_increment=19;
select i, count(*), std(s1/s2) from bug22555 group by i order by i;
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 008590aa5d8..fcb2e73e623 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -946,5 +946,789 @@ STDDEV_SAMP(a)
NULL
DROP TABLE t1;
#
+# MDEV-21977 main.func_math fails due to undefined behaviour
+#
+SELECT 9223372036854775808 DIV 1;
+9223372036854775808 DIV 1
+9223372036854775808
+SELECT 9223372036854775808 DIV -1;
+ERROR 22003: BIGINT UNSIGNED value is out of range in '(9223372036854775808 DIV -(1))'
+SELECT -9223372036854775808 DIV 1;
+ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) DIV 1)'
+SELECT -9223372036854775808 DIV -1;
+ERROR 22003: BIGINT value is out of range in '(-(9223372036854775808) DIV -(1))'
+SELECT 9223372036854775808 MOD 1;
+9223372036854775808 MOD 1
+0
+SELECT 9223372036854775808 MOD -1;
+9223372036854775808 MOD -1
+0
+SELECT -9223372036854775808 MOD 1;
+-9223372036854775808 MOD 1
+0
+SELECT -9223372036854775808 MOD -1;
+-9223372036854775808 MOD -1
+0
+SELECT 1 MOD 9223372036854775808;
+1 MOD 9223372036854775808
+1
+SELECT -1 MOD 9223372036854775808;
+-1 MOD 9223372036854775808
+-1
+SELECT 1 MOD -9223372036854775808;
+1 MOD -9223372036854775808
+1
+SELECT -1 MOD -9223372036854775808;
+-1 MOD -9223372036854775808
+-1
+SELECT 9223372036854775808 MOD 9223372036854775808;
+9223372036854775808 MOD 9223372036854775808
+0
+SELECT 9223372036854775808 MOD -9223372036854775808;
+9223372036854775808 MOD -9223372036854775808
+0
+SELECT -9223372036854775808 MOD 9223372036854775808;
+-9223372036854775808 MOD 9223372036854775808
+0
+SELECT -9223372036854775808 MOD -9223372036854775808;
+-9223372036854775808 MOD -9223372036854775808
+0
+#
+# MDEV-22502 MDB crashes in CREATE TABLE AS SELECT when the precision of returning type = 0
+#
+CREATE TABLE t1 (d decimal(5,5));
+INSERT INTO t1 VALUES (0.55555);
+SELECT TRUNCATE(d,0) FROM t1;
+TRUNCATE(d,0)
+0
+CREATE TABLE t2 AS SELECT TRUNCATE(d,0) FROM t1;
+SELECT * FROM t2;
+TRUNCATE(d,0)
+0
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `TRUNCATE(d,0)` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1, t2;
+#
+# MDEV-22503 MDB limits DECIMAL column precision to 16 doing CTAS with floor/ceil over DECIMAL(X,Y) where X > 16
+#
+CREATE TABLE t44 (d1 decimal(38,0) DEFAULT NULL);
+INSERT INTO t44 VALUES (12345678901234567890123456789012345678);
+SELECT FLOOR(d1) FROM t44;
+FLOOR(d1)
+12345678901234567890123456789012345678
+CREATE TABLE t45 AS SELECT FLOOR(d1) FROM t44;
+SELECT * FROM t45;
+FLOOR(d1)
+12345678901234567890123456789012345678
+SHOW CREATE TABLE t45;
+Table Create Table
+t45 CREATE TABLE `t45` (
+ `FLOOR(d1)` decimal(38,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t44, t45;
+CREATE PROCEDURE p1(prec INT, scale INT)
+BEGIN
+DECLARE maxval VARCHAR(128) DEFAULT '';
+SET @type= CONCAT('DECIMAL(', prec, ',', scale,')');
+SET @stmt= CONCAT('CREATE TABLE t1 (a ', @type, ',b ', @type, 'unsigned)');
+PREPARE stmt FROM @stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+SET maxval= CONCAT(REPEAT('9', prec-scale), '.', REPEAT('9',scale));
+INSERT INTO t1 VALUES (maxval, maxval);
+CREATE TABLE t2 AS SELECT a, b, FLOOR(a) AS fa, FLOOR(b) AS fb FROM t1;
+SHOW CREATE TABLE t2;
+SELECT * FROM t2;
+DROP TABLE t1, t2;
+END;
+$$
+CREATE PROCEDURE p2(prec INT)
+BEGIN
+DECLARE scale INT DEFAULT 0;
+WHILE scale < prec AND scale <= 30 DO
+CALL p1(prec, scale);
+SET scale= scale + 1;
+END WHILE;
+END;
+$$
+CALL p2(38);
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,0) DEFAULT NULL,
+ `b` decimal(38,0) unsigned DEFAULT NULL,
+ `fa` decimal(38,0) DEFAULT NULL,
+ `fb` decimal(38,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999999999999999
+b 99999999999999999999999999999999999999
+fa 99999999999999999999999999999999999999
+fb 99999999999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,1) DEFAULT NULL,
+ `b` decimal(38,1) unsigned DEFAULT NULL,
+ `fa` decimal(37,0) DEFAULT NULL,
+ `fb` decimal(37,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999999999999999.9
+b 9999999999999999999999999999999999999.9
+fa 9999999999999999999999999999999999999
+fb 9999999999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,2) DEFAULT NULL,
+ `b` decimal(38,2) unsigned DEFAULT NULL,
+ `fa` decimal(36,0) DEFAULT NULL,
+ `fb` decimal(36,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999999999999999.99
+b 999999999999999999999999999999999999.99
+fa 999999999999999999999999999999999999
+fb 999999999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,3) DEFAULT NULL,
+ `b` decimal(38,3) unsigned DEFAULT NULL,
+ `fa` decimal(35,0) DEFAULT NULL,
+ `fb` decimal(35,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999999999999.999
+b 99999999999999999999999999999999999.999
+fa 99999999999999999999999999999999999
+fb 99999999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,4) DEFAULT NULL,
+ `b` decimal(38,4) unsigned DEFAULT NULL,
+ `fa` decimal(34,0) DEFAULT NULL,
+ `fb` decimal(34,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999999999999.9999
+b 9999999999999999999999999999999999.9999
+fa 9999999999999999999999999999999999
+fb 9999999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,5) DEFAULT NULL,
+ `b` decimal(38,5) unsigned DEFAULT NULL,
+ `fa` decimal(33,0) DEFAULT NULL,
+ `fb` decimal(33,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999999999999.99999
+b 999999999999999999999999999999999.99999
+fa 999999999999999999999999999999999
+fb 999999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,6) DEFAULT NULL,
+ `b` decimal(38,6) unsigned DEFAULT NULL,
+ `fa` decimal(32,0) DEFAULT NULL,
+ `fb` decimal(32,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999999999.999999
+b 99999999999999999999999999999999.999999
+fa 99999999999999999999999999999999
+fb 99999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,7) DEFAULT NULL,
+ `b` decimal(38,7) unsigned DEFAULT NULL,
+ `fa` decimal(31,0) DEFAULT NULL,
+ `fb` decimal(31,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999999999.9999999
+b 9999999999999999999999999999999.9999999
+fa 9999999999999999999999999999999
+fb 9999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,8) DEFAULT NULL,
+ `b` decimal(38,8) unsigned DEFAULT NULL,
+ `fa` decimal(30,0) DEFAULT NULL,
+ `fb` decimal(30,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999999999.99999999
+b 999999999999999999999999999999.99999999
+fa 999999999999999999999999999999
+fb 999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,9) DEFAULT NULL,
+ `b` decimal(38,9) unsigned DEFAULT NULL,
+ `fa` decimal(29,0) DEFAULT NULL,
+ `fb` decimal(29,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999999.999999999
+b 99999999999999999999999999999.999999999
+fa 99999999999999999999999999999
+fb 99999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,10) DEFAULT NULL,
+ `b` decimal(38,10) unsigned DEFAULT NULL,
+ `fa` decimal(28,0) DEFAULT NULL,
+ `fb` decimal(28,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999999.9999999999
+b 9999999999999999999999999999.9999999999
+fa 9999999999999999999999999999
+fb 9999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,11) DEFAULT NULL,
+ `b` decimal(38,11) unsigned DEFAULT NULL,
+ `fa` decimal(27,0) DEFAULT NULL,
+ `fb` decimal(27,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999999.99999999999
+b 999999999999999999999999999.99999999999
+fa 999999999999999999999999999
+fb 999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,12) DEFAULT NULL,
+ `b` decimal(38,12) unsigned DEFAULT NULL,
+ `fa` decimal(26,0) DEFAULT NULL,
+ `fb` decimal(26,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999.999999999999
+b 99999999999999999999999999.999999999999
+fa 99999999999999999999999999
+fb 99999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,13) DEFAULT NULL,
+ `b` decimal(38,13) unsigned DEFAULT NULL,
+ `fa` decimal(25,0) DEFAULT NULL,
+ `fb` decimal(25,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999.9999999999999
+b 9999999999999999999999999.9999999999999
+fa 9999999999999999999999999
+fb 9999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,14) DEFAULT NULL,
+ `b` decimal(38,14) unsigned DEFAULT NULL,
+ `fa` decimal(24,0) DEFAULT NULL,
+ `fb` decimal(24,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999.99999999999999
+b 999999999999999999999999.99999999999999
+fa 999999999999999999999999
+fb 999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,15) DEFAULT NULL,
+ `b` decimal(38,15) unsigned DEFAULT NULL,
+ `fa` decimal(23,0) DEFAULT NULL,
+ `fb` decimal(23,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999.999999999999999
+b 99999999999999999999999.999999999999999
+fa 99999999999999999999999
+fb 99999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,16) DEFAULT NULL,
+ `b` decimal(38,16) unsigned DEFAULT NULL,
+ `fa` decimal(22,0) DEFAULT NULL,
+ `fb` decimal(22,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999.9999999999999999
+b 9999999999999999999999.9999999999999999
+fa 9999999999999999999999
+fb 9999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,17) DEFAULT NULL,
+ `b` decimal(38,17) unsigned DEFAULT NULL,
+ `fa` decimal(21,0) DEFAULT NULL,
+ `fb` decimal(21,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999.99999999999999999
+b 999999999999999999999.99999999999999999
+fa 999999999999999999999
+fb 999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,18) DEFAULT NULL,
+ `b` decimal(38,18) unsigned DEFAULT NULL,
+ `fa` decimal(20,0) DEFAULT NULL,
+ `fb` decimal(20,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999.999999999999999999
+b 99999999999999999999.999999999999999999
+fa 99999999999999999999
+fb 99999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,19) DEFAULT NULL,
+ `b` decimal(38,19) unsigned DEFAULT NULL,
+ `fa` decimal(19,0) DEFAULT NULL,
+ `fb` decimal(19,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999.9999999999999999999
+b 9999999999999999999.9999999999999999999
+fa 9999999999999999999
+fb 9999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,20) DEFAULT NULL,
+ `b` decimal(38,20) unsigned DEFAULT NULL,
+ `fa` decimal(18,0) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999.99999999999999999999
+b 999999999999999999.99999999999999999999
+fa 999999999999999999
+fb 999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,21) DEFAULT NULL,
+ `b` decimal(38,21) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999.999999999999999999999
+b 99999999999999999.999999999999999999999
+fa 99999999999999999
+fb 99999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,22) DEFAULT NULL,
+ `b` decimal(38,22) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999.9999999999999999999999
+b 9999999999999999.9999999999999999999999
+fa 9999999999999999
+fb 9999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,23) DEFAULT NULL,
+ `b` decimal(38,23) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999.99999999999999999999999
+b 999999999999999.99999999999999999999999
+fa 999999999999999
+fb 999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,24) DEFAULT NULL,
+ `b` decimal(38,24) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(16) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999.999999999999999999999999
+b 99999999999999.999999999999999999999999
+fa 99999999999999
+fb 99999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,25) DEFAULT NULL,
+ `b` decimal(38,25) unsigned DEFAULT NULL,
+ `fa` bigint(16) DEFAULT NULL,
+ `fb` bigint(15) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999.9999999999999999999999999
+b 9999999999999.9999999999999999999999999
+fa 9999999999999
+fb 9999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,26) DEFAULT NULL,
+ `b` decimal(38,26) unsigned DEFAULT NULL,
+ `fa` bigint(15) DEFAULT NULL,
+ `fb` bigint(14) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999.99999999999999999999999999
+b 999999999999.99999999999999999999999999
+fa 999999999999
+fb 999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,27) DEFAULT NULL,
+ `b` decimal(38,27) unsigned DEFAULT NULL,
+ `fa` bigint(14) DEFAULT NULL,
+ `fb` bigint(13) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999.999999999999999999999999999
+b 99999999999.999999999999999999999999999
+fa 99999999999
+fb 99999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,28) DEFAULT NULL,
+ `b` decimal(38,28) unsigned DEFAULT NULL,
+ `fa` bigint(13) DEFAULT NULL,
+ `fb` bigint(12) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999.9999999999999999999999999999
+b 9999999999.9999999999999999999999999999
+fa 9999999999
+fb 9999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,29) DEFAULT NULL,
+ `b` decimal(38,29) unsigned DEFAULT NULL,
+ `fa` bigint(12) DEFAULT NULL,
+ `fb` int(11) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999.99999999999999999999999999999
+b 999999999.99999999999999999999999999999
+fa 999999999
+fb 999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(38,30) DEFAULT NULL,
+ `b` decimal(38,30) unsigned DEFAULT NULL,
+ `fa` int(11) DEFAULT NULL,
+ `fb` int(10) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999.999999999999999999999999999999
+b 99999999.999999999999999999999999999999
+fa 99999999
+fb 99999999
+CALL p2(30);
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,0) DEFAULT NULL,
+ `b` decimal(30,0) unsigned DEFAULT NULL,
+ `fa` decimal(30,0) DEFAULT NULL,
+ `fb` decimal(31,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999999999
+b 999999999999999999999999999999
+fa 999999999999999999999999999999
+fb 999999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,1) DEFAULT NULL,
+ `b` decimal(30,1) unsigned DEFAULT NULL,
+ `fa` decimal(29,0) DEFAULT NULL,
+ `fb` decimal(30,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999999.9
+b 99999999999999999999999999999.9
+fa 99999999999999999999999999999
+fb 99999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,2) DEFAULT NULL,
+ `b` decimal(30,2) unsigned DEFAULT NULL,
+ `fa` decimal(28,0) DEFAULT NULL,
+ `fb` decimal(29,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999999.99
+b 9999999999999999999999999999.99
+fa 9999999999999999999999999999
+fb 9999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,3) DEFAULT NULL,
+ `b` decimal(30,3) unsigned DEFAULT NULL,
+ `fa` decimal(27,0) DEFAULT NULL,
+ `fb` decimal(28,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999999.999
+b 999999999999999999999999999.999
+fa 999999999999999999999999999
+fb 999999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,4) DEFAULT NULL,
+ `b` decimal(30,4) unsigned DEFAULT NULL,
+ `fa` decimal(26,0) DEFAULT NULL,
+ `fb` decimal(27,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999999.9999
+b 99999999999999999999999999.9999
+fa 99999999999999999999999999
+fb 99999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,5) DEFAULT NULL,
+ `b` decimal(30,5) unsigned DEFAULT NULL,
+ `fa` decimal(25,0) DEFAULT NULL,
+ `fb` decimal(26,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999999.99999
+b 9999999999999999999999999.99999
+fa 9999999999999999999999999
+fb 9999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,6) DEFAULT NULL,
+ `b` decimal(30,6) unsigned DEFAULT NULL,
+ `fa` decimal(24,0) DEFAULT NULL,
+ `fb` decimal(25,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999999.999999
+b 999999999999999999999999.999999
+fa 999999999999999999999999
+fb 999999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,7) DEFAULT NULL,
+ `b` decimal(30,7) unsigned DEFAULT NULL,
+ `fa` decimal(23,0) DEFAULT NULL,
+ `fb` decimal(24,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999999.9999999
+b 99999999999999999999999.9999999
+fa 99999999999999999999999
+fb 99999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,8) DEFAULT NULL,
+ `b` decimal(30,8) unsigned DEFAULT NULL,
+ `fa` decimal(22,0) DEFAULT NULL,
+ `fb` decimal(23,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999999.99999999
+b 9999999999999999999999.99999999
+fa 9999999999999999999999
+fb 9999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,9) DEFAULT NULL,
+ `b` decimal(30,9) unsigned DEFAULT NULL,
+ `fa` decimal(21,0) DEFAULT NULL,
+ `fb` decimal(22,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999999.999999999
+b 999999999999999999999.999999999
+fa 999999999999999999999
+fb 999999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,10) DEFAULT NULL,
+ `b` decimal(30,10) unsigned DEFAULT NULL,
+ `fa` decimal(20,0) DEFAULT NULL,
+ `fb` decimal(21,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999999.9999999999
+b 99999999999999999999.9999999999
+fa 99999999999999999999
+fb 99999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,11) DEFAULT NULL,
+ `b` decimal(30,11) unsigned DEFAULT NULL,
+ `fa` decimal(19,0) DEFAULT NULL,
+ `fb` decimal(20,0) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999999.99999999999
+b 9999999999999999999.99999999999
+fa 9999999999999999999
+fb 9999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,12) DEFAULT NULL,
+ `b` decimal(30,12) unsigned DEFAULT NULL,
+ `fa` decimal(18,0) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999999.999999999999
+b 999999999999999999.999999999999
+fa 999999999999999999
+fb 999999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,13) DEFAULT NULL,
+ `b` decimal(30,13) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999999.9999999999999
+b 99999999999999999.9999999999999
+fa 99999999999999999
+fb 99999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,14) DEFAULT NULL,
+ `b` decimal(30,14) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999999.99999999999999
+b 9999999999999999.99999999999999
+fa 9999999999999999
+fb 9999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,15) DEFAULT NULL,
+ `b` decimal(30,15) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(17) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999999.999999999999999
+b 999999999999999.999999999999999
+fa 999999999999999
+fb 999999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,16) DEFAULT NULL,
+ `b` decimal(30,16) unsigned DEFAULT NULL,
+ `fa` bigint(17) DEFAULT NULL,
+ `fb` bigint(16) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999999.9999999999999999
+b 99999999999999.9999999999999999
+fa 99999999999999
+fb 99999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,17) DEFAULT NULL,
+ `b` decimal(30,17) unsigned DEFAULT NULL,
+ `fa` bigint(16) DEFAULT NULL,
+ `fb` bigint(15) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999999.99999999999999999
+b 9999999999999.99999999999999999
+fa 9999999999999
+fb 9999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,18) DEFAULT NULL,
+ `b` decimal(30,18) unsigned DEFAULT NULL,
+ `fa` bigint(15) DEFAULT NULL,
+ `fb` bigint(14) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999999.999999999999999999
+b 999999999999.999999999999999999
+fa 999999999999
+fb 999999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,19) DEFAULT NULL,
+ `b` decimal(30,19) unsigned DEFAULT NULL,
+ `fa` bigint(14) DEFAULT NULL,
+ `fb` bigint(13) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999999.9999999999999999999
+b 99999999999.9999999999999999999
+fa 99999999999
+fb 99999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,20) DEFAULT NULL,
+ `b` decimal(30,20) unsigned DEFAULT NULL,
+ `fa` bigint(13) DEFAULT NULL,
+ `fb` bigint(12) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999999.99999999999999999999
+b 9999999999.99999999999999999999
+fa 9999999999
+fb 9999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,21) DEFAULT NULL,
+ `b` decimal(30,21) unsigned DEFAULT NULL,
+ `fa` bigint(12) DEFAULT NULL,
+ `fb` int(11) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999999.999999999999999999999
+b 999999999.999999999999999999999
+fa 999999999
+fb 999999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,22) DEFAULT NULL,
+ `b` decimal(30,22) unsigned DEFAULT NULL,
+ `fa` int(11) DEFAULT NULL,
+ `fb` int(10) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999999.9999999999999999999999
+b 99999999.9999999999999999999999
+fa 99999999
+fb 99999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,23) DEFAULT NULL,
+ `b` decimal(30,23) unsigned DEFAULT NULL,
+ `fa` int(10) DEFAULT NULL,
+ `fb` int(9) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999999.99999999999999999999999
+b 9999999.99999999999999999999999
+fa 9999999
+fb 9999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,24) DEFAULT NULL,
+ `b` decimal(30,24) unsigned DEFAULT NULL,
+ `fa` int(9) DEFAULT NULL,
+ `fb` int(8) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999999.999999999999999999999999
+b 999999.999999999999999999999999
+fa 999999
+fb 999999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,25) DEFAULT NULL,
+ `b` decimal(30,25) unsigned DEFAULT NULL,
+ `fa` int(8) DEFAULT NULL,
+ `fb` int(7) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99999.9999999999999999999999999
+b 99999.9999999999999999999999999
+fa 99999
+fb 99999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,26) DEFAULT NULL,
+ `b` decimal(30,26) unsigned DEFAULT NULL,
+ `fa` int(7) DEFAULT NULL,
+ `fb` int(6) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9999.99999999999999999999999999
+b 9999.99999999999999999999999999
+fa 9999
+fb 9999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,27) DEFAULT NULL,
+ `b` decimal(30,27) unsigned DEFAULT NULL,
+ `fa` int(6) DEFAULT NULL,
+ `fb` int(5) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 999.999999999999999999999999999
+b 999.999999999999999999999999999
+fa 999
+fb 999
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,28) DEFAULT NULL,
+ `b` decimal(30,28) unsigned DEFAULT NULL,
+ `fa` int(5) DEFAULT NULL,
+ `fb` int(4) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 99.9999999999999999999999999999
+b 99.9999999999999999999999999999
+fa 99
+fb 99
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` decimal(30,29) DEFAULT NULL,
+ `b` decimal(30,29) unsigned DEFAULT NULL,
+ `fa` int(4) DEFAULT NULL,
+ `fb` int(3) unsigned DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+a 9.99999999999999999999999999999
+b 9.99999999999999999999999999999
+fa 9
+fb 9
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index dc2664e040d..ca9eef211f4 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -2633,3 +2633,16 @@ ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'secret'
DROP USER untrusted@localhost;
DROP DATABASE secret;
set GLOBAL sql_mode=default;
+#
+# MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
+#
+SET NAMES utf8;
+SET SQL_MODE='';
+CREATE USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
+SELECT * FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE "'abcdefghijklmnopqrstuvwxyz'%";
+GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
+SELECT GRANTEE FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE '%觻%';
+GRANTEE
+'觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻'@'localhost'
+DROP USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
+SET SQL_MODE=DEFAULT;
diff --git a/mysql-test/r/grant5.result b/mysql-test/r/grant5.result
index 8c32d90a640..01ec063c1d9 100644
--- a/mysql-test/r/grant5.result
+++ b/mysql-test/r/grant5.result
@@ -23,3 +23,13 @@ ERROR HY000: Table 'user' was not locked with LOCK TABLES
REVOKE PROCESS ON *.* FROM u;
ERROR HY000: Table 'user' was not locked with LOCK TABLES
DROP TABLE t1;
+create database mysqltest1;
+use mysqltest1;
+create table t1(id int);
+insert t1 values(2);
+create user u1@localhost;
+grant select on mysqltest1.t1 to u1@localhost;
+grant update on mysqltest1.* to u1@localhost;
+update mysqltest1.t1 set id=1 where id=2;
+drop user u1@localhost;
+drop database mysqltest1;
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index 0a80fa4171c..657b740a90b 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -805,3 +805,33 @@ sum(col1)
33632261
drop table t1;
set optimizer_switch=@tmp_optimizer_switch;
+#
+# MDEV-22728: SIGFPE in Unique::get_cost_calc_buff_size from prepare_search_best_index_intersect
+# on optimized builds
+#
+SET @save_sort_buffer_size=@@sort_buffer_size;
+SET @save_innodb_file_format= @@innodb_file_format;
+SET @save_innodb_large_prefix= @@innodb_large_prefix;
+SET sort_buffer_size=2048;
+SET GLOBAL innodb_file_format = BARRACUDA;
+SET GLOBAL innodb_large_prefix = ON;
+CREATE TABLE t1 (
+a VARCHAR(1024) CHARACTER SET UTF8 PRIMARY KEY,
+b INT,
+c INT,
+INDEX (b)
+) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC;
+INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_100;
+EXPLAIN SELECT * FROM t1 WHERE a='1' OR b < 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,b b,PRIMARY 5,3074 NULL 4 Using sort_union(b,PRIMARY); Using where
+SELECT * FROM t1 WHERE a='1' OR b < 5;
+a b c
+2 2 2
+3 3 3
+4 4 4
+1 1 1
+DROP TABLE t1;
+SET GLOBAL innodb_file_format = @save_innodb_file_format;
+SET GLOBAL innodb_large_prefix = @save_innodb_large_prefix;
+SET sort_buffer_size= @save_sort_buffer_size;
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index b87a7dfef4b..8f3d536983f 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -1685,6 +1685,58 @@ id select_type table type possible_keys key key_len ref rows Extra
DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save;
#
+# MDEV-21932: ROR union with index_merge_sort_union=off
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t0 select a+10 from t0;
+insert into t0 select a+20 from t0;
+insert into t0 select a+40 from t0;
+insert into t0 select a+80 from t0;
+insert into t0 select a+160 from t0;
+delete from t0 where a > 300;
+create table t1 (
+f1 int, f2 int, f3 int, f4 int,
+primary key (f1), key (f3), key(f4)
+) engine=myisam;
+insert into t1 select a+100, a+100, a+100, a+100 from t0;
+insert into t1 VALUES (9,0,2,6), (9930,0,0,NULL);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+set optimizer_switch='index_merge_sort_union=off';
+set optimizer_switch='index_merge_union=on';
+explain select * from t1
+where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
+(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where
+select * from t1
+where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
+(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
+f1 f2 f3 f4
+9 0 2 6
+insert into t1 values (52,0,1,0),(53,0,1,0);
+insert into t1 values (50,0,1,0),(51,0,1,0);
+insert into t1 values (48,0,1,0),(49,0,1,0);
+insert into t1 values (46,0,1,0),(47,0,1,0);
+insert into t1 values (44,0,1,0),(45,0,1,0);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+explain select * from t1
+where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
+(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 13 Using union(f3,PRIMARY,f3); Using where
+select * from t1
+where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
+(f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
+f1 f2 f3 f4
+9 0 2 6
+drop table t0,t1;
+set optimizer_switch= @optimizer_switch_save;
+#
# MDEV-16695: Estimate for rows of derived tables is very high when we are using index_merge union
#
create table t0
@@ -1719,3 +1771,4 @@ key1 key2 key3 key8
3 3 3 1021
set @@optimizer_switch= @optimizer_switch_save;
drop table t0;
+# End of 10.1 tests
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 631dd8eabf5..dae46f9ff47 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -2101,3 +2101,13 @@ column_name
c1
c2
DROP TABLE tt1, tt2;
+#
+# MDEV-13242 Wrong results for queries with row constructors and information_schema
+#
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
+SCHEMA_NAME
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a',193);
+SCHEMA_NAME
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/r/innodb_ext_key,off.rdiff b/mysql-test/r/innodb_ext_key,off.rdiff
new file mode 100644
index 00000000000..47ca1e6849a
--- /dev/null
+++ b/mysql-test/r/innodb_ext_key,off.rdiff
@@ -0,0 +1,295 @@
+@@ -4,7 +4,7 @@
+ explain
+ select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 const,const 1 Using index
++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where
+ flush status;
+ select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
+ count(*)
+@@ -14,7 +14,7 @@
+ Handler_read_first 0
+ Handler_read_key 1
+ Handler_read_last 0
+-Handler_read_next 1
++Handler_read_next 5
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -45,7 +45,7 @@
+ select count(*) from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 NULL 1 Using where; Using index
++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
+ flush status;
+ select count(*) from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
+@@ -56,7 +56,7 @@
+ Handler_read_first 0
+ Handler_read_key 1
+ Handler_read_last 0
+-Handler_read_next 1
++Handler_read_next 6
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -66,7 +66,7 @@
+ select l_orderkey, l_linenumber from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem range PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 NULL 3 Using where; Using index
++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
+ flush status;
+ select l_orderkey, l_linenumber from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
+@@ -79,7 +79,7 @@
+ Handler_read_first 0
+ Handler_read_key 1
+ Handler_read_last 0
+-Handler_read_next 3
++Handler_read_next 6
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -88,7 +88,7 @@
+ explain
+ select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
++1 SIMPLE lineitem ref i_l_shipdate i_l_shipdate 4 const 6 Using index
+ flush status;
+ select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
+ min(l_orderkey)
+@@ -98,7 +98,7 @@
+ Handler_read_first 0
+ Handler_read_key 1
+ Handler_read_last 0
+-Handler_read_next 0
++Handler_read_next 6
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -108,7 +108,7 @@
+ select min(l_orderkey) from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
+ flush status;
+ select min(l_orderkey) from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
+@@ -119,7 +119,7 @@
+ Handler_read_first 0
+ Handler_read_key 1
+ Handler_read_last 0
+-Handler_read_next 0
++Handler_read_next 6
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -129,7 +129,7 @@
+ select max(l_linenumber) from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey=130;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where
+ flush status;
+ select max(l_linenumber) from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey=130;
+@@ -140,7 +140,7 @@
+ Handler_read_first 0
+ Handler_read_key 1
+ Handler_read_last 0
+-Handler_read_next 0
++Handler_read_next 5
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -152,7 +152,7 @@
+ where l_shipdate='1992-07-01' and l_orderkey=130
+ or l_receiptdate='1992-07-01' and l_orderkey=5603;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 8,8 NULL 2 Using union(i_l_shipdate,i_l_receiptdate); Using where
++1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 4,4 NULL 9 Using union(i_l_shipdate,i_l_receiptdate); Using where
+ flush status;
+ select l_orderkey, l_linenumber
+ from lineitem use index (i_l_shipdate, i_l_receiptdate)
+@@ -166,10 +166,10 @@
+ Handler_read_first 0
+ Handler_read_key 2
+ Handler_read_last 0
+-Handler_read_next 2
++Handler_read_next 9
+ Handler_read_prev 0
+ Handler_read_retry 0
+-Handler_read_rnd 2
++Handler_read_rnd 9
+ Handler_read_rnd_deleted 0
+ Handler_read_rnd_next 0
+ explain
+@@ -178,7 +178,7 @@
+ where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
+ or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 8,8 NULL 3 Using sort_union(i_l_shipdate,i_l_receiptdate); Using where
++1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 4,4 NULL 9 Using union(i_l_shipdate,i_l_receiptdate); Using where
+ flush status;
+ select l_orderkey, l_linenumber
+ from lineitem use index (i_l_shipdate, i_l_receiptdate)
+@@ -193,10 +193,10 @@
+ Handler_read_first 0
+ Handler_read_key 2
+ Handler_read_last 0
+-Handler_read_next 3
++Handler_read_next 9
+ Handler_read_prev 0
+ Handler_read_retry 0
+-Handler_read_rnd 3
++Handler_read_rnd 9
+ Handler_read_rnd_deleted 0
+ Handler_read_rnd_next 0
+ explain
+@@ -204,7 +204,7 @@
+ where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
+ or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem index_merge PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate,i_l_receiptdate 8,8 NULL 3 Using sort_union(i_l_shipdate,i_l_receiptdate); Using where
++1 SIMPLE lineitem index_merge PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate,PRIMARY,i_l_receiptdate,PRIMARY 4,4,4,4 NULL 2 Using union(intersect(i_l_shipdate,PRIMARY),intersect(i_l_receiptdate,PRIMARY)); Using where
+ flush status;
+ select l_orderkey, l_linenumber from lineitem
+ where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
+@@ -218,7 +218,7 @@
+ Handler_read_first 0
+ Handler_read_key 2
+ Handler_read_last 0
+-Handler_read_next 3
++Handler_read_next 9
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 3
+@@ -228,7 +228,7 @@
+ select max(l_orderkey) from lineitem
+ where l_partkey between 1 and 10 group by l_partkey;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index for group-by
++1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index
+ flush status;
+ select max(l_orderkey) from lineitem
+ where l_partkey between 1 and 10 group by l_partkey;
+@@ -246,9 +246,9 @@
+ show status like 'handler_read%';
+ Variable_name Value
+ Handler_read_first 0
+-Handler_read_key 21
+-Handler_read_last 1
+-Handler_read_next 0
++Handler_read_key 1
++Handler_read_last 0
++Handler_read_next 294
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -258,7 +258,7 @@
+ select max(l_orderkey) from lineitem
+ where l_suppkey in (1,4) group by l_suppkey;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE lineitem range i_l_suppkey i_l_suppkey 5 NULL # Using where; Using index for group-by
++1 SIMPLE lineitem range i_l_suppkey i_l_suppkey 5 NULL # Using where; Using index
+ flush status;
+ select max(l_orderkey) from lineitem
+ where l_suppkey in (1,4) group by l_suppkey;
+@@ -268,9 +268,9 @@
+ show status like 'handler_read%';
+ Variable_name Value
+ Handler_read_first 0
+-Handler_read_key 6
+-Handler_read_last 1
+-Handler_read_next 0
++Handler_read_key 2
++Handler_read_last 0
++Handler_read_next 1230
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -286,7 +286,7 @@
+ id select_type table type possible_keys key key_len ref rows Extra
+ 1 SIMPLE part range i_p_retailprice i_p_retailprice 9 NULL # Using where; Using index
+ 1 SIMPLE orders ref PRIMARY,i_o_orderdate i_o_orderdate 4 const # Using index
+-1 SIMPLE lineitem ref i_l_partkey i_l_partkey 9 dbt3_s001.part.p_partkey,dbt3_s001.orders.o_orderkey # Using index
++1 SIMPLE lineitem ref i_l_partkey i_l_partkey 5 dbt3_s001.part.p_partkey # Using where; Using index
+ flush status;
+ select o_orderkey, p_partkey
+ from part use index (i_p_retailprice),
+@@ -300,7 +300,7 @@
+ Handler_read_first 0
+ Handler_read_key 3
+ Handler_read_last 0
+-Handler_read_next 3
++Handler_read_next 26
+ Handler_read_prev 0
+ Handler_read_retry 0
+ Handler_read_rnd 0
+@@ -317,8 +317,8 @@
+ select * from t0, part ignore index (primary)
+ where p_partkey=t0.a and p_size=1;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE t0 ALL NULL NULL NULL NULL 5 Using where
+-1 SIMPLE part eq_ref i_p_size i_p_size 9 const,dbt3_s001.t0.a 1
++1 SIMPLE t0 ALL NULL NULL NULL NULL 5
++1 SIMPLE part ref i_p_size i_p_size 5 const 5 Using index condition
+ select * from t0, part ignore index (primary)
+ where p_partkey=t0.a and p_size=1;
+ a p_partkey p_name p_mfgr p_brand p_type p_size p_container p_retailprice p_comment
+@@ -495,7 +495,7 @@
+ select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
+ id select_type table type possible_keys key key_len ref rows Extra
+ 1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
+-1 SIMPLE t3 ref PRIMARY,col1 col1 12 test.t1.a,test.t1.a,test.t1.a # Using index
++1 SIMPLE t3 ref PRIMARY,col1 col1 8 test.t1.a,test.t1.a # Using where; Using index
+ drop table t1,t2,t3;
+ #
+ # Bug mdev-4340: performance regression with extended_keys=on
+@@ -705,13 +705,13 @@
+ select * from t1 force index(index_date_updated)
+ where index_date_updated= 10 and index_id < 800;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE t1 range index_date_updated index_date_updated 13 NULL # Using index condition
++1 SIMPLE t1 ref index_date_updated index_date_updated 5 const # Using index condition
+ # This used to work from the start:
+ explain
+ select * from t2 force index(index_date_updated)
+ where index_date_updated= 10 and index_id < 800;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE t2 range index_date_updated index_date_updated 13 NULL # Using index condition
++1 SIMPLE t2 ref index_date_updated index_date_updated 5 const # Using index condition
+ drop table t0,t1,t2;
+ #
+ # MDEV-11196: Error:Run-Time Check Failure #2 - Stack around the variable 'key_buff'
+@@ -746,11 +746,12 @@
+ "select_id": 1,
+ "table": {
+ "table_name": "t1",
+- "access_type": "range",
++ "access_type": "ref",
+ "possible_keys": ["f2"],
+ "key": "f2",
+- "key_length": "3070",
+- "used_key_parts": ["f2", "pk1"],
++ "key_length": "3066",
++ "used_key_parts": ["f2"],
++ "ref": ["const"],
+ "rows": 1,
+ "filtered": 100,
+ "index_condition": "t1.pk1 <= 5 and t1.pk2 <= 5 and t1.f2 = 'abc'",
+@@ -779,8 +780,8 @@
+ "access_type": "range",
+ "possible_keys": ["k1"],
+ "key": "k1",
+- "key_length": "3011",
+- "used_key_parts": ["pk1", "f2", "pk2"],
++ "key_length": "3007",
++ "used_key_parts": ["pk1", "f2"],
+ "rows": 1,
+ "filtered": 100,
+ "index_condition": "t1.f2 <= 5 and t1.pk2 <= 5 and t1.pk1 = 'abc'",
diff --git a/mysql-test/r/innodb_ext_key.result b/mysql-test/r/innodb_ext_key.result
index e02b78cad15..233b359157b 100644
--- a/mysql-test/r/innodb_ext_key.result
+++ b/mysql-test/r/innodb_ext_key.result
@@ -1,30 +1,6 @@
-DROP TABLE IF EXISTS t1,t2,t3,t4;
-DROP DATABASE IF EXISTS dbt3_s001;
SET SESSION STORAGE_ENGINE='InnoDB';
CREATE DATABASE dbt3_s001;
use dbt3_s001;
-set @save_ext_key_optimizer_switch=@@optimizer_switch;
-set optimizer_switch='extended_keys=off';
-explain
-select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where
-flush status;
-select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
-count(*)
-1
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 5
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
id select_type table type possible_keys key key_len ref rows Extra
@@ -44,29 +20,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select count(*) from lineitem
-where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem const PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 8 const,const 1
-flush status;
-select count(*) from lineitem
-where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
-count(*)
-1
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 0
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select count(*) from lineitem
where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
@@ -88,29 +41,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select count(*) from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
-flush status;
-select count(*) from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
-count(*)
-1
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 6
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select count(*) from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
@@ -132,31 +62,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select l_orderkey, l_linenumber from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
-flush status;
-select l_orderkey, l_linenumber from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-l_orderkey l_linenumber
-1088 3
-1217 1
-1221 3
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 6
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
@@ -180,27 +85,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem ref i_l_shipdate i_l_shipdate 4 const 6 Using index
-flush status;
-select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
-min(l_orderkey)
-130
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 6
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
id select_type table type possible_keys key key_len ref rows Extra
@@ -220,29 +104,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select min(l_orderkey) from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index
-flush status;
-select min(l_orderkey) from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-min(l_orderkey)
-1088
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 6
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select min(l_orderkey) from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
@@ -264,29 +125,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select max(l_linenumber) from lineitem
-where l_shipdate='1992-07-01' and l_orderkey=130;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where
-flush status;
-select max(l_linenumber) from lineitem
-where l_shipdate='1992-07-01' and l_orderkey=130;
-max(l_linenumber)
-2
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 5
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select max(l_linenumber) from lineitem
where l_shipdate='1992-07-01' and l_orderkey=130;
@@ -308,34 +146,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select l_orderkey, l_linenumber
-from lineitem use index (i_l_shipdate, i_l_receiptdate)
-where l_shipdate='1992-07-01' and l_orderkey=130
-or l_receiptdate='1992-07-01' and l_orderkey=5603;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 4,4 NULL 9 Using union(i_l_shipdate,i_l_receiptdate); Using where
-flush status;
-select l_orderkey, l_linenumber
-from lineitem use index (i_l_shipdate, i_l_receiptdate)
-where l_shipdate='1992-07-01' and l_orderkey=130
-or l_receiptdate='1992-07-01' and l_orderkey=5603;
-l_orderkey l_linenumber
-130 2
-5603 2
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 2
-Handler_read_last 0
-Handler_read_next 9
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 9
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select l_orderkey, l_linenumber
from lineitem use index (i_l_shipdate, i_l_receiptdate)
@@ -362,35 +172,6 @@ Handler_read_retry 0
Handler_read_rnd 2
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select l_orderkey, l_linenumber
-from lineitem use index (i_l_shipdate, i_l_receiptdate)
-where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
-or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem index_merge i_l_shipdate,i_l_receiptdate i_l_shipdate,i_l_receiptdate 4,4 NULL 9 Using union(i_l_shipdate,i_l_receiptdate); Using where
-flush status;
-select l_orderkey, l_linenumber
-from lineitem use index (i_l_shipdate, i_l_receiptdate)
-where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
-or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-l_orderkey l_linenumber
-130 2
-5603 2
-5959 3
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 2
-Handler_read_last 0
-Handler_read_next 9
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 9
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select l_orderkey, l_linenumber
from lineitem use index (i_l_shipdate, i_l_receiptdate)
@@ -418,33 +199,6 @@ Handler_read_retry 0
Handler_read_rnd 3
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select l_orderkey, l_linenumber from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
-or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem index_merge PRIMARY,i_l_shipdate,i_l_receiptdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate,PRIMARY,i_l_receiptdate,PRIMARY 4,4,4,4 NULL 2 Using union(intersect(i_l_shipdate,PRIMARY),intersect(i_l_receiptdate,PRIMARY)); Using where
-flush status;
-select l_orderkey, l_linenumber from lineitem
-where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
-or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-l_orderkey l_linenumber
-130 2
-5603 2
-5959 3
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 2
-Handler_read_last 0
-Handler_read_next 9
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 3
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
@@ -470,38 +224,6 @@ Handler_read_retry 0
Handler_read_rnd 3
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select max(l_orderkey) from lineitem
-where l_partkey between 1 and 10 group by l_partkey;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem range i_l_suppkey_partkey,i_l_partkey i_l_partkey 5 NULL # Using where; Using index
-flush status;
-select max(l_orderkey) from lineitem
-where l_partkey between 1 and 10 group by l_partkey;
-max(l_orderkey)
-5984
-5957
-5892
-5856
-5959
-5957
-5794
-5894
-5859
-5632
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 1
-Handler_read_last 0
-Handler_read_next 294
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select max(l_orderkey) from lineitem
where l_partkey between 1 and 10 group by l_partkey;
@@ -532,30 +254,6 @@ Handler_read_retry 0
Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=off';
-explain
-select max(l_orderkey) from lineitem
-where l_suppkey in (1,4) group by l_suppkey;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE lineitem range i_l_suppkey i_l_suppkey 5 NULL # Using where; Using index
-flush status;
-select max(l_orderkey) from lineitem
-where l_suppkey in (1,4) group by l_suppkey;
-max(l_orderkey)
-5988
-5984
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 2
-Handler_read_last 0
-Handler_read_next 1230
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select max(l_orderkey) from lineitem
where l_suppkey in (1,4) group by l_suppkey;
@@ -579,37 +277,6 @@ Handler_read_rnd 0
Handler_read_rnd_deleted 0
Handler_read_rnd_next 0
create index i_p_retailprice on part(p_retailprice);
-set optimizer_switch='extended_keys=off';
-explain
-select o_orderkey, p_partkey
-from part use index (i_p_retailprice),
-lineitem use index (i_l_partkey), orders
-where p_retailprice > 1100 and o_orderdate='1997-01-01'
-and o_orderkey=l_orderkey and p_partkey=l_partkey;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE part range i_p_retailprice i_p_retailprice 9 NULL # Using where; Using index
-1 SIMPLE orders ref PRIMARY,i_o_orderdate i_o_orderdate 4 const # Using index
-1 SIMPLE lineitem ref i_l_partkey i_l_partkey 5 dbt3_s001.part.p_partkey # Using where; Using index
-flush status;
-select o_orderkey, p_partkey
-from part use index (i_p_retailprice),
-lineitem use index (i_l_partkey), orders
-where p_retailprice > 1100 and o_orderdate='1997-01-01'
-and o_orderkey=l_orderkey and p_partkey=l_partkey;
-o_orderkey p_partkey
-5895 200
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 3
-Handler_read_last 0
-Handler_read_next 26
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 0
-set optimizer_switch='extended_keys=on';
explain
select o_orderkey, p_partkey
from part use index (i_p_retailprice),
@@ -646,7 +313,6 @@ Handler_read_rnd_next 0
create table t0 (a int);
insert into t0 values (1), (2), (3), (4), (5);
create index i_p_size on part(p_size);
-set optimizer_switch='extended_keys=on';
explain
select * from t0, part ignore index (primary)
where p_partkey=t0.a and p_size=1;
@@ -667,7 +333,6 @@ use test;
#
set @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='materialization=on,semijoin=on';
-SET optimizer_switch='extended_keys=on';
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1 WHERE 2 IN (SELECT MAX(s1.a) FROM t1 AS s1, t1 AS s2);
@@ -688,9 +353,7 @@ set optimizer_switch=@save_optimizer_switch;
# + extended_keys = on
# (valgrinf complains fixed by the patch for bug #914560)
#
-set @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch = 'derived_with_keys=on';
-SET optimizer_switch = 'extended_keys=on';
CREATE TABLE t1 (a varchar(1)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('j'), ('v');
CREATE TABLE t2 (b varchar(1)) ENGINE=MyISAM;
@@ -720,21 +383,6 @@ c int NOT NULL PRIMARY KEY
INSERT INTO t2 VALUES
(10), (11), (12), (13), (14),
(15), (16), (17), (18), (19), (24);
-set @save_optimizer_switch=@@optimizer_switch;
-SET optimizer_switch = 'extended_keys=off';
-EXPLAIN
-SELECT a FROM t1 AS t, t2
-WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t index a,b b 7 NULL 10 Using index
-1 PRIMARY t1 ref b b 3 test.t.b 2 Using index
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 11 Using index; FirstMatch(t)
-1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t.a 1 Using index
-SELECT a FROM t1 AS t, t2
-WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
-a
-24
-SET optimizer_switch = 'extended_keys=on';
EXPLAIN
SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
@@ -747,7 +395,6 @@ SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
a
24
-set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
#
# LP Bug #923236: hash join + extended_keys = on
@@ -756,12 +403,10 @@ CREATE TABLE t1 (a int) ENGINE=MyISAM;
CREATE TABLE t2 (b int) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES (4), (6);
INSERT INTO t2 (b) VALUES (0), (8);
-set @save_optimizer_switch=@@optimizer_switch;
set @save_join_cache_level=@@join_cache_level;
SET join_cache_level=3;
SET optimizer_switch='join_cache_hashed=on';
SET optimizer_switch='join_cache_bka=on';
-SET optimizer_switch='extended_keys=on';
EXPLAIN
SELECT * FROM t1, t2 WHERE b=a;
id select_type table type possible_keys key key_len ref rows Extra
@@ -786,26 +431,16 @@ UNIQUE KEY uq (c2,c3),
KEY c3 (c3),
KEY c4 (c4)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-set @save_optimizer_switch=@@optimizer_switch;
-set session optimizer_switch='extended_keys=off';
-INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
-ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
-DELETE FROM t1;
-set session optimizer_switch='extended_keys=on';
INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
-INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
-ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
-set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1;
#
# Bug mdev-4220: using ref instead of eq_ref
# with extended_keys=on
# (performance regression introduced in the patch for mdev-3851)
#
-set @save_optimizer_switch=@@optimizer_switch;
create table t1 (a int not null) engine=innodb;
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t2 (
@@ -815,29 +450,6 @@ insert into t2
select
A.a + 10 * B.a, A.a + 10 * B.a, A.a + 10 * B.a
from t1 A, t1 B;
-set optimizer_switch='extended_keys=off';
-explain
-select * from t1, t2 where t2.a=t1.a and t2.b < 2;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 10
-1 SIMPLE t2 eq_ref a a 4 test.t1.a 1 Using where
-flush status;
-select * from t1, t2 where t2.a=t1.a and t2.b < 2;
-a pk a b
-0 0 0 0
-1 1 1 1
-show status like 'handler_read%';
-Variable_name Value
-Handler_read_first 0
-Handler_read_key 10
-Handler_read_last 0
-Handler_read_next 0
-Handler_read_prev 0
-Handler_read_retry 0
-Handler_read_rnd 0
-Handler_read_rnd_deleted 0
-Handler_read_rnd_next 11
-set optimizer_switch='extended_keys=on';
explain
select * from t1, t2 where t2.a=t1.a and t2.b < 2;
id select_type table type possible_keys key key_len ref rows Extra
@@ -874,18 +486,6 @@ analyze table t1,t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
test.t3 analyze status OK
-set optimizer_switch='extended_keys=off';
-explain
-select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
-1 SIMPLE t3 ref col1 col1 8 test.t1.a,test.t1.a # Using index
-explain
-select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
-1 SIMPLE t3 ref PRIMARY,col1 col1 8 test.t1.a,test.t1.a # Using where; Using index
-set optimizer_switch='extended_keys=on';
explain
select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
@@ -900,7 +500,6 @@ drop table t1,t2,t3;
#
# Bug mdev-4340: performance regression with extended_keys=on
#
-set @save_optimizer_switch=@@optimizer_switch;
CREATE TABLE t1 (
page_id int(8) unsigned NOT NULL AUTO_INCREMENT,
page_namespace int(11) NOT NULL DEFAULT '0',
@@ -1000,16 +599,6 @@ INSERT INTO t3 VALUES
(89,'text-8008',''),(90,'text-9008',''),(91,'text-9',''),(92,'text-1009',''),
(93,'text-2009',''),(94,'text-3009',''),(95,'text-4009',''),(96,'text-5009',''),
(97,'text-6009',''),(98,'text-7009',''),(99,'text-8009',''),(100,'text-9009','');
-set optimizer_switch='extended_keys=off';
-EXPLAIN
-SELECT * FROM t1, t2 IGNORE INDEX (PRIMARY), t3
-WHERE page_id=rev_page AND rev_text_id=old_id AND page_namespace=4 AND page_title='Sandbox'
-ORDER BY rev_timestamp ASC LIMIT 10;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 const PRIMARY,name_title name_title 261 const,const 1
-1 SIMPLE t2 ref page_timestamp page_timestamp 4 const 10 Using where
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.rev_text_id 1
-set optimizer_switch='extended_keys=on';
EXPLAIN
SELECT * FROM t1, t2 IGNORE INDEX (PRIMARY), t3
WHERE page_id=rev_page AND rev_text_id=old_id AND page_namespace=4 AND page_title='Sandbox'
@@ -1027,7 +616,6 @@ create table t1 (a bigint not null unique auto_increment, b varchar(10), primary
create table t2 (a bigint not null unique auto_increment, b varchar(10), primary key (a), key (b(2))) engine = innodb default character set utf8;
insert into t1 (b) values (null), (null), (null);
insert into t2 (b) values (null), (null), (null);
-set optimizer_switch='extended_keys=on';
explain select a from t1 where b is null order by a desc limit 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index b PRIMARY 8 NULL 3 Using where
@@ -1042,14 +630,6 @@ select a from t2 where b is null order by a desc limit 2;
a
3
2
-set optimizer_switch='extended_keys=off';
-explain select a from t2 where b is null order by a desc limit 2;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range b b 9 NULL 3 Using where; Using filesort
-select a from t2 where b is null order by a desc limit 2;
-a
-3
-2
explain select a from t2 where b is null order by a desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index b PRIMARY 8 NULL 3 Using where
@@ -1067,7 +647,6 @@ a
2
1
drop table t1, t2;
-set optimizer_switch=@save_optimizer_switch;
#
# MDEV-10325: Queries examines all rows of a tables when it should not
#
@@ -1213,7 +792,6 @@ EXPLAIN
}
}
drop table t1;
-set optimizer_switch=@save_ext_key_optimizer_switch;
set global innodb_file_format = @save_innodb_file_format;
set global innodb_large_prefix = @save_innodb_large_prefix;
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/insert_debug.result b/mysql-test/r/insert_debug.result
new file mode 100644
index 00000000000..ef4f304800a
--- /dev/null
+++ b/mysql-test/r/insert_debug.result
@@ -0,0 +1,25 @@
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+CREATE TABLE t1(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL);
+INSERT INTO t1(c1, c2, c3) VALUES('A1','B1','IT1'), ('A2','B2','IT1'), ('A3','B3','IT1'), ('A4','B4','IT1'), ('A5','B5','IT1'), ('A6','B6','IT1'), ('A7','B7','IT1');
+CREATE TABLE t2(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL);
+INSERT INTO t2(c1, c2, c3) VALUES ('A3','B3','IT2'), ('A2','B2','IT2'), ('A4','B4','IT2'), ('A5','B5','II2');
+CREATE TABLE result(id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10),
+c3 VARCHAR(10), update_count INT DEFAULT 0, UNIQUE KEY uniq_idx (c1,c2), PRIMARY KEY (id)) ENGINE = innodb;
+SET DEBUG_SYNC = "ha_write_row_end WAIT_FOR flushed EXECUTE 1";
+INSERT INTO result(c1, c2, c3) SELECT * FROM t1 ON DUPLICATE KEY UPDATE c2=t1.c2, c3='UT1', update_count=update_count+1;
+INSERT INTO result(c1, c2, c3) SELECT * FROM t2 ON DUPLICATE KEY UPDATE c2=t2.c2, c3='UT2', update_count=update_count+1;
+SET DEBUG_SYNC = "now SIGNAL flushed";
+SELECT * FROM result;
+id c1 c2 c3 update_count
+1 A1 B1 IT1 0
+2 A3 B3 UT1 1
+3 A2 B2 UT1 1
+4 A4 B4 UT1 1
+5 A5 B5 UT1 1
+9 A6 B6 IT1 0
+10 A7 B7 IT1 0
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE result;
+SET DEBUG_SYNC = "RESET";
diff --git a/mysql-test/r/limit_rows_examined.result b/mysql-test/r/limit_rows_examined.result
index 0b3bc196a31..a3ab6122c59 100644
--- a/mysql-test/r/limit_rows_examined.result
+++ b/mysql-test/r/limit_rows_examined.result
@@ -853,3 +853,18 @@ Warnings:
Warning 1931 Query execution was interrupted. The query examined at least 22 rows, which exceeds LIMIT ROWS EXAMINED (21). The query result may be incomplete.
drop view v;
drop table t1, t2;
+#
+# 10.1 Test
+#
+# MDEV-17729: Assertion `! is_set() || m_can_overwrite_status'
+# failed in Diagnostics_area::set_error_status
+#
+set @old_mode= @@sql_mode;
+CREATE TABLE t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,k INT, c CHAR(20));
+INSERT INTO t1 (k,c) VALUES(0,'0'), (0,'0'),(0,'0'),(0,'0'),(0,'0'),(0,'0'),(0,'0');
+SET @@sql_mode='STRICT_TRANS_TABLES';
+INSERT INTO t1 (c) SELECT k FROM t1 LIMIT ROWS EXAMINED 2;
+Warnings:
+Warning 1931 Query execution was interrupted. The query examined at least 4 rows, which exceeds LIMIT ROWS EXAMINED (2). The query result may be incomplete.
+SET @@sql_mode=@old_mode;
+DROP TABLE t1;
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index ff5055e1ae4..cfecae91733 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -377,6 +377,14 @@ slow_log
slow_log_new
drop table slow_log_new, general_log_new;
use test;
+SET GLOBAL LOG_OUTPUT = 'FILE';
+SET GLOBAL slow_query_log = 1;
+SET GLOBAL general_log = 1;
+ALTER TABLE mysql.slow_log ADD COLUMN comment_text TEXT NOT NULL;
+ALTER TABLE mysql.general_log ADD COLUMN comment_text TEXT NOT NULL;
+SET GLOBAL LOG_OUTPUT = 'NONE';
+ALTER TABLE mysql.slow_log DROP COLUMN comment_text;
+ALTER TABLE mysql.general_log DROP COLUMN comment_text;
SET GLOBAL LOG_OUTPUT = 'TABLE';
SET GLOBAL general_log = 0;
FLUSH LOGS;
diff --git a/mysql-test/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/r/mysql_tzinfo_to_sql_symlink.result
index fc9ddce08b1..0de4a5ada95 100644
--- a/mysql-test/r/mysql_tzinfo_to_sql_symlink.result
+++ b/mysql-test/r/mysql_tzinfo_to_sql_symlink.result
@@ -15,6 +15,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -32,6 +33,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -57,6 +59,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -71,6 +74,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -142,6 +146,8 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
diff --git a/mysql-test/r/mysqlbinlog_row_minimal.result b/mysql-test/r/mysqlbinlog_row_minimal.result
index 2e34b2885ca..a7fecc7e4bc 100644
--- a/mysql-test/r/mysqlbinlog_row_minimal.result
+++ b/mysql-test/r/mysqlbinlog_row_minimal.result
@@ -295,6 +295,24 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
DROP TABLE t1,t2;
+#
+# MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log with system table
+#
+FLUSH BINARY LOGS;
+CREATE TABLE t1 (pk INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1), (2) ON DUPLICATE KEY UPDATE pk= pk + 10;
+FLUSH BINARY LOGS;
+Proof: two subsequent patterns must be found
+FOUND /### UPDATE `test`.`t1`/ in mysqlbinlog.sql
+FOUND /### INSERT INTO `test`.`t1`/ in mysqlbinlog.sql
+DROP TABLE t1;
+SELECT * FROM t1;
+pk
+2
+11
+# Cleanup
+DROP TABLE t1;
CREATE TABLE `t1` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`is_deleted` BIT(1) DEFAULT b'0',
@@ -319,28 +337,28 @@ FLUSH BINARY LOGS;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
-# at 368
-#<date> server id 1 end_log_pos 406 GTID 0-1-16
+# at POS
+#<date> server id 1 end_log_pos END_LOG_POS GTID D-S-N
/*!100101 SET @@session.skip_parallel_replication=0*//*!*/;
/*!100001 SET @@session.gtid_domain_id=0*//*!*/;
/*!100001 SET @@session.server_id=1*//*!*/;
-/*!100001 SET @@session.gtid_seq_no=16*//*!*/;
+/*!100001 SET @@session.gtid_seq_no=21*//*!*/;
BEGIN
/*!*/;
-# at 406
-#<date> server id 1 end_log_pos 453 Table_map: `test`.`t1` mapped to number 34
-# at 453
-#<date> server id 1 end_log_pos 498 Update_rows: table id 34 flags: STMT_END_F
+# at POS
+#<date> server id 1 end_log_pos END_LOG_POS Table_map: `test`.`t1` mapped to number TID
+# at POS
+#<date> server id 1 end_log_pos END_LOG_POS Update_rows: table id TID flags: STMT_END_F
### UPDATE `test`.`t1`
### WHERE
### @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
### SET
### @2=b'1' /* BIT(1) meta=1 nullable=1 is_null=0 */
### @3=X /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
-# at 498
-#<date> server id 1 end_log_pos 576 Query thread_id=4 exec_time=x error_code=0
+# at POS
+#<date> server id 1 end_log_pos END_LOG_POS Query thread_id=TID exec_time=x error_code=0
SET TIMESTAMP=X/*!*/;
-SET @@session.pseudo_thread_id=4/*!*/;
+SET @@session.pseudo_thread_id=TID/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1342177280/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
@@ -350,8 +368,6 @@ SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
COMMIT
/*!*/;
-# at 576
-#<date> server id 1 end_log_pos 620 Rotate to master-bin.000004 pos: 4
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
diff --git a/mysql-test/r/mysqld--defaults-file.result b/mysql-test/r/mysqld--defaults-file.result
index 5fd5ca8d95a..ccad1d119fc 100644
--- a/mysql-test/r/mysqld--defaults-file.result
+++ b/mysql-test/r/mysqld--defaults-file.result
@@ -10,3 +10,13 @@ Could not open required defaults file: MYSQL_TEST_DIR/with.ext
Fatal error in defaults handling. Program aborted
Could not open required defaults file: MYSQL_TEST_DIR/no_extension
Fatal error in defaults handling. Program aborted
+#
+# MDEV-21374: When "--help --verbose" prints out configuration file paths,
+# the --defaults-file option is not considered
+#
+# Test on `defaults-file`
+Default options are read from the following files in the given order:
+MYSQLTEST_VARDIR/my.cnf
+# Test on `defaults-extra-file`
+Default options are read from the following files in the given order:
+<first-defaults> MYSQLTEST_VARDIR/my_test.cnf ~/.my.cnf
diff --git a/mysql-test/r/mysqld--help,win.rdiff b/mysql-test/r/mysqld--help,win.rdiff
index 128155870b8..b71401bf461 100644
--- a/mysql-test/r/mysqld--help,win.rdiff
+++ b/mysql-test/r/mysqld--help,win.rdiff
@@ -1,6 +1,6 @@
--- mysqld--help.result
+++ mysqld--help,win.reject
-@@ -333,7 +333,6 @@
+@@ -337,7 +337,6 @@ The following specify which files/extra groups are read (specified before remain
The number of segments in a key cache
-L, --language=name Client error messages in given language. May be given as
a full path. Deprecated. Use --lc-messages-dir instead.
@@ -8,7 +8,7 @@
--lc-messages=name Set the language used for the error messages.
-L, --lc-messages-dir=name
Directory where error messages are
-@@ -533,6 +532,7 @@
+@@ -537,6 +536,7 @@ The following specify which files/extra groups are read (specified before remain
Use MySQL-5.6 (instead of MariaDB-5.3) format for TIME,
DATETIME, TIMESTAMP columns.
(Defaults to on; use --skip-mysql56-temporal-format to disable.)
@@ -16,7 +16,7 @@
--net-buffer-length=#
Buffer length for TCP/IP and socket communication
--net-read-timeout=#
-@@ -924,6 +924,9 @@
+@@ -928,6 +928,9 @@ The following specify which files/extra groups are read (specified before remain
files within specified directory
--server-id=# Uniquely identifies the server instance in the community
of replication partners
@@ -26,7 +26,7 @@
--show-slave-auth-info
Show user and password in SHOW SLAVE HOSTS on this
master.
-@@ -1034,6 +1037,10 @@
+@@ -1038,6 +1041,10 @@ The following specify which files/extra groups are read (specified before remain
Log slow queries to given log file. Defaults logging to
'hostname'-slow.log. Must be enabled to activate other
slow log options
@@ -37,7 +37,7 @@
--socket=name Socket file to use for connection
--sort-buffer-size=#
Each thread that needs to do a sort allocates a buffer of
-@@ -1052,6 +1059,7 @@
+@@ -1056,6 +1063,7 @@ The following specify which files/extra groups are read (specified before remain
NO_ENGINE_SUBSTITUTION, PAD_CHAR_TO_FULL_LENGTH
--stack-trace Print a symbolic stack trace on failure
(Defaults to on; use --skip-stack-trace to disable.)
@@ -45,7 +45,7 @@
--stored-program-cache=#
The soft upper limit for number of cached stored routines
for one connection.
-@@ -1088,25 +1096,11 @@
+@@ -1092,25 +1100,11 @@ The following specify which files/extra groups are read (specified before remain
COMMIT, ROLLBACK
--thread-cache-size=#
How many threads we should keep in a cache for reuse
@@ -73,7 +73,7 @@
--thread-stack=# The stack size for each thread
--time-format=name The TIME format (ignored)
--timed-mutexes Specify whether to time mutexes. Deprecated, has no
-@@ -1115,8 +1109,8 @@
+@@ -1119,8 +1113,8 @@ The following specify which files/extra groups are read (specified before remain
size, MariaDB will automatically convert it to an on-disk
MyISAM or Aria table.
-t, --tmpdir=name Path for temporary files. Several paths may be specified,
@@ -84,7 +84,7 @@
--transaction-alloc-block-size=#
Allocation block size for transactions to be stored in
binary log
-@@ -1240,7 +1234,6 @@
+@@ -1244,7 +1238,6 @@ key-cache-block-size 1024
key-cache-division-limit 100
key-cache-file-hash-size 512
key-cache-segments 0
@@ -92,7 +92,7 @@
lc-messages en_US
lc-messages-dir MYSQL_SHAREDIR/
lc-time-names en_US
-@@ -1307,6 +1300,7 @@
+@@ -1310,6 +1303,7 @@ myisam-sort-buffer-size 134216704
myisam-stats-method NULLS_UNEQUAL
myisam-use-mmap FALSE
mysql56-temporal-format TRUE
@@ -100,7 +100,7 @@
net-buffer-length 16384
net-read-timeout 30
net-retry-count 10
-@@ -1403,6 +1397,8 @@
+@@ -1406,6 +1400,8 @@ safe-user-create FALSE
secure-auth TRUE
secure-file-priv (No default value)
server-id 0
@@ -109,7 +109,7 @@
show-slave-auth-info FALSE
silent-startup FALSE
skip-grant-tables TRUE
-@@ -1426,6 +1422,7 @@
+@@ -1429,6 +1425,7 @@ slave-transaction-retries 10
slave-type-conversions
slow-launch-time 2
slow-query-log FALSE
@@ -117,15 +117,8 @@
sort-buffer-size 2097152
sql-mode NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
stack-trace TRUE
-@@ -1438,15 +1435,13 @@
- sync-relay-log 10000
- sync-relay-log-info 10000
- sysdate-is-now FALSE
--table-cache 421
-+table-cache 2000
+@@ -1444,10 +1441,8 @@ sysdate-is-now FALSE
table-definition-cache 400
--table-open-cache 421
-+table-open-cache 2000
tc-heuristic-recover OFF
thread-cache-size 0
-thread-pool-idle-timeout 60
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index c7fb52eeeb6..dce1578adee 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -1277,7 +1277,6 @@ max-binlog-cache-size 18446744073709547520
max-binlog-size 1073741824
max-binlog-stmt-cache-size 18446744073709547520
max-connect-errors 100
-max-connections 151
max-delayed-threads 20
max-digest-length 1024
max-error-count 64
@@ -1442,9 +1441,7 @@ sync-master-info 10000
sync-relay-log 10000
sync-relay-log-info 10000
sysdate-is-now FALSE
-table-cache 421
table-definition-cache 400
-table-open-cache 421
tc-heuristic-recover OFF
thread-cache-size 0
thread-pool-idle-timeout 60
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 8d8e3b7eda4..68a9190030d 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -5628,3 +5628,22 @@ select count(*) from t2;
count(*)
2
drop tables t2, t1;
+#
+# MDEV-22037: Add ability to skip content of some tables
+# (work around for MDEV-20939)
+#
+use mysql;
+# check that all tables we need are not empty
+select count(*) >= 1 from mysql.proc;
+count(*) >= 1
+1
+select count(*) >= 1 from mysql.db;
+count(*) >= 1
+1
+# for proc we have CREATE and INSERT for all other only CREATE
+FOUND /INSERT INTO `proc`/ in MDEV-20939.sql
+NOT FOUND /INSERT INTO `db`/ in MDEV-20939.sql
+FOUND /CREATE TABLE `db`/ in MDEV-20939.sql
+FOUND /CREATE TABLE `proc`/ in MDEV-20939.sql
+use test;
+# End of 10.1 tests
diff --git a/mysql-test/r/nested_profiling.result b/mysql-test/r/nested_profiling.result
new file mode 100644
index 00000000000..86841383046
--- /dev/null
+++ b/mysql-test/r/nested_profiling.result
@@ -0,0 +1,16 @@
+SET @saved_profiling=@@GLOBAL.profiling;
+SET @saved_init_connect=@@GLOBAL.init_connect;
+SET GLOBAL init_connect="set @a=2;set @b=3";
+SET GLOBAL profiling=on;
+create user mysqltest1@localhost;
+SELECT @a, @b;
+@a @b
+2 3
+SHOW PROFILES;
+Query_ID Duration Query
+1 # set @a=2;set @b=3
+2 # set @b=3
+3 # SELECT @a, @b
+DROP USER mysqltest1@localhost;
+SET GLOBAL profiling=@saved_profiling;
+SET GLOBAL init_connect=@saved_init_connect;
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 380687554d7..f7427bcd30e 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -3237,3 +3237,138 @@ o 15
p 16
set @@sort_buffer_size= @save_sort_buffer_size;
drop table t1;
+#
+# MDEV-22715: SIGSEGV in radixsort_for_str_ptr and in native_compare/my_qsort2 (optimized builds)
+#
+SET @save_sort_buffer_size= @@sort_buffer_size;
+SET @save_max_sort_length= @@max_sort_length;
+SET max_sort_length=8;
+SET sort_buffer_size=1024;
+CREATE TABLE t1(a INT, b DECIMAL(65), c BLOB);
+INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_25;
+INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_25;
+SELECT * FROM t1 ORDER BY a,b;
+a b c
+1 1 1
+1 1 1
+2 2 2
+2 2 2
+3 3 3
+3 3 3
+4 4 4
+4 4 4
+5 5 5
+5 5 5
+6 6 6
+6 6 6
+7 7 7
+7 7 7
+8 8 8
+8 8 8
+9 9 9
+9 9 9
+10 10 10
+10 10 10
+11 11 11
+11 11 11
+12 12 12
+12 12 12
+13 13 13
+13 13 13
+14 14 14
+14 14 14
+15 15 15
+15 15 15
+16 16 16
+16 16 16
+17 17 17
+17 17 17
+18 18 18
+18 18 18
+19 19 19
+19 19 19
+20 20 20
+20 20 20
+21 21 21
+21 21 21
+22 22 22
+22 22 22
+23 23 23
+23 23 23
+24 24 24
+24 24 24
+25 25 25
+25 25 25
+SET @@sort_buffer_size= @save_sort_buffer_size;
+SET @@max_sort_length= @save_max_sort_length;
+DROP TABLE t1;
+#
+# MDEV-22390: Assertion `m_next_rec_ptr >= m_rawmem' failed in Filesort_buffer::spaceleft |
+# SIGSEGV in __memmove_avx_unaligned_erms from my_b_write (on optimized)
+#
+SET @save_max_sort_length= @@max_sort_length;
+SET @save_sort_buffer_size= @@sort_buffer_size;
+SET @save_max_length_for_sort_data= @@max_length_for_sort_data;
+SET max_sort_length=8;
+SET sort_buffer_size=1024;
+SET max_length_for_sort_data=7000;
+CREATE TABLE t1(a VARCHAR(64), b VARCHAR(2048))DEFAULT CHARSET=utf8;
+INSERT INTO t1 SELECT seq,seq from seq_1_to_100;
+ANALYZE FORMAT=JSON SELECT * FROM t1 ORDER BY a LIMIT 5;
+ANALYZE
+{
+ "query_block": {
+ "select_id": 1,
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "read_sorted_file": {
+ "r_rows": 5,
+ "filesort": {
+ "r_loops": 1,
+ "r_total_time_ms": "REPLACED",
+ "r_limit": 5,
+ "r_used_priority_queue": false,
+ "r_output_rows": 35,
+ "r_sort_passes": 1,
+ "r_buffer_size": "REPLACED",
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "r_loops": 1,
+ "rows": 100,
+ "r_rows": 100,
+ "r_total_time_ms": "REPLACED",
+ "filtered": 100,
+ "r_filtered": 100
+ }
+ }
+ }
+ }
+}
+SELECT * FROM t1 ORDER BY a LIMIT 5;
+a b
+1 1
+10 10
+100 100
+11 11
+12 12
+SET max_sort_length= @save_max_sort_length;
+SET sort_buffer_size= @save_sort_buffer_size;
+SET max_length_for_sort_data= @save_max_length_for_sort_data;
+DROP TABLE t1;
+#
+# MDEV-23596: Assertion `tab->ref.use_count' failed in join_read_key_unlock_row
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY(b));
+INSERT INTO t1 VALUES (0, 1),(1, 2);
+CREATE TABLE t2 SELECT * FROM t1;
+EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t1 index PRIMARY b 5 NULL 1 Using where
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2;
+c
+1
+NULL
+DROP TABLE t1,t2;
+# end of 10.1 tests
diff --git a/mysql-test/r/parser_precedence.result b/mysql-test/r/parser_precedence.result
index 4330c8a2045..f23295bd61b 100644
--- a/mysql-test/r/parser_precedence.result
+++ b/mysql-test/r/parser_precedence.result
@@ -619,7 +619,7 @@ select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2);
Testing that / is left associative
select 15 / 5 / 3, (15 / 5) / 3, 15 / (5 / 3);
15 / 5 / 3 (15 / 5) / 3 15 / (5 / 3)
-1.00000000 1.00000000 9.0000
+1.00000000 1.00000000 8.9998
Testing that / has precedence over |
select 105 / 5 | 2, (105 / 5) | 2, 105 / (5 | 2);
105 / 5 | 2 (105 / 5) | 2 105 / (5 | 2)
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 6cea712e482..662929c5b48 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -2756,5 +2756,56 @@ SELECT 1 FROM t1 WHERE a XOR 'a';
1
DROP TABLE t1;
#
+# Bug #25207522: INCORRECT ORDER-BY BEHAVIOR ON A PARTITIONED TABLE
+# WITH A COMPOSITE PREFIX INDEX
+#
+create table t1(id int unsigned not null,
+data varchar(2) default null,
+key data_idx (data(1),id)
+) default charset=utf8
+partition by range (id) (
+partition p10 values less than (10),
+partition p20 values less than (20)
+);
+insert t1 values (6, 'ab'), (4, 'ab'), (5, 'ab'), (16, 'ab'), (14, 'ab'), (15, 'ab'), (5, 'ac'), (15, 'aa') ;
+select id from t1 where data = 'ab' order by id;
+id
+4
+5
+6
+14
+15
+16
+drop table t1;
+create table t1(id int unsigned not null,
+data text default null,
+key data_idx (data(1),id)
+) default charset=utf8
+partition by range (id) (
+partition p10 values less than (10),
+partition p20 values less than (20)
+);
+insert t1 values (6, 'ab'), (4, 'ab'), (5, 'ab'), (16, 'ab'), (14, 'ab'), (15, 'ab'), (5, 'ac'), (15, 'aa') ;
+select id from t1 where data = 'ab' order by id;
+id
+4
+5
+6
+14
+15
+16
+drop table t1;
+#
+# MDEV-5628: Assertion `! is_set()' or `!is_set() ||
+# (m_status == DA_OK_BULK && is_bulk_op())' fails on UPDATE on a
+# partitioned table with subquery (MySQL:71630)
+#
+CREATE TABLE t1 (a INT) PARTITION BY HASH(a) PARTITIONS 2;
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+UPDATE t1 SET a = 7 WHERE a = ( SELECT b FROM t2 ) ORDER BY a LIMIT 6;
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/processlist_notembedded.result b/mysql-test/r/processlist_notembedded.result
index e6b30f3ec70..fd34c78ea5d 100644
--- a/mysql-test/r/processlist_notembedded.result
+++ b/mysql-test/r/processlist_notembedded.result
@@ -1,8 +1,10 @@
#
# MDEV-20466: SHOW PROCESSLIST truncates query text on \0 bytes
#
-SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync';
+SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync WAIT_FOR go';
SET DEBUG_SYNC= 'now WAIT_FOR in_sync';
FOUND /sleep/ in MDEV-20466.text
+SET DEBUG_SYNC= 'now SIGNAL go';
+user
SET DEBUG_SYNC = 'RESET';
End of 5.5 tests
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index d34c96cd568..265245ac1bd 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -2090,6 +2090,18 @@ drop procedure p1;
drop table t1;
set GLOBAL query_cache_size=1355776;
SET GLOBAL userstat=default;
+#
+# MDEV-5924: MariaDB could crash after changing the query_cache size
+#
+SET GLOBAL query_cache_size= 50*1024;
+SET GLOBAL query_cache_type= 1;
+SET query_cache_type= 1;
+CREATE TABLE t1 (pk INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM v1 WHERE pk IN (5178922,5178924,6911605,6584899,1754348,7735031,9583206,8377182,6309967,3110885,7197937,5582397,9811721,8310302,7001831,3687942,8454635,8743988,9524703,3313583,1376007,5276565,7238861,5307189,2242691,2052764,8160476,7668014,5891525,9070968,1989181,3014068,5365005,2974655,6877822,7813446,6188705,1028564,6426696,6098205,7231857,2749710,4996963,9879425,2995803,8160614,1934799,1981216,3673522,2135299,4803054,8515609,1825485,5805694,8211425,3712249,8013259,3496368,4339706,2326187,3236816,8158416,5749801,6339492,2517486,1769729,2576400,8177368,5471847,4670669,5694046,5155990,1219314,1304321,7951736,2381942,1467330,3329376,6069503,3821151,8118179,4575775,5291671,4757186,6241302,9809112,5388351,3356292,5753921,8776535,7101943,8558868,6655212,5498901,1629516,8016143,1156005,1280700,9236450,8289703,4549957,5404968,3594833,3034667,3167602,7983322,3939941,8382949,9258422,6927947,9639236,3246566,3144943,5516067,5266540,3760726,6491516,9515090,7776229,1582824,4031951,3336517,5871612,4268432,2600433,6188018,6158355,6442214,7808502,7692871,9180969,3982238,9212692,9944381,3932525,5937118,6315460,2464477,1933151,3393646,4244674,7036026,1470764,3015029,2453765,9876129,2097534,3467391,4287658,8120651,4975540,4454101,7758102,6087905,2167022,7575454,5370086,8289703,7460235,8734512,7346801,6660293,5826843,4305511,8093597,8970031,9104476,1784973,9245925,6893890,4996414,3144393,1145568,2702056,4984878,5602859,7088073,2044113,5248275,6037094,2185287,1791564,3180374,8750991,9187011,6411453,9600372,4819671,3105667,2837051,1252548,3729003,7986618,8305633,5684432,4528808,8670104,4132202,2101516,5218475,6885513,4886413,1288803,9584167,6524475,3943649,6195846,4204986,5435592,8877334,9276275,8848358,3583435,6662216,7178298,1973526,5917205,9156387,8877334,4559432,2792144,9831634,8846710,6979858,5287277,2220718,9358123,4140029,1263122,8049789,9508361,3597030,8504348,4525924,9062866,1880691,9788375,4746612,7711822,9735366,9227523,9701721,2832519,4498870,3725021,4836151,2351181,7339935,9890686,7641098,1797607,1571838,3258377,6244186,5147476,6760543,9151580,2465576,2545776,6846237,4037582,8310440,2503616,1998245,1716445,2364913,4665039,8420440,1187728,1065917,1734710,5826705,8538681,8311950,4662017,7804519,7696853,7385116,8674362,2787612,2393341,1652313,2254364,3852737,4177108,7013641,8654037,9062728,7826629,2569396,1039138,2572692,9001892,3470550,4859359,5218887,6479568,1424621,3535644,7808639,7817291,8825149,6060302,2830047,7787765,5971313,9603256,1800491,3429214,9350021,8716796,1972564,6054946,6445510,9234802,5616729,6064559,2048233,9458511,1597244,3902862,2530120,5723846,3463821,9008346,3055130,2941696,8774337,3095367,2195037,6208480,9869262,3615295,9916641,1078002,1815597,7737228,1412261,6588607,9740173,6696411,7740386,1641326,9269546,3848754,7745193,6819458,5297164,1280975,1224395,5247589,7793533,5314743,8814025,2579010,7882659,6753128,9558349,8710067,7898727,4209106,2634902,7311233,1644897,8363449,6201339,1770828,3572174,5493408,8835449,5644332,5096115,7116088,1534484,3204544,1772064,2091903,6744476,9183166,5546005,1030075,7387725,1300888,5799789,7340209,7356552,7677627,9410995,5775894,9442581,5718353,6544937,9809524,7171569,4565475,1397293,6687759,1509353,3715682,8607208,3506118,3910827,1890167,1559341,4150329,9679336,9756927,1292373,3445419,2105361,6594238,4234237,8359466,7352432,1492462,9482818,1601226,8561614,4186584,5849365,1460189,9139495,3113357,8384460,7229660,8701553,7786254,4606399,2057708,1638992,1083221,8147293,9569198,4776550,2539871,8040039,7104141,8090713,7242568,2361480,6913940,7958053,1414596,3451461,9160644,7901473,8289703,5428588,3063232,2302291,5366378,8216918,8033447,8048965,8636322,7807952,7146026,6589569,2882644,1971328,7786392,5357864,4637985,2137222,9819961,9039932,8900680,1666732,8126968,1652999,7199035,8229003,7845581,8902328,8100051,9506164,8168579,8786560,4753890,6941268,5035552,2919860,9570983,4751968,4566574,7540023,1621963,7924270,7578750,6669494,5857192,6409805,2030792,4401779,5737991,8241088,4739746,2776901,7373718,8786697,9211593,6219741,1758331,3863586,6932754,5006164,8200302,5925033,1962127,2728149,8540191,9044326,6171264,4224899,9248672,5911026,6974502,1950317,4998611,2561569,2891845,3243957,8806335,8058303,8791778,1475708,3335281,7841186,9153228,5532135,5453994,5966369,4194824,3612686,8645385,9952621,1211349,2806289,4358520,7454330,5964035,2415313,8897384,6479431,1467330,6496185,8941055,8369903,5015502,5586105,4288482,3266204,1793212,6083923,6920394,1272048,7913696,1253234,3975372,9038970,7229522,7319061,4729995,9990386,5756942,4622741,8179565,1901840,2060729,6308593,2311767,6058517,9440521,4506286,2667724,2707412,9264328,7481658,7283767,4022613,7292282,7722808,1607543,3303695,9334091,4429382,7483169,2624877,7084777,1376693,3797668,1654510,6480667,4619720,9884094,5862548,9422256,4009429,6273574,8836135,8204696,7987167,1890991,6920944,2501831,7627502,3287765,9907714,8246444,2397872,6005920,6982330,5250473,8604049,6665649,4658172,8910156,2989349,2872344,5909790,5837142,1457168,6535461,2226623,1763137,9385314,1692550,9805267,2558547,7501022,7434143,5598876,5709976,6785263,6020614,1443572,3101684,3374557,4787536,3978530,9441757,1930130,9930648,8580841,9180145,1442749,9766128,9032516,7260009,3941177,6559494,9137985,4546386,3074356,5515518,9012878,2276748,4035247,9025100,6259704,9377487,4794540,5761474,2752593,3987731,8114746,2718948,3247390,3037689,3311660,8790679,5536666,2222091,5232482,8974563,4368682,3214843,8420028,8806335,8848220,7466827,6930969,8109664,5539825,4431991,9777114,1658630,1989456,4565338,4458084,9845504,1885635,9934494,5555755,2949661,1578155,8792465,5856231,1098190,3172134,3951339,2971771,6514724,7918090,8303161,8927734,5148162,3115005,8331726,8686172,9277099,5245941,8956710,9073989,9181930,1564422,7557327,9082504,3478927,5851699,1516220,6011001,3210998,7561996,3128875,3419052,8286682,3075180,4222702,9359085,4364151,5275878,8327606,8856597,5770950,4176971,9744155,7107299,3555694,8808120,1351837,1360076,6263137,8084533,7500198,4953704,5528839,7879226,7829376,8476745,9084976,9013153,9360595,1519927,9272705,2386062,6703552,2987976,2653991,7962310,6720443,7441421,9816116,8835861,1495346,2436462,3964523,5086776,2948287,9331619,3395294,2654541,4939971,5529388,2443054,8942016,4211166,4622741,4996826,3370712,8998596,8414672,6178268,8606521,4673553,8279541,6275634,5673858,3244918,1834274,1526931,7676940,2071578,4389968,8847671,8347793,5627304,3150848,6094223,3139175,7662246,4629882,6958709,6080078,6604812,6250503,8088928,8115158,5547515,6602340,9526214,7144378,6659744,2319869,8054733,1483261,5373657,5053268,2558273,4960433,3183807,8498855,9974731,2374801,8405883,1960617,4945877,2526550,7739700,5407440,6752304,8544998,3976608,6499618,1631164,8728744,3698516,8548431,5066864,5619064,5310623,6882492,6150802,6524063,6251052,3584671,8603775,2213165,7723495,4073150,9552993,9999450,8793975,6491241,4660095,9930786,4196609,8377456,4691268,3305343,4692779,5583221,8125320,4233688,4325836,7907516,4892318,4463714,3417266,1417343,9836441,1187866,2645751,7921936,2998275,2052352,5054229,9570159,9308273,7085052,4329132,6040390,5786056,7763320,5193618,8289703,5839752,2938400,9261032,2333740,8758682,8836135,3190261,2023376,1993301,8853439,8487869,8288879,1314758,9366775,4800720,2819610,1451126,3274719,2042053,9648025,2290206,7490997,1195281,1606033,1245407,3106765,2140518,9124389,8877197,7443206,5344268,1341262,5363906,7709762,3759902,4991333,2916427,3489913,1779754,4042251,5729888,4771057,3584533,4547760,5565505,7738327,7732559,5686904,2558273,2051116,4332153,9457275,9341644,4819946,2643692,7991149,1085830,4004486,4451492,8963714,3540176,4449020,5051483,2061691,2676651,5276153,9197860,7980850,3026428,2856414,8852752,4922805,8302612,1072509,9081542,9056823,8404922,6097930,3939804,4919097,7398712,5407302,6692565,2214401,5561660,7238311,9212554,4992568,6093811,5223144,1899368,7665542,4582092,7409286,9964294,1835372,4815963,3387054,7423294,9401657,1044494,8743713,6644226,8916748,6272750,6561965,4788223,4657897,3687393,6183486,3993774,6385223,8807159,2952682,2643692,7253280,2452804,5163818,3558853,6846511,3127502,1926834,8465347,4805801,2904479,2171691,8575622,3015853,8413299,9511245,3628479,4821868,1020324,9179046,5233032,4244400,3795471,2762893,2857376,7661010,6360778,4951644,1309265,8922927,7212219,2014862,9049407,5376403,5611511,2232940,5183456,2757949,4638946,6997848,7474517,6429168,1501800,5802124,8222274,9924880,8694000,3835708,8349304,5278213,1097091,5408126,6541915,8095245,3619415,6916961,2786102,4845352,7466827,3578079,8144683,4338470,1635971,9640609,3117614,1855010,5728103,6300903,7430709,1900192,3673660,6037643,5595443,7049072,6462951,3585632,8084533,1853363,8477294,2266586,1465270,1276580,2511856,2895828,4337097,3626968,7087249,8985000,9414840,7458724,1141174,7457214,1602325,4407272,7694519,5595306,3399688,8429092,5586380,2441543,4488845,6415573,9871047,2366287,5840713,7647552,8970306,3026016,8186569,5060821,9175888,2428634,4199768,7791061,9595565,2325363,2228820,2966415,5135116,7646453,5928054,6217681,2612930,8201812,4628372,4872955,3597305,5363082,6790893,7307388,2064025,6947860,9389984,2415451,4464401,8022598,7566390,6675811,3299850,6845413,9396438,2775527,1796508,1665359,7119934,1264907,2772644,8598693,4670669,2209182,5293182,1299514,7853683,7307525,3205093,1643661,5012481,3448440,2148208,6146820,6530380,5167251,4132614,4331054,9009719,4979522,3280487,7764144,6472427,9053253,4821456,3984985,4425674,7194503,2939361,6038879,6136795,9609985,1561401,3836807,7960662,8419204,4684951,6060989,9063690,5382308,6334548,5833572,9388198,8814849,5744033,4868148,1200775,6155197,5857192,1321624,9067535,4156234,2739959,4067108,3602661,8168441,4998748,5604919,4829833,5483520,9798538,3330474,2504852,4206909,1574035,1379440,9239746,3629440,8028366,1766845,8773513,1564834,9511657,7040695,7232955,4622467,6376022,7167312,3728591,2885940,4396835,8868270,7126800,9963195,6857360,8126831,5344406,3878555,7389236,9083740,5007949,4776962,9162017,8039764,2822631,7905044,1516357,9784667,6493438,7841873,9634292,3971252,2542480,3446517,4340805,4752929,6867660,3490188,3628890,9403579,5384231,3443496,9004089,6138854,1594360,7386215,9240707,3856857,5428863,2509521,9643905,7018722,9202941,5178375,4411254,7385116,1032135,5022506,3187652,5829727,7550186,7026824,2408035,9947540,9273666,7087936,3519851,2677337,8457244,2005661,4680969,7654968,2781570,4380081,5025390,3519851,9721084,1380264,2092041,1889892,2931121,7856018,3507766,5226303,4501617,8759506,6521591,6303924,5419250,4346023,2481506,6510330,3082870,7123367,4848236,7687789,8214035,6017868,4840545,8739181,4010116,7725280,6304473,6717834,6878509,8717071,7901062,6616348,4601318,7868927,3206878,3577255,2269744,3181472,1819305,4741119,5834259,1561264,7062255,9452194,2613754,3131347,7384979,6041351,2607711,7039733,7047561,2902420,1954162,9234252,9188522,8082885,4378570,3174057,3865371,2107696,6976425,7944458,9164901,7252593,5173294,8744537,1974624,9989013,4207321,5217926,2511032,1816970,1975036,7593170,5195953,3204681,2588897,5102981,1978607,2856002,7484954,7652359,6692153,1021011,7428237,5203643,2542892,8071487,3258789,8846160,9323516,7058685,6720581,9020843,3444595,1471038,4219131,5868041,4378570,3913986,5849914,1166580,6608795,5926269,9542007,7833496,7679412,9654891,2661956,2453765,9437225,8606246,1918182,2806838,9062179,7191619,1914337,6861343,9976791,2286773,4190429,2203964,6232238,7523681,6100128,7373992,6461715,7533432,4364425,3069549,5995483,3859741,9647476,2696838,9232879,3760177,9996704,3229263,1862838,5615081,5493682,2845703,2029144,3163070,6955413,6317382,9031143,8281463,4034286,6611404,5656692,6529281,2557037,7679138,3738891,7174179,1447692,4899871,1031311,2919723,9078796,6147369,9996154,1052597,5393844,9947265,8596496,4228469,3644683,5696243,9690322,3616119,1088714,2409408,9116287,6616210,8487594,6966949,9066986,8876098,1753799,3326492,2843505,4818298,3586044,6671554,9584304,9400833,3439788,9963745,9062454,5329025,4675338,4869110,9144851,4437484,6226333,2525177,6007293,2460083,9634979,2118820,6699844,6908035,2795578,3744247,9154464,7273742,2250106,4507247,1230575,4279830,6382064,2348434,8891067,3391723,4348358,9550247,3103195,8312500,1096817,1399078,1557693,9679061,5311035,8970581,3799728,4678497,3626144,2506088,5866256,6802154,2960510,8350540,3022857,9459060,2306274,6918197,1693374,6662902,2821807,9658737,3177215,7515991,7572296,6487258,7247650,3706619,2758773,1652862,7224166,6737197,6782653,9508499,6613464,6106307,7986755,3156753,1912689,1157928,3418365,2435089,6668395,2821121,4458084,6213150,7384841,4956588,5656692,9468399,7376190,1529541,7625167,8110488,4155548,4326660,9321182,7022293,2455001,2438247,6575973,6285659,7469299,7221694,2205200,8063247,1420089,6965988,1546844,1101211,1029525,1977233,7771560,1325469,1002197,7301620,8807983,6497558,9104614,4806625,6226608,6400192,4939971,1838119,5926544,5520736,1008239,7172256,2969299,1701065,2148345,9481033,6402252,3724060,5954696,3031097,1415832,4303314,2261367,1832077,2679534,9446289,6289642,5956481,6198181,4659408,2550033,5247451,2534515,3963287,5095428,2133926,2739273,8188217,3215667,3772262,5836044,9515914,7171432,1232360,3201110,3740264,8057205,2948013,2683380,3211685,3389938,5149536,5809814,2937438,1515121,2497161,1916946,9803070,3426055,2634490,2554565,6387695,1088165,3881027,9005325,4338607,8863464,7781997,8261825,4775314,5127700,7733795,7307662,2691619,7675155,7405029,3044555,5825195,7004577,1170974,5709426,6961456,8078491,6280166,4126296,6142974,3652511,6972854,8634674,3751251,3765670,8268692,6040664,6930145,7486328,5643508,7432495,6320541,5509338,5313095,5205291,1573486,7694519,9343841,2139007,5612060,4143325,1307479,9871459,7109771,6907073,8700454,8613937,1154495,8917709,7844482,8447906,4566436,7239135,8489517,6052200,3839691,8229141,2835678,4199905,4175323,8708282,8194808,4871032,1574859,5727005,5008087,8324310,1463348,2027908,8441726,9971160,4810195,5793334,3275268,9397537,4217071,9775192,7305740,5373931,9941085,2398422,1982727,9201156,4322540,4933517,4495849,5232894,6585449,7331008,2030380,7920013,2480133,3811264,4413452,9220382,1735946,9804443,7867004,1716995,4794265,9334091,9085937,6289505,6787734,2436599,6362701,1682113,9238510,2713180,9974731,8810867,5440124,1605346,7554306,2156448,8995162,1488616,5659713,9083602,1474746,8179290,3266479,6432189,3670639,3946395,9397125,2223464,2407348,7623107,5608078,1825759,9384216,8912216,1553573,3422897,2014999,9478012,3343109,1127990,4734252,2919174,6914352,5589126,6739257,9217086,7136825,6427658,1636795,4750732,8867584,3355194,6962417,7476028,3676681,3311248,7041381,5358688,6461715,2466674,1160812,5658477,7668701,3436492,1520339,1155868,7340484,5543807,9931472,4916351,4708572,9482269,6733489,3684921,1550277,1217529,7894882,8505722,1027053,1472686,7768676,7660186,6224548,1642013,7472045,9516738,9112304,7475891,9356063,7386627,1142272,2380706,6537246,8979507,5205017,6678558,9957977,7552108,7161132,8668594,6944839,1344284,2669509,6835388,1734024,1395782,1526519,2048233,4932006,8337219,7240371,8092910,5380798,6250778,3054855,9382293,7395965,8190826,7143417,6188568,4846725,3462585,3192459,4239730,2046173,3249038,7091369,8025619,6921768,7681472,3949142,9657363,7432083,9947952,7155502,5621810,9702407,4531005,9706253,6277420,4844802,7171432,7510910,7433593,5931900,8650329,8901092,5858154,4095260,4981582,3058837,1055618,3214157,8112823,8584686,2161529,9165863,8723663,3921676,9294815,7104553,2218933,4856338,6214111,9738388,4507385,9814605,5619476,3073944,6663589,6171264,3944747,7595642,2061828,1291549,3983886,9349472,8080001,1524597,7195190,5899627,8965774,1866134,8026992,2628311,2957077,8510116,9107772,6343338,8253860,4008056,8646896,4668334,3932388,3253845,5886444,5178100,2396499,2014038,2950347,5752685,4460418,2222091,3933761,6116195,6655349,5753921,7576416,4029617,9855392,7905731,3363021,5107925,9814193,8291625,3396118,7727340,8709106,7378662,2883880,9994369,1283721,6381515,9586502,9243728,1684173,5730987,8065444,5034179,1582687,1839355,8079864,3111434,6681854,4377883,6971893,4306335,6193237,1788269,6387695,2837463,4385025,5243469,3174743,4987213,4790969,8780242,4800720,2618560,4176147,4818984,7139160,2503341,3850814,9791671,2962158,9929962,5429962,5096252,3986495,4558197,7627365,9094863,9817352,4991607,7182281,5376953,5630050,8035095,2510208,6003860,2938125,7106887,3171859,1955535,7287338,1773712,7754669,7495941,8222000,4877899,7259323,4678359,1366531,4223800,3587005,3707168,2965866,2295425,1219451,7376739,3728454,9970886,6685424,5303894,2315887,9703781,2909561,2175811,2323165,7140121,5034454,7728713,5091583,6640106,2812194,1678405,8201538,2672393,4156784,8321426,5984634,2550033,2953506,6023086,1902389,1477493,4717636,4315399,2133514,6376846,5195816,4818298,9213790,2461318,1505645,7708389,3072433,4026733,2905441,4950271,9309646,2427673,3788604,5009185,8055969,6708496,2996353,3267303,8261962,7856567,5043243,5857742,4757736,8148254,6347595,3138214,7927566,9555328,1061660,9522094,7344879,3679702,9596115,2885391,5208862,1187316,2430694,6269180,7927566,8208404,1305557,1094345,3691787,5673171,5388214,4610794,3382659,1052047,6508132,9796203,1656845,1468566,2053451,3425094,7553344,4655014,8623550,3527130,1465820,9716827,3031921,7952148,3823211,9178497,9751296,2261642,4323776,9275726,9396713,8665298,9065475,3965347,4339019,9221206,8415771,3620239,6043273,4017669,5966918,7879364,1225357,1557693,1418029,5619750,3420288,4062301,4727935,8520965,4057769,9912384,1385345,3190261,1635009,5948928,9135787,8316482,4085784,7848876,2012527,4822143,2933731,4295349,4014236,6482864,3328826,7162643,2271255,2981796,9557113,9432693,9047897,6868209,5119186,8063522,3421249,8389816,6970932,1526794,9981323,6666061,8019989,2235137,9397674,2172653,4471405,9574966,1193222,2005249,3118026,1768218,3572723,3890502,7165664,9276138,4645675,1415008,1691864,3969055,9891784,3438964,9327087,8777359,2208221,2164550,3255218,9043640,4385986,8827209,9126037,7295166,6357345,1478454,2973831,9655166,1058364,2829772,8735198,6611129,8250564,6625549,2459808,6358993,6145446,6513763,8809906,3443222,1175506,7884445,5938491,3910003,2754791,6642028,6344024,7692321,7374542,4383651,1791976,6447158,1875610,7949401,4899871,5562210,9243316,1815460,1476806,2551406,6766448,3296005,1213958,2557037,9905792,9026611,9817352,3179687,7716079,5693908,2177871,2351318,7162918,6483001,7673095,6473388,7181182,7209884,9192642,2536437,6816848,3608978,9982421,6441802,3296966,8742614,5900588,7242019,3370437,5003005,1180038,9520996,3764846,3674896,3289688,2631469,9101318,2526824,8989807,5007400,7113479,5401260,7174453,3273345,5511123,2270706,1593536,6365859,5335891,1730178,7051544,7387725,6149566,5393157,4172851,1414047,7900924,7161407,4330230,4966888,5813796,5835769,2828125,9380371,6140365,6038192,7937316,2771408,5123031,4912918,4870758,1837982,4010116,2574890,6298431,3201385,2466812,6776748,3491561,2513092,7227188,6759307,5692810,9042953,7330047,3757431,8803588,5969116,6781829,1129501,8984313,9088272,2991958,5577041,1259963,3164169,1823287,5426803,6726211,7632995,2600433,4440368,5447265,5885894,7922348,5123031,7642471,7846130,9620559,1999069,5252807,7059509,5707778,4822280,9482543,3017227,8660079,8191787,6408432,2930847,9877914,8539230,9252243,2676239,4667510,2959274,3407928,5126190,6587783,7850250,7819076,3590988,2506912,4833679,3799865,6584762,2210281,4922119,8892715,4637023,7906829,3403945,1856384,9367874,3473297,7413269,3380325,2544815,4784790,7654968,9615203,6342239,9971298,4251541,2117309,4519607,7946517,3183120,1297866,6738845,1051910,3286804,8972640,3738891,2159606,7285964,5103530,6586410,7077911,4817749,6329193,7722259,1603561,5926681,9375427,3019973,4063812,9994644,6939620,2578460,4693328,6574325,7145065,7464492,9687576,1096542,1156280,6125946,6278930,8918533,8050064,3693298,2677200,1683486,6537109,2888824,4219543,1459091,8626159,3761962,7572845,9624130,3825820,3968780,9332580,1971603,1976409,3816619,2862869,9997940,2307785,6790069,4718322,6846374,8813613,1777969,3496368,4872543,9539810,7721435,7458587,2303665,3877731,4899459,2769210,5956069,4456573,4572067,7691223,1483673,7730087,9200744,7586166,8124221,3849990,6962142,1059600,8411376,1920242,4776962,5097625,6823440,6225646,9569747,6536422,7835830,9529373,6981643,4710769,5347152,2032440,9251419,6622802,7945831,8088516,5485855,2476974,2988937,5269012,3038101,7923171,9959075,7870986,2211242,2853256,9069732,7463119,3007064,6093948,3587417,7560760,3138900,7839126,1839767,7027923,5026901,8167617,6376571,7295303,8993240,9487762,3256179,5992187,1379440,4252777,2920959,7083404,4800170,3793411,8635635,1105880,1255706,5607391,8953414,8598556,2320556,7952972,5181121,5320098,5126464,5088424,8310302,2346237,9359497,9002166,7384567,9643218,4989135,3976333,5771224,3207702,6949234,5828079,1304595,2371093,1488204,6173599,6773727,8357406,6408294,9555328,4717910,9692520,1911865,6779769,5003417,3555969,6274536,2307785,9147460,4669708,8062423,2040130,4858810,8818420,2114013,7345428,1764511,8593612,3003219,2669921,6790618,1456893,4204849,9576339,4165985,6714675,8679168,5553833,9517425,4499008,9095275,5443008,2026672,2348159,7412719,4820083,2114974,7480285,6037643,2184051,8626983,2354614,6275634,6289505,8980880,7612533,9296875,2471069,1254608,5995071,1334533,9300170,7675155,9326675,8334060,1420776,9482681,6162338,3772125,9906066,7634506,9190582,6864776,4980621,4321441,2985504,1883026,7451583,1762176,2202453,6793502,6691879,2246124,2810958,2945541,5521011,6893066,9458099,9021118,3825271,6098617,2557449,1967208,7262207,4133438,1194869,4129455,7893096,7865768,4447372,3305892,5086364,4075759,3208389,6939208,4536224,8330490,7111282,5166290,9741546,2888275,8646896,8943939,6785263,8600479,9068771,9970336,1762588,9280670,1178115,1618530,3697692,9509460,6584213,6604125,3295181,7342956,8532638,7602783,2369445,9894943,3896545,5538314,9294677,8260726,6422164,2759735,1321487,3750839,8825698,9824768,3100723,1905136,5832061,8110076,3261810,3254257,4751968,2966964,2386199,6297744,8689193,9639648,4221878,6668258,6972305,7666915,9481719,7949813,2905578,2983993,4068893,1119064,5430648,8445571,1074844,9077972,5795669,9986267,2391555,9248260,9822845,8139328,2283752,1693374,2869735,4131240,6762603,8740417,8077941,2270980,2107284,3566955,7001831,5853759,8375259,3725296,9212966,6295822,7248474,3069274,3972213,5722198,6054946,5055191,8563949,9722595,9314178,1884674,9386138,3497467,6645874,9457138,1390701,1110000,9389160,2602355,2966140,1065917,1773025,4560668,8858108,9937103,9985168,4180130,1220413,3248764,1978744,8799468,8390914,3350250,1365570,5284805,7485504,8485122,2234451,2189544,2404602,6783477,5243881,6506759,1344696,7390609,4827224,8981018,9410720,7455017,4858947,2450195,3420425,7191207,9621932,8185333,4497222,9738250,4422927,8697296,8542800,1031723,7697265,4978424,7184341,8407806,1947021,6649032,3291748,8159240,5358276,1976959,1654510,5760513,1439041,4238906,4916351,4981994,6522415,5391647,4358245,9611770,1479003,5523620,4626174,8002960,7481796,3053894,8994476,3166503,5167526,6147781,4260742,2627899,4039230,4318557,6865875,3765258,6450592,5683197,2331268,5849777,2020767,6841018,1609466,3505157,6818222,9844543,1439590,1806671,4161727,7229934,9302505,7736267,8379104,4578521,1070449,2215637,9368972,1574035,7941986,9432556,1309539,1029113,2759872,6681716,6356933,2844879,7301071,7437988,8677932,7377288,9637863,6880569,6660156,3174057,5158874,5587478,8644012,8555709,2346786,7618026,9019470,7005401,9906204,1703262,4032501,7838989,8333786,1762863,3143569,9122741,3526306,2465850,5283157,4307983,3519302,7056213,3846557,7551559,6949920,1160125,7774307,5189910,6339355,2794616,7558563,6337158,4785751,8296295,8522476,1073608,4164199,9388610,6213287,8196319,8426071,9106262,8256332,2998275,9091156,4796463,4509582,6045196,5527465,9914581,7866455,6419692,9112030,1833175,4547760,9400970,2865753,2384552,8228454,8048828,3656906,7353118,2841583,6660018,9567001,7639175,4403564,3567642,6511566,7309448,8705261,7249710,5712310,2257522,1211624,2218246,7110458,4687561,3014617,1655746,4319107,5145690,5181259,4268157,7204940,2313140,8344085,1324645,8695922,1282760,1873413,4350143,6906112,2536437,9478836,5441497,9173278,8342300,8581115,2676376,3102645,5790725,3300399,2581344,1209014,7187911,4402877,6129516,9254028,8025482,7049758,7237350,6868759,6244735,7693283,1226455,6558395,6015396,6962966,5222869,9681259,5745407,3885696,6958709,6495498,1543685,9283279,5948654,9869125,5851013,2692443,9506988,8744674,4460968,4648147,3575607,1954162,4647460,8678619,3831451,7477539,7618713,7850387,9041580,9737701,4016433,4211715,7136001,1026779,5677841,1975311,8964263,7656478,5381347,7785430,8208404,4928024,3792312,2912307,4417709,7512557,4328857,9718750,5635406,5338775,7167449,1241424,3586044,4579208,2104400,1230850,8892166,5830688,9494354,6495361,4289169,8081100,6983703,6889770,2306961,5557952,7257400,4796051,2386474,3050186,7518600,3436630,6901718,7799987,3918792,9866241,8053634,5555618,7658538,3985122,6106307,4879959,3976608,9416625,6934402,4309494,6746124,1595596,5348388,2456649,5898254,4907012,1169189,4647735,5388626,6224136,9518524,2193664,2929748,9683593,4296173,3884460,1203933,4047058,8309890,5801712,9778625,5489837,8029602,6043823,1441375,1160125,5433120,4456710,7173080,1354446,1911590,3964248,7478637,7652221,1706008,7592483,2295013,5852111,9839462,9779861,7191894,7055389,4018493,3069549,7088897,2740234,8468368,7775405,2202453,1168365,6172912,1716995,6445648,1971328,6488357,9616577,6997436,4256210,4597885,4251403,6260665,4079055,5777130,4956176,1926696,4624389,3939117,7569137,8367843,3940353,6426834,5414031,2072952,1567993,3523422,5414718,2348022,6912017,1646820,1932601,7998428,9695816,9699523,1423660,1212448,3342422,7540847,6507171,9365539,3629714,2051803,7540298,3961776,9458236,1759292,7292007,5433807,1079238,6490966,9811035,2019119,3625869,5026763,8080276,6429992,5289886,5218612,9552169,2538909,9989013,8544448,8159515,6794601,4868148,7567077,4892868,5590774,5479263,8266906,3542373,2303253,3980590,2714279,2693130,7217575,1203659,2055099,9571945,6062225,1927520,1273422,6836624,1369415,1206130,3703598,5902236,9379959,3092895,3758117,9898788,7712097,9604354,1842376,1853500,4512878,3268402,3922088,6190216,8310577,5100921,7714981,6142974,6286895,6352264,8973876,8173522,9187973,8870880,2830322,8990081,9592819,8423873,4667098,3257827,1758468,2822631,2489883,3597442,8758407,3192733,9264739,3965072,4136734,4235610,1190887,2005386,6793365,8823089,9379272,2474227,2320968,8770904,6902542,9323104,5511398,8132461,2687774,9538986,7251495,8858795,2219345,1334396,3525619,9166824,3521362,6780456,2744628,6460342,3387741,4477172,2120056,1148727,2329895,1354995,9301132,2203689,1208877,8199890,9995468,3802337,5022644,2997863,2789672,5896057,8815811,6691329,1890853,3052383,8181900,4440643,3005828,5410736,9325714,7986343,2078857,7098373,9154190,1204071,8104995,1948257,1367492,1446594,4737823,6863677,6014160,5766830,8911804,3673385,7483993,9615615,1196792,2820159,5404418,2107421,2103164,4727249,9409347,8449142,6057556,8186843,2250930,2623092,2266860,3613098,8221176,3921401,1190063,1504409,3352722,9422119,7835418,6958709,2368209,4004486,4603790,8584686,4846313,5992187,1894561,9653381,9572631,3024642,3194107,7834320,4545974,6243225,5866668,5358825,6606872,5392471,1362960,9954544,4158294,7925231,6069641,9396301,2946640,7708389,5514968,6014709,1372299,3421661,5150497,4008468,5298126,2243103,7428649,8902191,7824295,2916702,9393417,3995971,7999801,1792938,2502792,8146469,2937164,6939071,5904022,8729019,9300720,4910720,6877136,9117935,3636032,9279434,1667831,2534515,8511627,9510559,1428466,3602523,6937561,3283370,7483444,3457229,2033676,2848999,9641845,6750656,3414657,9519485,2771545,7396926,5259674,8880355,3356979,7401870,7537002,7822784,7258224,7619949,1351837,3986770,5388900,2783355,5885345,7711685,7533843,8645797,5894409,7084091,2023925,9585128,3241348,5181808,8486633,7509124,4420455,2102203,7391571,6408020,4552703,5873672,2610733,5396316,5814620,7840362,9709548,5589263,4772842,6615524,1190475,4657211,4590332,7197799,6405685,2400756,4575637,7341857,1358840,9191680,5042007,5779602,2113876,8623138,6945663,8385284,6030639,1211624,8272674,3876358,5544769,8496246,3642486,2145874,6711380,2377685,7096176,7819900,7232131,8041687,5540786,4132888,1181274,3310287,6814514,8714462,1154083,6763565,8845474,6383575,1052734,4477722,8870193,9541183,5229187,8721603,5181121,6255996,2205200,6456222,2373291,1638992,8686996,9980773,8556671,2596588,8093048,3568054,8504623,7560211,8314971,7435653,9206100,4283401,6929321,7892547,6791992,1301025,7579025,2009506,7302032,6144348,1744049,4652954,4263351,2906402,5619476,5228500,9547088,4249618,3318664,9977890,4474014,5451385,3122970,4170928,6637084,5580062,3993637,6038879,2408584,4396011,7067474,1791290,3602249,5070022,4352478,5560974,5258575,3315643,7344192,6619781,4021240,2025161,2780471,2710296,7075027,5007125,6253387,7836242,2111541,1915847,1898132,8355621,7295303,5968704,1875610,7719787,9693756,3544433,4869796,7704544,1145706,3255493,6317245,3472610,1031860,7589187,1587219,2316024,4919235,4710357,8832290,8419067,9547775,1521026,7727890,1486557,8126968,6568695,9818313,4580718,7411621,1897857,3689453,8011749,5526229,1439590,8686996,6624313,9006011,1031448,7397201,7323867,1022659,7661285,8611053,3187515,2266174,7030807,1988632,5002456,1447555,3030685,2144638,9576477,4895065,6220428,6371353,4662017,9210083,5910064,9719985,6841293,2452667,9932708,9657226,7213043,4825027,6706710,9017822,1225082,2321380,5676330,3470275,4499008,9314453,1728942,7214279,5987243,5545181,1679092,4130966,3308502,1485870,3416030,4101303,8604049,4545288,2805877,1714660,7760848,5083892,8944076,8083297,4341766,6709320,7851348,6984664,5069198,3818130,8206207,6047531,6206283,2856552,1208740,7201782,8676147,8264846,4168457,4111053,4267471,6577621,1911727,1806671,5765869,4645263,9599685,4241104,9358261,2449234,8053222,9979949,7151107,1476669,2177322,6751754,1148864,1124420,7578201,5074142,1534347,3101135,8968246,2674316,5595993,3296829,1451263,9923645,3144943,9086761,5283157,1004257,4766937,7540847,3200012,2027496,3750564,3505432,5908416,9821609,3038925,8026718,5832611,6608383,9044326,6085433,6710281,7287475,6673751,9109970,6131713,8546234,6405960,5238250,1616333,1514984,6766036,2796127,5320922,7186264,8038940,6961318,2970397,8315383,1568405,8081375,4109130,7023391,7482070,1615234,2262878,9819137,4189880,1166305,1107666,7260147,2496063,1575958,6237045,1971740,8670928,6546585,3623809,8240676,3325531,5762435,4368408,4905502,4432128,6977523,5828079,7759201,8335571,8038803,2721008,9185089,3098388,5313919,6298019,5243469,1023483,4491729,7177612,1928619,5698440,4224899,1935623,4813766,4405349,8582626,1045181,9804031,9238922,2783630,3260299,8215820,3778030,2175399,7035339,5900039,7653457,9932296,8077117,6630218,7855743,2438110,8619705,4472229,5127288,2822357,5519500,7355453,5281784,1621139,9760635,1564010,5795806,1028564,1467605,5366516,5515106,4708984,8016555,4503128,6819732,4639083,2340744,7748764,2092453,2947463,7022430,6272064,3833236,3221023,2265899,3006378,2264389,9246887,5345092,3754959,8768981,1659179,9620010,1245819,6007843,2458297,6713989,5858016,8057067,8871841,4948623,1234832,6412139,5526779,6626510,4506011,5199249,7400085,1258590,1335357,2441131,9518112,9328323,7513244,3718154,2872482,8686172,9312942,6069915,4521530,3169250,7329635,2481369,9345626,2539459,6019790,7796005,9426788,2333190,2661682,3400787,6518432,2717163,6953353,8526733,1576919,1944000,9968826,4507247,3821975,3500900,5690200,9840835,7295028,8545684,1834411,5398788,4384613,5723571,6194335,7624618,2287048,1958282,6211776,7065826,3871688,7312057,9001205,7084503,8918945,8507644,6545211,6089553,6200378,6205596,5275878,5133193,3368927,6631866,2766326,1216979,2129257,6648345,5746505,3151260,1655197,6860656,8165008,3309600,9723968,1857208,5513595,5124679,9537612,9171768,9135513,3667617,5696105,5065490,1733062,1155456,7295852,8720642,4797424,8729431,8618469,2940185,1174819,8349166,5381072,4946838,9492019,6145721,8015182,2375488,8656646,7076538,8943801,5053405,9153228,6228530,9325851,8660079,5352508,6609756,8235595,3863174,6553588,5775894,5746368,7021057,6976562,6134460,3887207,3048950,2425750,9270370,2942520,1540664,3841339,4136734,4060379,6738983,2458023,8454223,6641342,3450637,7791198,2164138,2475189,2497436,5165878,1277404,9094314,4799072,8011611,2963394,9312530,8679718,6637908,5223281,1418579,9493942,6712203,2990997,8991867,8163360,4156784,2006210,2811096,4720794,8685211,6300903,6822616,2452804,7695617,2647125,7638488,7735992,9739898,5805557,2532318,6160552,5288925,7921936,3402160,8034545,2010192,3913024,7668701,8862503,8278717,8186294,5577865,2893081,5138687,9538436,7876892,3328140,5435317,4574264,1331100,9287811,6335372,2491119,5052169,8125869,5954284,6572814,9105850,7187225,7311096,9235763,4366760,3604034,9326538,5971450,2090805,3220886,7086151,2029556,9172729,6246246,1085006,8185333,1558105,7721298,1673873,8433761,5778503,2401443,1425445,3955734,7078598,6142837,9639099,8200164,1102584,2389770,4702804,7423568,6611816,5854034,6531890,4533752,5199249,7982772,7802185,7578750,3470687,5305953,2196548,8727920,3662261,1259277,1384796,4084274);
+pk
+DROP VIEW v1;
+DROP TABLE t1;
End of 5.5 tests
#
# Bug#12977203: SERVER CRASH ON A DERIVED TABLE WITH QUERY CACHE ENABLED
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 5adb8225b38..6911a2b37a8 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -2145,6 +2145,26 @@ value1 1003560 12345
value1 1004807 12345
drop table t1;
#
+# MDEV-22191: Range access is not picked when index_merge_sort_union is turned off
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_optimizer_switch="index_merge_sort_union=OFF";
+CREATE TABLE t1 (a INT, INDEX(a));
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+explain
+SELECT * FROM t1 WHERE a > 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index
+SELECT * FROM t1 WHERE a > 5;
+a
+6
+7
+8
+9
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1;
+# End of 5.5 tests
+#
# BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
#
CREATE TABLE t1 (pk INT PRIMARY KEY);
diff --git a/mysql-test/r/range_innodb.result b/mysql-test/r/range_innodb.result
index 6572b248911..faeec530acb 100644
--- a/mysql-test/r/range_innodb.result
+++ b/mysql-test/r/range_innodb.result
@@ -37,6 +37,33 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10
1 SIMPLE t2 range a,b b 5 NULL 201 Using where; Using join buffer (flat, BNL join)
drop table t0,t1,t2;
+#
+# MDEV-10466: constructing an invalid SEL_ARG
+#
+create table t1 (
+pk int, a int, b int,
+primary key (pk), index idx1(b), index idx2(b)
+) engine=innodb;
+Warnings:
+Note 1831 Duplicate index `idx2`. This is deprecated and will be disallowed in a future release.
+insert into t1 values (1,6,0),(2,1,0),(3,5,2),(4,8,0);
+create table t2 (c int) engine=innodb;
+insert into t2 values (1),(2);
+create table t3 (d int) engine=innodb;
+insert into t3 values (3),(-1),(4);
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='extended_keys=on';
+explain
+select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 4 Using where; Using join buffer (incremental, BNL join)
+select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
+pk a b
+1 6 0
+set optimizer_switch=@save_optimizer_switch;
+drop table t1,t2,t3;
CREATE TABLE t1 (
pk INT PRIMARY KEY, f1 INT, f2 CHAR(1), f3 CHAR(1),
KEY(f1), KEY(f2)
@@ -79,3 +106,4 @@ ERROR HY000: Table definition has changed, please retry transaction
DROP TABLE t0,t1;
set @@global.debug_dbug="-d";
set @@optimizer_switch= @optimizer_switch_save;
+# End of 10.1 tests
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
index 4ef7c0b658c..ecd3162da97 100644
--- a/mysql-test/r/range_mrr_icp.result
+++ b/mysql-test/r/range_mrr_icp.result
@@ -2147,6 +2147,26 @@ value1 1003560 12345
value1 1004807 12345
drop table t1;
#
+# MDEV-22191: Range access is not picked when index_merge_sort_union is turned off
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_optimizer_switch="index_merge_sort_union=OFF";
+CREATE TABLE t1 (a INT, INDEX(a));
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+explain
+SELECT * FROM t1 WHERE a > 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 5 Using where; Using index
+SELECT * FROM t1 WHERE a > 5;
+a
+6
+7
+8
+9
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1;
+# End of 5.5 tests
+#
# BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
#
CREATE TABLE t1 (pk INT PRIMARY KEY);
diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result
index 4f3c36b7660..faab314896c 100644
--- a/mysql-test/r/range_vs_index_merge.result
+++ b/mysql-test/r/range_vs_index_merge.result
@@ -1659,7 +1659,7 @@ SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where
+1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where
SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10
OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 );
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result
index dc7e9494946..9bb197ad056 100644
--- a/mysql-test/r/selectivity.result
+++ b/mysql-test/r/selectivity.result
@@ -1866,4 +1866,19 @@ id select_type table type possible_keys key key_len ref rows Extra
set optimizer_switch= @save_optimizer_switch;
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
drop table t1,t2;
+#
+# MDEV-21495: Conditional jump or move depends on uninitialised value in sel_arg_range_seq_next
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 SELECT seq, seq from seq_1_to_100;
+set optimizer_use_condition_selectivity=4;
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+SELECT * from t1 WHERE a = 5 and b = 5;
+a b
+5 5
+set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+drop table t1;
# End of 10.1 tests
diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result
index f0cbf1662aa..d0e31374784 100644
--- a/mysql-test/r/selectivity_innodb.result
+++ b/mysql-test/r/selectivity_innodb.result
@@ -1876,6 +1876,21 @@ id select_type table type possible_keys key key_len ref rows Extra
set optimizer_switch= @save_optimizer_switch;
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
drop table t1,t2;
+#
+# MDEV-21495: Conditional jump or move depends on uninitialised value in sel_arg_range_seq_next
+#
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 SELECT seq, seq from seq_1_to_100;
+set optimizer_use_condition_selectivity=4;
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+SELECT * from t1 WHERE a = 5 and b = 5;
+a b
+5 5
+set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+drop table t1;
# End of 10.1 tests
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
set @tmp_ust= @@use_stat_tables;
diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result
index b8bed681465..fd9f337c30d 100644
--- a/mysql-test/r/stat_tables_innodb.result
+++ b/mysql-test/r/stat_tables_innodb.result
@@ -770,4 +770,28 @@ set @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selecti
set @save_optimizer_switch=@@optimizer_switch;
set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
+#
+# MDEV-22851: Engine independent index statistics are incorrect for large tables on Windows.
+#
+CREATE TABLE t1(a INT) ENGINE=INNODB;
+INSERT INTO t1 SELECT 1 FROM seq_1_to_60000;
+SET @save_use_stat_tables= @@use_stat_tables;
+SET use_stat_tables= preferably;
+SELECT count(*) FROM t1;
+count(*)
+60000
+CREATE INDEX idx ON t1(a);
+ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES (idx);
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+SELECT * FROM mysql.index_stats where table_name='t1';
+db_name table_name index_name prefix_arity avg_frequency
+test t1 idx 1 60000.0000
+SELECT * FROM mysql.column_stats where table_name='t1';
+db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
+test t1 a 1 1 0.0000 4.0000 60000.0000 0 NULL NULL
+SET use_stat_tables= @save_use_stat_tables;
+DROP TABLE t1;
+# end of 10.1 tests
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/stat_tables_partition.result b/mysql-test/r/stat_tables_partition.result
index 12ae2570272..2dd63e858d4 100644
--- a/mysql-test/r/stat_tables_partition.result
+++ b/mysql-test/r/stat_tables_partition.result
@@ -9,5 +9,37 @@ ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
-SET use_stat_tables = DEFAULT;
DROP TABLE t1;
+#
+# MDEV-21472: ALTER TABLE ... ANALYZE PARTITION ... with EITS reads and locks all rows
+#
+CREATE TABLE t1 (
+id int(11) auto_increment primary key,
+c1 int(11) DEFAULT NULL
+) PARTITION BY RANGE (id) (
+PARTITION p0 VALUES LESS THAN (4),
+PARTITION p1 VALUES LESS THAN MAXVALUE
+);
+insert into t1(c1) values (1),(1),(1),(1), (1),(1),(1),(1);
+insert into t1(c1) select c1 from t1;
+insert into t1(c1) select c1 from t1;
+select count(*) from t1;
+count(*)
+32
+select count(*) from t1 where id <4;
+count(*)
+3
+flush status;
+set session use_stat_tables='preferably';
+# Must NOT show "Engine-independent statistics collected":
+alter table t1 analyze partition p0;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+# Should not have Handler_read_rnd_next=34
+show session status like 'Handler_read_rnd%';
+Variable_name Value
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 0
+drop table t1;
+SET use_stat_tables = DEFAULT;
diff --git a/mysql-test/r/stat_tables_rbr.result b/mysql-test/r/stat_tables_rbr.result
index 35e74e29b08..83f8e3bb7c6 100644
--- a/mysql-test/r/stat_tables_rbr.result
+++ b/mysql-test/r/stat_tables_rbr.result
@@ -13,7 +13,6 @@ SET use_stat_tables = PREFERABLY;
CREATE TABLE t1 ( a INT ) ENGINE=MyISAM PARTITION BY HASH(a) PARTITIONS 2;
ALTER TABLE t1 ANALYZE PARTITION p1;
Table Op Msg_type Msg_text
-test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index a7e2bd9d1b5..e7655131fcf 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -2534,3 +2534,118 @@ x
c1
1
drop table t1;
+#
+# MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT
+#
+set @save_sql_select_limit= @@sql_select_limit;
+SET sql_select_limit=0;
+CREATE TABLE t1(b INT, c INT);
+CREATE TABLE t2(a INT, b INT);
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
+EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Zero limit
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
+Note 1003 select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t2`.`b` from `test`.`t1` where (<cache>(`test`.`t2`.`a`) = `test`.`t2`.`b`)))
+SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
+sum(a) a b
+SET @@sql_select_limit= @save_sql_select_limit;
+EXPLAIN EXTENDED SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.b' of SELECT #2 was resolved in SELECT #1
+Note 1003 select sum(`test`.`t2`.`a`) AS `sum(a)`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` having <expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t2`.`b` from `test`.`t1` where (<cache>(`test`.`t2`.`a`) = `test`.`t2`.`b`))))
+SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
+sum(a) a b
+6 1 1
+DROP TABLE t1,t2;
+#
+# MDEV-17606: Query returns wrong results (while using CHARACTER SET utf8)
+#
+CREATE TABLE t1(l1 varchar(10), i2 int);
+INSERT INTO t1 VALUES ('e',2),('o',6),('x',4);
+CREATE TABLE t2 (v1 varchar(10) CHARACTER SET utf8, KEY v1 (v1(3)));
+INSERT INTO t2 VALUES ('k'),('rid'),('f'),('x');
+EXPLAIN EXTENDED SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`l1` AS `l1`,`test`.`t1`.`i2` AS `i2` from `test`.`t1` where <nop>(<in_optimizer>(`test`.`t1`.`l1`,(<max>(select max(`test`.`t2`.`v1`) from `test`.`t2`) > convert(<cache>(`test`.`t1`.`l1`) using utf8))))
+SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+l1 i2
+e 2
+o 6
+DROP TABLE t1, t2;
+#
+# MDEV-19232: Floating point precision / value comparison problem
+#
+CREATE TABLE t1 (region varchar(60), area decimal(10,0), population decimal(11,0));
+INSERT INTO t1 VALUES ('Central America and the Caribbean',91,11797);
+INSERT INTO t1 VALUES ('Central America and the Caribbean',442,66422);
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='subquery_cache=on';
+SELECT
+population, area, population/area,
+cast(population/area as DECIMAL(20,9)) FROM t1 LIMIT 1;
+population area population/area cast(population/area as DECIMAL(20,9))
+11797 91 129.6374 129.637400000
+SELECT * FROM t1 A
+WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = B.region);
+region area population
+Central America and the Caribbean 442 66422
+SET optimizer_switch='subquery_cache=off';
+SELECT * FROM t1 A
+WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = B.region);
+region area population
+Central America and the Caribbean 442 66422
+SET @@optimizer_switch= @save_optimizer_switch;
+DROP TABLE t1;
+#
+# MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 VALUES (2),(3);
+EXPLAIN
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+a
+1
+2
+EXPLAIN
+SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY A ALL NULL NULL NULL NULL 2
+3 UNION B ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+a
+1
+2
+EXPLAIN
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
+a
+1
+2
+DROP TABLE t1,t2;
+# end of 10.1 tests
diff --git a/mysql-test/r/subselect_exists2in.result b/mysql-test/r/subselect_exists2in.result
index 18cd0567989..23b252c92d6 100644
--- a/mysql-test/r/subselect_exists2in.result
+++ b/mysql-test/r/subselect_exists2in.result
@@ -972,4 +972,131 @@ id
DROP PROCEDURE p1;
DROP TABLE t1;
# End of 10.0 tests
+#
+# MDEV-23221: A subquery causes crash
+#
+create table t1 (
+location_code varchar(10),
+country_id varchar(10)
+);
+insert into t1 values ('HKG', 'HK');
+insert into t1 values ('NYC', 'US');
+insert into t1 values ('LAX', 'US');
+create table t2 (
+container_id varchar(10),
+cntr_activity_type varchar(10),
+cntr_dest varchar(10)
+);
+insert into t2 values ('AAAA1111', 'VSL', 'NYC');
+insert into t2 values ('AAAA1111', 'CUV', 'NYC');
+insert into t2 values ('BBBB2222', 'VSL', 'LAX');
+insert into t2 values ('BBBB2222', 'XYZ', 'LAX');
+# Must not crash or return an error:
+select
+(select country_id from t1 where location_code = cl1.cntr_dest) as dest_cntry,
+(select
+max(container_id)
+from t2 as cl2
+where
+cl2.container_id = cl1.container_id and
+cl2.cntr_activity_type = 'CUV' and
+exists (select location_code
+from t1
+where
+location_code = cl2.cntr_dest and
+country_id = dest_cntry)
+) as CUV
+from
+t2 cl1;
+dest_cntry CUV
+US AAAA1111
+US AAAA1111
+US NULL
+US NULL
+prepare s from "select
+(select country_id from t1 where location_code = cl1.cntr_dest) as dest_cntry,
+(select
+max(container_id)
+from t2 as cl2
+where
+cl2.container_id = cl1.container_id and
+cl2.cntr_activity_type = 'CUV' and
+exists (select location_code
+from t1
+where
+location_code = cl2.cntr_dest and
+country_id = dest_cntry)
+) as CUV
+from
+t2 cl1";
+execute s;
+dest_cntry CUV
+US AAAA1111
+US AAAA1111
+US NULL
+US NULL
+execute s;
+dest_cntry CUV
+US AAAA1111
+US AAAA1111
+US NULL
+US NULL
+drop table t1,t2;
+#
+# MDEV-20557: SQL query with duplicate table aliases consistently crashes server
+# (Just a testcase)
+#
+create table t1 (id int, id2 int);
+create table t2 (id int, id2 int, a int);
+create table t3 (id int);
+create table t4 (id int);
+select (select 1 from t1 where (exists
+(select 1 from t2
+where t2.a = (select t4.id from t4 where t4.id = t3.id) and t2.id2 = t1.id2))) dt
+from t3;
+ERROR 42000: This version of MariaDB doesn't yet support 'SUBQUERY in ROW in left expression of IN/ALL/ANY'
+drop table t1,t2,t3,t4;
+#
+# MDEV-21649: Crash when using nested EXISTS
+# (Just a testcase)
+#
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id));
+CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT, ip_id INT, PRIMARY KEY(id));
+CREATE TABLE t3 (id INT NOT NULL AUTO_INCREMENT, storage_method_id INT, storage_target_id INT, PRIMARY KEY(id));
+SELECT
+W0.`id`
+FROM
+`t1` W0
+WHERE (
+EXISTS(
+SELECT
+V0.`id`
+ FROM
+`t2` V0
+WHERE (
+EXISTS(
+SELECT
+U0.`id`
+ FROM
+`t2` U0
+INNER JOIN `t3` U4 ON (U0.`id` = U4.`storage_target_id`)
+WHERE (
+U0.`ip_id` = V0.`ip_id`
+ AND U4.`storage_method_id` = (
+SELECT
+U5.`storage_method_id`
+ FROM
+`t3` U5
+WHERE
+U5.`storage_target_id` = V0.`id`
+ LIMIT
+1
+)
+)
+)
+)
+)
+);
+id
+drop table t1,t2,t3;
set optimizer_switch=default;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index 240a6ab47e4..bfdf5525cad 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -615,3 +615,17 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t2`.`f2` AS `f2`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` join `test`.`t2` semi join (`test`.`t4`) join `test`.`t3` where ((`test`.`t4`.`f4` = 1) and (`test`.`t1`.`f1` >= `test`.`t2`.`f2`))
DROP TABLE t1,t2,t3,t4;
+#
+# MDEV-23535: SIGSEGV, SIGABRT and SIGILL in typeinfo for Item_func_set_collation (on optimized builds)
+#
+set @save_character_set_connection=@@character_set_connection;
+set character_set_connection='utf8';
+CREATE TABLE t1(a DATETIME, b VARCHAR(50)) ENGINE=INNODB;
+INSERT INTO t1 VALUES ('2019-03-10 02:55:05', '2019-03-10 02:55:05');
+CREATE TABLE t2(a VARCHAR(50)) ENGINE=INNODB;
+INSERT INTO t2 VALUES ('2019-03-10 02:55:05');
+SELECT * FROM t1 WHERE (SELECT 1,CONCAT(a) FROM t1) = (SELECT 1,CONCAT(a) FROM t2);
+a b
+2019-03-10 02:55:05 2019-03-10 02:55:05
+DROP TABLE t1,t2;
+set character_set_connection=@save_character_set_connection;
diff --git a/mysql-test/r/temp_table_symlink.result b/mysql-test/r/temp_table_symlink.result
new file mode 100644
index 00000000000..1c5c68170ff
--- /dev/null
+++ b/mysql-test/r/temp_table_symlink.result
@@ -0,0 +1,13 @@
+create table d1 (a int);
+create temporary table t1 (a int);
+create temporary table t2 (a int);
+Got one of the listed errors
+create temporary table t3 (a int) engine=Aria;
+Got one of the listed errors
+select * from information_schema.columns where table_schema='test';
+Got one of the listed errors
+flush tables;
+select * from d1;
+a
+drop temporary table t1;
+drop table d1;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index 1a5a1d1c756..c945591fa07 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -429,6 +429,7 @@ select @a;
#
# BUG LP:1008487 virtual bool Item_cache::is_expensive(): Assertion `example' failed
#
+SET TIMESTAMP=UNIX_TIMESTAMP('2012-01-01 00:00:01');
create table t1(a date,key(a));
insert into t1 values ('2012-01-01'),('2012-02-02');
explain
@@ -440,6 +441,7 @@ id select_type table type possible_keys key key_len ref rows Extra
select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1;
1
drop table t1;
+SET TIMESTAMP=DEFAULT;
#
# 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
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 3468ff67b53..26e852f116c 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -57,6 +57,7 @@ select * from t1;
t
0000-00-00 00:00:00
drop table t1;
+SET TIMESTAMP=UNIX_TIMESTAMP('2020-08-11 00:00:01');
CREATE TABLE t1 (a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b date, c time, d datetime);
insert into t1 (b,c,d) values(now(),curtime(),now());
Warnings:
@@ -65,6 +66,7 @@ select date_format(a,"%Y-%m-%d")=b,right(a+0,6)=c+0,a=d+0 from t1;
date_format(a,"%Y-%m-%d")=b right(a+0,6)=c+0 a=d+0
1 1 1
drop table t1;
+SET TIMESTAMP=DEFAULT;
CREATE TABLE t1 (a datetime not null);
insert into t1 values (0);
select * from t1 where a is null;
@@ -298,8 +300,10 @@ f2 f3
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
f2
2001-04-15 00:00:00
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:01');
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
1
+SET timestamp=DEFAULT;
drop table t1;
create table t1 (f1 date);
insert into t1 values('01-01-01'),('01-01-02'),('01-01-03');
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index f1d429a8058..57e26a072de 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -672,5 +672,26 @@ Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 2010e0)
DROP TABLE t1;
#
+# MDEV-23282 FLOAT(53,0) badly handles out-of-range values
+#
+CREATE OR REPLACE TABLE t1 (c1 FLOAT NOT NULL, c2 FLOAT NOT NULL);
+INSERT IGNORE INTO t1 VALUES (1e+40, -1e+40);
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+SELECT c1, c2 FROM t1;
+c1 c2
+3.40282e38 -3.40282e38
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 (c1 FLOAT(53,0) NOT NULL, c2 FLOAT(53,0) NOT NULL);
+INSERT IGNORE INTO t1 VALUES (1e+40, -1e+40);
+Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
+SELECT c1, c2 FROM t1;
+c1 c2
+340282346638528860000000000000000000000 -340282346638528860000000000000000000000
+DROP TABLE t1;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index dc6ef3c59e2..0c8f4f55442 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1530,11 +1530,8 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000)
0.812988073953673124592306939480
create table t1 as select 5.05 / 0.014;
-Warnings:
-Note 1265 Data truncated for column '5.05 / 0.014' at row 1
show warnings;
Level Code Message
-Note 1265 Data truncated for column '5.05 / 0.014' at row 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -1649,8 +1646,6 @@ my_col
0.123456789123456789123456789123
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
-Warnings:
-Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,4) YES NULL
@@ -2347,6 +2342,50 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
+# MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
+#
+SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
+val
+20.01
+SET sql_mode='';
+CREATE TABLE t1 (a TEXT);
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999'));
+CREATE TABLE t2 (a TEXT, d DECIMAL(15,2));
+INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1;
+Warnings:
+Note 1265 Data truncated for column 'd' at row 5
+Note 1265 Data truncated for column 'd' at row 6
+Note 1265 Data truncated for column 'd' at row 7
+INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1;
+Warnings:
+Note 1265 Data truncated for column 'd' at row 5
+Note 1265 Data truncated for column 'd' at row 6
+Note 1265 Data truncated for column 'd' at row 7
+SELECT d, a FROM t2 ORDER BY d,a;
+d a
+-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995
+-2.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999
+-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99
+-1.99 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994
+-1.90 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9
+-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+-1.00 -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0
+1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+1.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.0
+1.90 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.9
+1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.99
+1.99 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.994
+2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.995
+2.00 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001.999
+DROP TABLE t1, t2;
+SET sql_mode=DEFAULT;
+#
# End of 10.1 tests
#
#
diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result
index 101bf0cfb2c..a10d2a56eae 100644
--- a/mysql-test/r/type_ranges.result
+++ b/mysql-test/r/type_ranges.result
@@ -94,8 +94,6 @@ DROP INDEX test ON t1;
insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3);
-Warnings:
-Warning 1265 Data truncated for column 'string' at row 1
insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
Warnings:
Warning 1264 Out of range value for column 'utiny' at row 1
@@ -136,7 +134,7 @@ select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,ut
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
-12 0.33333333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
+12 0.3333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 0 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 0 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
@@ -188,7 +186,7 @@ Warning 1265 Data truncated for column 'new_field' at row 7
select * from t2;
auto string mediumblob_col new_field
1 2 2 ne
-2 0.33333333 ne
+2 0.3333 ne
3 -1 -1 ne
4 -429496729 -4294967295 ne
5 4294967295 4294967295 ne
diff --git a/mysql-test/r/type_set.result b/mysql-test/r/type_set.result
index 586c6345e00..289073a2ed0 100644
--- a/mysql-test/r/type_set.result
+++ b/mysql-test/r/type_set.result
@@ -108,7 +108,7 @@ End of 5.0 tests
# Start of 10.0 tests
#
#
-# MDEV-6950 Bad results with joins compating DATE and INT/ENUM/VARCHAR columns
+# MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns
#
CREATE TABLE t1 (c1 DATE PRIMARY KEY);
INSERT INTO t1 VALUES ('2001-01-01');
diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result
index bcfc9941db9..c74b89a1b96 100644
--- a/mysql-test/r/udf.result
+++ b/mysql-test/r/udf.result
@@ -30,9 +30,9 @@ lookup("127.0.0.1")
127.0.0.1
select lookup(127,0,0,1);
ERROR HY000: Can't initialize function 'lookup'; Wrong arguments to lookup; Use the source
-select lookup("localhost");
-lookup("localhost")
-127.0.0.1
+select lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$';
+lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$'
+1
select reverse_lookup();
ERROR HY000: Can't initialize function 'reverse_lookup'; Wrong number of arguments to reverse_lookup; Use the source
select reverse_lookup("127.0.0.1");
diff --git a/mysql-test/r/uniques_crash-7912.result b/mysql-test/r/uniques_crash-7912.result
deleted file mode 100644
index bf3aab684ae..00000000000
--- a/mysql-test/r/uniques_crash-7912.result
+++ /dev/null
@@ -1,11 +0,0 @@
-call mtr.add_suppression("Out of memory");
-set sql_mode="";
-drop table if exists t1,t2;
-create table `t1` (`a` datetime not null) engine=InnoDB;
-create table `t2` (`a` int not null) engine=innodb;
-replace into t1 values (),();
-insert into t2 values(0);
-set session sort_buffer_size = 1024*1024*1024*1024;
-delete d2 from t2 as d1, t1 as d2 where d1.a <=> d2.a;
-drop table t2;
-drop table t1;
diff --git a/mysql-test/std_data/checkDBI_DBD-mysql.pl b/mysql-test/std_data/checkDBI_DBD-mysql.pl
index 328a7ad774f..0c26325b715 100755
--- a/mysql-test/std_data/checkDBI_DBD-mysql.pl
+++ b/mysql-test/std_data/checkDBI_DBD-mysql.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2011, Oracle and/or its affiliates
#
diff --git a/mysql-test/suite.pm b/mysql-test/suite.pm
index f90679e6f1f..3db419bae84 100644
--- a/mysql-test/suite.pm
+++ b/mysql-test/suite.pm
@@ -62,9 +62,10 @@ sub skip_combinations {
sub ipv6_ok() {
use Socket;
return 0 unless socket my $sock, PF_INET6, SOCK_STREAM, getprotobyname('tcp');
+ $!="";
# eval{}, if there's no Socket::sockaddr_in6 at all, old Perl installation
- eval { connect $sock, sockaddr_in6(7, Socket::IN6ADDR_LOOPBACK) };
- return $@ eq "";
+ eval { bind $sock, sockaddr_in6($::baseport, Socket::IN6ADDR_LOOPBACK) };
+ return $@ eq "" && $! eq ""
}
$skip{'include/check_ipv6.inc'} = 'No IPv6' unless ipv6_ok();
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
index 9a3f4751165..0b05c4f449f 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
@@ -339,7 +339,11 @@ a
123.47
999.99
DROP TABLE t1dec102;
-flush logs;
+CREATE TABLE t1 (a GEOMETRY DEFAULT NULL);
+INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 VALUES (POINT(10,10));
+DROP TABLE t1;
+FLUSH LOGS;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
@@ -4623,6 +4627,56 @@ SET TIMESTAMP=1000000000/*!*/;
DROP TABLE `t1dec102` /* generated by server */
/*!*/;
# at #
+#010909 4:46:40 server id 1 end_log_pos # GTID 0-1-321 ddl
+/*!100001 SET @@session.gtid_seq_no=321*//*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+CREATE TABLE t1 (a GEOMETRY DEFAULT NULL)
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # GTID 0-1-322
+/*!100001 SET @@session.gtid_seq_no=322*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1=NULL /* GEOMETRY meta=4 nullable=1 is_null=1 */
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # GTID 0-1-323
+/*!100001 SET @@session.gtid_seq_no=323*//*!*/;
+BEGIN
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1='\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00$@\x00\x00\x00\x00\x00\x00$@' /* GEOMETRY meta=4 nullable=1 is_null=0 */
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # GTID 0-1-324 ddl
+/*!100001 SET @@session.gtid_seq_no=324*//*!*/;
+# at #
+#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+DROP TABLE `t1` /* generated by server */
+/*!*/;
+# at #
#010909 4:46:40 server id 1 end_log_pos # Rotate to master-bin.000002 pos: 4
DELIMITER ;
# End of log file
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result
index 041be5ed09f..3ae5519fe00 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_frag.result
@@ -20,5 +20,8 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
SET @binlog_fragment_0='012345';
BINLOG @binlog_fragment_0, @binlog_fragment_not_exist;
ERROR 42000: Incorrect argument type to variable 'binlog_fragment_not_exist'
+SET @a= '42';
+BINLOG @a, @a;
+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
# Cleanup
DROP TABLE t;
diff --git a/mysql-test/suite/binlog/r/binlog_no_uniqfile_crash.result b/mysql-test/suite/binlog/r/binlog_no_uniqfile_crash.result
new file mode 100644
index 00000000000..e943d606274
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_no_uniqfile_crash.result
@@ -0,0 +1,44 @@
+call mtr.add_suppression("Next log extension: 2147483647. Remaining log filename extensions: 0");
+call mtr.add_suppression("Log filename extension number exhausted:.");
+call mtr.add_suppression("Can't generate a unique log-filename");
+call mtr.add_suppression("MYSQL_BIN_LOG::open failed to generate new file name.");
+call mtr.add_suppression("Could not use master-bin for logging");
+"Test case verifies creation of binary log with max entension value."
+RESET MASTER TO 2147483647;
+show binary logs;
+Log_name File_size
+master-bin.2147483647 #
+FOUND /Next log extension: 2147483647. Remaining log filename extensions: 0./ in mysqld.1.err
+CREATE DATABASE db1;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.2147483647 # Gtid # # GTID #-#-#
+master-bin.2147483647 # Query # # CREATE DATABASE db1
+RESET MASTER TO 2147483648;
+ERROR HY000: Can't generate a unique log-filename master-bin.(1-999)
+
+FOUND /Turning logging off for the whole duration of the MySQL server process/ in mysqld.1.err
+"Following CREATE DATABSE db2 command will not be present in binary log"
+"as binary log got closed due to ER_NO_UNIQUE_LOGFILE error."
+CREATE DATABASE db2;
+"RESET MASTER command fails to generate a new binary log"
+"log-bin will be disabled and server needs to be restarted to"
+"re-enable the binary log."
+SHOW BINARY LOGS;
+ERROR HY000: You are not using binary logging
+show binary logs;
+Log_name File_size
+master-bin.000001 #
+SHOW DATABASES LIKE 'db%';
+Database (db%)
+db1
+db2
+include/show_binlog_events.inc
+DROP DATABASE db1;
+DROP DATABASE db2;
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # DROP DATABASE db1
+master-bin.000001 # Gtid # # GTID #-#-#
+master-bin.000001 # Query # # DROP DATABASE db2
diff --git a/mysql-test/suite/binlog/r/binlog_recover_checksum_error.result b/mysql-test/suite/binlog/r/binlog_recover_checksum_error.result
new file mode 100644
index 00000000000..f65f7797d7f
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_recover_checksum_error.result
@@ -0,0 +1,7 @@
+set @@global.binlog_checksum = CRC32;
+call mtr.add_suppression("Replication event checksum verification failed");
+call mtr.add_suppression("Error in Log_event::read_log_event");
+set @@global.debug_dbug = VALUE;
+set @@global.master_verify_checksum = DO_CHECKSUM;
+set @@global.binlog_checksum = BINLOG_CHECKSUM;
+# EOF the test
diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result
index 6070f2da608..4e72ed8b032 100644
--- a/mysql-test/suite/binlog/r/binlog_row_annotate.result
+++ b/mysql-test/suite/binlog/r/binlog_row_annotate.result
@@ -449,7 +449,6 @@ BEGIN
### DELETE FROM `test1`.`t1`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
-'/*!*/;
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
@@ -1117,7 +1116,6 @@ BEGIN
### DELETE FROM `test1`.`t1`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
-'/*!*/;
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
diff --git a/mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result b/mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result
index 358422c5842..c2e634ebe82 100644
--- a/mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result
+++ b/mysql-test/suite/binlog/r/binlog_show_binlog_event_random_pos.result
@@ -9,4 +9,7 @@ INSERT INTO t1 VALUES (repeat('a', 255), repeat('a', 255),repeat('a', 255),repea
INSERT INTO t1 VALUES (repeat('a', 255), repeat('a', 255),repeat('a', 255),repeat('a', 255),repeat('a', 255));
UPDATE t1 SET c1=repeat('b',255);
INSERT INTO t1 VALUES (repeat('a', 255), repeat('a', 255),repeat('a', 255),repeat('a', 255),repeat('a', 255));
+SHOW BINLOG EVENTS FROM POS;
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Invalid pos specified. Requested from pos:POS is greater than actual file size:MAX_POS
+
DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
index 0c94d968338..93c26cc57a2 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test
@@ -450,7 +450,19 @@ INSERT INTO t1dec102 VALUES (999.99);
SELECT * FROM t1dec102 ORDER BY a;
DROP TABLE t1dec102;
-flush logs;
+
+#
+# MDEV-22330: mysqlbinlog stops with an error Don't know how to handle column
+# type: 255 meta: 4 (0004)
+# Check support for GEOMETRY type with verbose mode.
+#
+CREATE TABLE t1 (a GEOMETRY DEFAULT NULL);
+
+INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 VALUES (POINT(10,10));
+DROP TABLE t1;
+
+FLUSH LOGS;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /(@[0-9]*=[0-9]*[.][0-9]{1,3})[0-9e+-]*[^ ]*(.*(FLOAT|DOUBLE).*[*].)/\1...\2/
diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test
index f0317ef1219..9f79deea3db 100644
--- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test
+++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row_frag.test
@@ -11,7 +11,7 @@ SELECT a from t into @a;
FLUSH LOGS;
DELETE FROM t;
---exec $MYSQL_BINLOG --debug-binlog-row-event-max-encoded-size=256 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
+--exec $MYSQL_BINLOG --verbose --debug-binlog-row-event-max-encoded-size=256 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
--let SEARCH_PATTERN= BINLOG @binlog_fragment_0, @binlog_fragment_1
--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
@@ -40,6 +40,11 @@ SET @binlog_fragment_0='012345';
--error ER_WRONG_TYPE_FOR_VAR
BINLOG @binlog_fragment_0, @binlog_fragment_not_exist;
+# MDEV-22520
+SET @a= '42';
+--error ER_SYNTAX_ERROR
+BINLOG @a, @a;
+
--echo # Cleanup
--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
DROP TABLE t;
diff --git a/mysql-test/suite/binlog/t/binlog_no_uniqfile_crash.test b/mysql-test/suite/binlog/t/binlog_no_uniqfile_crash.test
new file mode 100644
index 00000000000..1485ab87ca9
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_no_uniqfile_crash.test
@@ -0,0 +1,85 @@
+# ==== Purpose ====
+#
+# Test verifies that when RESET MASTER TO # command is supplied with binlog
+# extension number greater than 2147483647 the command should report
+# appropriate error and binary log should be disabled. It should not result in
+# a crash.
+#
+# ==== Implementation ====
+#
+# Steps:
+# 0 - Verify case with max binary log extension. Max value is '2147483647'
+# 1 - Confirm that SHOW BINARY LOGS displays a binary log with '2147483647'
+# 2 - Verify that events are successfully written into max extension file.
+# 3 - Try to create a binary log with extension greater than max allowed
+# value '2147483648', verify ER_NO_UNIQUE_LOGFILE error is reported.
+# 4 - Execute CREATE DATABASE db2 statement and verify server dosn't crash.
+# 5 - Execute SHOW BINARY LOG command and verify that it reports
+# ER_NO_BINARY_LOGGING error.
+# 6 - Restart the server and verify that databse 'db2' exists and it it not
+# present in the binary log.
+#
+# ==== References ====
+#
+# MDEV-22451: SIGSEGV in __memmove_avx_unaligned_erms/memcpy from
+# _my_b_write on CREATE after RESET MASTER
+#
+--source include/have_log_bin.inc
+
+call mtr.add_suppression("Next log extension: 2147483647. Remaining log filename extensions: 0");
+call mtr.add_suppression("Log filename extension number exhausted:.");
+call mtr.add_suppression("Can't generate a unique log-filename");
+call mtr.add_suppression("MYSQL_BIN_LOG::open failed to generate new file name.");
+call mtr.add_suppression("Could not use master-bin for logging");
+
+
+--echo "Test case verifies creation of binary log with max entension value."
+RESET MASTER TO 2147483647;
+--source include/show_binary_logs.inc
+
+# Check error log for correct messages.
+let $log_error_= `SELECT @@GLOBAL.log_error`;
+if(!$log_error_)
+{
+ # MySQL Server on windows is started with --console and thus
+ # does not know the location of its .err log, use default location
+ let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
+}
+
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=Next log extension: 2147483647. Remaining log filename extensions: 0.
+--source include/search_pattern_in_file.inc
+
+CREATE DATABASE db1;
+--source include/show_binlog_events.inc
+
+--error ER_NO_UNIQUE_LOGFILE
+RESET MASTER TO 2147483648;
+
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=Turning logging off for the whole duration of the MySQL server process
+--source include/search_pattern_in_file.inc
+
+--echo "Following CREATE DATABSE db2 command will not be present in binary log"
+--echo "as binary log got closed due to ER_NO_UNIQUE_LOGFILE error."
+CREATE DATABASE db2;
+
+
+--echo "RESET MASTER command fails to generate a new binary log"
+--echo "log-bin will be disabled and server needs to be restarted to"
+--echo "re-enable the binary log."
+--error ER_NO_BINARY_LOGGING
+SHOW BINARY LOGS;
+
+--source include/restart_mysqld.inc
+
+--source include/show_binary_logs.inc
+SHOW DATABASES LIKE 'db%';
+--source include/show_binlog_events.inc
+
+# Cleanup
+DROP DATABASE db1;
+DROP DATABASE db2;
+--source include/show_binlog_events.inc
diff --git a/mysql-test/suite/binlog/t/binlog_recover_checksum_error.test b/mysql-test/suite/binlog/t/binlog_recover_checksum_error.test
new file mode 100644
index 00000000000..12c9f3d914f
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_recover_checksum_error.test
@@ -0,0 +1,37 @@
+# The test verifies server binlog-based recovery.
+#
+# MDEV-23832 checksum error at server binlog recovery should not crash
+
+# The test logic really requires --log-bin.
+--source include/have_binlog_format_mixed.inc
+--source include/have_debug.inc
+
+--let $do_checksum = `SELECT @@global.master_verify_checksum`
+--let $debug_dbug_saved = `SELECT @@global.debug_dbug`
+--let $binlog_checksum = `SELECT @@global.binlog_checksum`
+set @@global.binlog_checksum = CRC32;
+
+call mtr.add_suppression("Replication event checksum verification failed");
+call mtr.add_suppression("Error in Log_event::read_log_event");
+
+# Proof of no crash follows.
+# There's no need for actual bin-loggable queries to the server
+--let $restart_parameters= --master_verify_checksum=ON --debug_dbug="+d,corrupt_read_log_event_char"
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+--let $restart_parameters=
+--let $shutdown_timeout=
+
+#
+# Cleanup
+
+--replace_regex /= .*/= VALUE/
+--eval set @@global.debug_dbug = "$debug_dbug_saved"
+
+--replace_result $do_checksum DO_CHECKSUM
+--eval set @@global.master_verify_checksum = $do_checksum
+--replace_result $binlog_checksum BINLOG_CHECKSUM
+--eval set @@global.binlog_checksum = $binlog_checksum
+#
+--echo # EOF the test
+#
diff --git a/mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test b/mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test
index e6a9e1cb2c1..05e6967c538 100644
--- a/mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test
+++ b/mysql-test/suite/binlog/t/binlog_show_binlog_event_random_pos.test
@@ -34,4 +34,9 @@ while ($pos <= $max_pos)
--enable_query_log
}
+# Testing a case where input position is greater than actual binlog file size.
+--replace_result $pos POS $max_pos MAX_POS
+--error 1220
+eval SHOW BINLOG EVENTS FROM $pos;
+
DROP TABLE t1;
diff --git a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result
index 41721441a72..6485b723975 100644
--- a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result
+++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result
@@ -449,7 +449,6 @@ BEGIN
### DELETE FROM `test1`.`t1`
### WHERE
### @1=3 /* INT meta=0 nullable=1 is_null=0 */
-'/*!*/;
# at #
#010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
diff --git a/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result
index 72844fb9de6..fead3d128e5 100644
--- a/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result
+++ b/mysql-test/suite/binlog_encryption/rpl_binlog_errors.result
@@ -7,6 +7,7 @@ include/stop_slave.inc
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
call mtr.add_suppression("Error writing file .*");
+call mtr.add_suppression("Could not use master-bin for logging");
SET @old_debug= @@global.debug;
SELECT repeat('x',8192) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data';
SELECT repeat('x',10) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data';
diff --git a/mysql-test/suite/engines/iuds/r/insert_decimal.result b/mysql-test/suite/engines/iuds/r/insert_decimal.result
index eab8592c4ee..37f14e94b1a 100644
--- a/mysql-test/suite/engines/iuds/r/insert_decimal.result
+++ b/mysql-test/suite/engines/iuds/r/insert_decimal.result
@@ -1892,9 +1892,13 @@ Warnings:
Warning 1264 Out of range value for column 'c1' at row 3
INSERT INTO t5 VALUES('1e+52','-1e+52','1e+52',5),('1e-52','-1e-52','1e-52',6);
Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
Warning 1264 Out of range value for column 'c3' at row 1
INSERT INTO t5 VALUES('1e+53','-1e+53','1e+53',7),('1e-53','-1e-53','1e-53',8);
Warnings:
+Warning 1264 Out of range value for column 'c1' at row 1
+Warning 1264 Out of range value for column 'c2' at row 1
Warning 1264 Out of range value for column 'c3' at row 1
SELECT * FROM t5;
c1 c2 c3 c4
diff --git a/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl b/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl
index f277bce018e..e997f479466 100755
--- a/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl
+++ b/mysql-test/suite/engines/rr_trx/run_stress_tx_rr.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
################################################################################
#
# This script runs the transactional stress test "stress_tx_rr" against the
diff --git a/mysql-test/suite/funcs_1/lib/DataGen_local.pl b/mysql-test/suite/funcs_1/lib/DataGen_local.pl
index 738a73e0fd5..8ca74407141 100755
--- a/mysql-test/suite/funcs_1/lib/DataGen_local.pl
+++ b/mysql-test/suite/funcs_1/lib/DataGen_local.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
if ( (scalar(@ARGV) != 1 ) || ($ARGV[0] =~ /[^0-9]/i ) )
diff --git a/mysql-test/suite/funcs_1/lib/DataGen_modify.pl b/mysql-test/suite/funcs_1/lib/DataGen_modify.pl
index 4675049ff0d..8ad8e619a20 100755
--- a/mysql-test/suite/funcs_1/lib/DataGen_modify.pl
+++ b/mysql-test/suite/funcs_1/lib/DataGen_modify.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
if ( (scalar(@ARGV) != 2 ) || ($ARGV[0] =~ /[^0-9]/i ) )
diff --git a/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl b/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl
index 3b85ed02f5b..c0973a10950 100755
--- a/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl
+++ b/mysql-test/suite/funcs_2/lib/gen_charset_utf8.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
#################################################################################
# Author: Serge Kozlov #
diff --git a/mysql-test/suite/galera/r/MDEV-20225.result b/mysql-test/suite/galera/r/MDEV-20225.result
new file mode 100644
index 00000000000..582353f10a6
--- /dev/null
+++ b/mysql-test/suite/galera/r/MDEV-20225.result
@@ -0,0 +1,16 @@
+CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+CREATE TABLE t2 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT, f2 INT) ENGINE=InnoDB;
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, NEW.f1);
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_slave_threads = 2;
+SET GLOBAL debug_dbug = 'd,sync.mdev_20225';
+DROP TRIGGER tr1;
+INSERT INTO t1 VALUES (NULL);
+SET GLOBAL debug_dbug = 'RESET';
+SET DEBUG_SYNC = 'now SIGNAL signal.mdev_20225_continue';
+SET DEBUG_SYNC = 'RESET';
+SET GLOBAL wsrep_slave_threads = 1;
+SHOW TRIGGERS;
+Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
+DROP TABLE t1;
+DROP TABLE t2;
diff --git a/mysql-test/suite/galera/r/galera_sp_bf_abort.result b/mysql-test/suite/galera/r/galera_sp_bf_abort.result
new file mode 100644
index 00000000000..205d73dd763
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_sp_bf_abort.result
@@ -0,0 +1,294 @@
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
+SET SESSION wsrep_sync_wait = 0;
+CREATE PROCEDURE proc_update_insert()
+BEGIN
+UPDATE t1 SET f2 = 'b';
+INSERT INTO t1 VALUES (4, 'd');
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_update_insert;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 b
+2 c
+3 b
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_update_insert_with_exit_handler()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
+UPDATE t1 SET f2 = 'b';
+INSERT INTO t1 VALUES (4, 'd');
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_update_insert_with_exit_handler;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 b
+2 c
+3 b
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_update_insert_with_continue_handler()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
+UPDATE t1 SET f2 = 'b';
+INSERT INTO t1 VALUES (4, 'd');
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_update_insert_with_continue_handler;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 b
+2 c
+3 b
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_update_insert_transaction()
+BEGIN
+START TRANSACTION;
+UPDATE t1 SET f2 = 'b';
+INSERT INTO t1 VALUES (4, 'd');
+COMMIT;
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_update_insert_transaction;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+Warnings:
+Error 1317 Query execution was interrupted
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 b
+2 c
+3 b
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_update_insert_transaction_with_continue_handler()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
+START TRANSACTION;
+UPDATE t1 SET f2 = 'b';
+INSERT INTO t1 VALUES (4, 'd');
+COMMIT;
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_update_insert_transaction_with_continue_handler;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+Warnings:
+Error 1317 Query execution was interrupted
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 b
+2 c
+3 b
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_update_insert_transaction_with_exit_handler()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
+START TRANSACTION;
+UPDATE t1 SET f2 = 'b';
+INSERT INTO t1 VALUES (4, 'd');
+COMMIT;
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_update_insert_transaction_with_exit_handler;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+Warnings:
+Error 1317 Query execution was interrupted
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 b
+2 c
+3 b
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_insert_insert_conflict()
+BEGIN
+INSERT INTO t1 VALUES (2, 'd');
+INSERT INTO t1 VALUES (4, 'd');
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_insert_insert_conflict;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+Got one of the listed errors
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 a
+2 c
+3 a
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_insert_insert_conflict_with_exit_handler()
+BEGIN
+DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT "Conflict exit handler";
+INSERT INTO t1 VALUES (2, 'd');
+INSERT INTO t1 VALUES (4, 'd');
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_insert_insert_conflict_with_exit_handler;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+Conflict exit handler
+Conflict exit handler
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 a
+2 c
+3 a
+wsrep_local_replays
+1
+DELETE FROM t1;
+CREATE PROCEDURE proc_insert_insert_conflict_with_continue_handler()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT "Conflict continue handler";
+INSERT INTO t1 VALUES (2, 'd');
+INSERT INTO t1 VALUES (4, 'd');
+END|
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
+INSERT INTO t1 VALUES (2, 'c');
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_replicate_sync';
+CALL proc_insert_insert_conflict_with_continue_handler;
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 1;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
+SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
+Conflict continue handler
+Conflict continue handler
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+f1 f2
+1 a
+2 c
+3 a
+4 d
+wsrep_local_replays
+1
+DELETE FROM t1;
+DROP PROCEDURE proc_update_insert;
+DROP PROCEDURE proc_update_insert_with_continue_handler;
+DROP PROCEDURE proc_update_insert_with_exit_handler;
+DROP PROCEDURE proc_update_insert_transaction;
+DROP PROCEDURE proc_update_insert_transaction_with_continue_handler;
+DROP PROCEDURE proc_update_insert_transaction_with_exit_handler;
+DROP PROCEDURE proc_insert_insert_conflict;
+DROP PROCEDURE proc_insert_insert_conflict_with_exit_handler;
+DROP PROCEDURE proc_insert_insert_conflict_with_continue_handler;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/MDEV-20225.test b/mysql-test/suite/galera/t/MDEV-20225.test
new file mode 100644
index 00000000000..38efb0d6647
--- /dev/null
+++ b/mysql-test/suite/galera/t/MDEV-20225.test
@@ -0,0 +1,52 @@
+#
+# MDEV-20225 - Verify that DROP TRIGGER gets keys assigned corresponding
+# to all affected tables.
+#
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source suite/galera/include/galera_have_debug_sync.inc
+
+CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
+CREATE TABLE t2 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT, f2 INT) ENGINE=InnoDB;
+
+CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, NEW.f1);
+
+--connection node_2
+SET SESSION wsrep_sync_wait = 0;
+SET GLOBAL wsrep_slave_threads = 2;
+SET GLOBAL debug_dbug = 'd,sync.mdev_20225';
+
+--let $galera_connection_name = node_1a
+--let $galera_server_number = 1
+--source include/galera_connect.inc
+DROP TRIGGER tr1;
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'debug sync point: now'
+--source include/wait_condition.inc
+
+
+--connection node_1
+INSERT INTO t1 VALUES (NULL);
+# We must rely on sleep here. If the bug is fixed, the second applier
+# is not allowed to go past apply monitor which would trigger the bug,
+# so there is no sync point or condition to wait.
+--sleep 1
+
+--connection node_2
+SET GLOBAL debug_dbug = 'RESET';
+SET DEBUG_SYNC = 'now SIGNAL signal.mdev_20225_continue';
+SET DEBUG_SYNC = 'RESET';
+SET GLOBAL wsrep_slave_threads = 1;
+
+--let $wait_condition = SELECT COUNT(*) = 1 FROM test.t1;
+--source include/wait_condition.inc
+
+# Trigger should now be dropped on node_2.
+SHOW TRIGGERS;
+
+DROP TABLE t1;
+DROP TABLE t2;
diff --git a/mysql-test/suite/galera/t/MW-388.test b/mysql-test/suite/galera/t/MW-388.test
index fafdde092bf..2d3fe5b5d93 100644
--- a/mysql-test/suite/galera/t/MW-388.test
+++ b/mysql-test/suite/galera/t/MW-388.test
@@ -1,5 +1,7 @@
--source include/galera_cluster.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
--connection node_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB;
diff --git a/mysql-test/suite/galera/t/MW-86-wait1.test b/mysql-test/suite/galera/t/MW-86-wait1.test
index 40a7882829b..c5b78be64e5 100644
--- a/mysql-test/suite/galera/t/MW-86-wait1.test
+++ b/mysql-test/suite/galera/t/MW-86-wait1.test
@@ -5,7 +5,9 @@
#
--source include/galera_cluster.inc
--source include/have_binlog_format_row.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
--connection node_2
# Make sure no signals have been leftover from previous tests to surprise us.
diff --git a/mysql-test/suite/galera/t/MW-86-wait8.test b/mysql-test/suite/galera/t/MW-86-wait8.test
index 551b0f67b7c..a648924b9d8 100644
--- a/mysql-test/suite/galera/t/MW-86-wait8.test
+++ b/mysql-test/suite/galera/t/MW-86-wait8.test
@@ -3,7 +3,9 @@
#
--source include/galera_cluster.inc
--source include/have_binlog_format_row.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
--connection node_2
# Make sure no signals have been leftover from previous tests to surprise us.
diff --git a/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test b/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test
index e13e7f1f748..6d1e21fd94d 100644
--- a/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test
+++ b/mysql-test/suite/galera/t/galera_query_cache_sync_wait.test
@@ -1,6 +1,8 @@
--source include/galera_cluster.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/have_query_cache.inc
+--source include/galera_have_debug_sync.inc
CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
diff --git a/mysql-test/suite/galera/t/galera_sp_bf_abort.inc b/mysql-test/suite/galera/t/galera_sp_bf_abort.inc
new file mode 100644
index 00000000000..7ca8ecf20a9
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_sp_bf_abort.inc
@@ -0,0 +1,36 @@
+#
+# Issue an INSERT for gap between 1 and 3 to node_2 and wait until it hits
+# apply monitor sync point on node_1
+#
+
+--connection node_1a
+--let $galera_sync_point = apply_monitor_slave_enter_sync
+--source include/galera_set_sync_point.inc
+
+--connection node_2
+--eval $galera_sp_bf_abort_conflict
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+# Send a procedure to node_1 which should take a gap lock between
+# rows 1 and 3. It does not conflict with INSERT from node_2 in
+# certification. Park the UPDATE after replicate and let INSERT to
+# continue applying, generating a BF abort.
+
+--let $galera_sync_point = after_replicate_sync
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+--send_eval CALL $galera_sp_bf_abort_proc
+
+--connection node_1a
+--let $galera_sync_point = after_replicate_sync apply_monitor_slave_enter_sync
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+--let $galera_sync_point = apply_monitor_slave_enter_sync
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = after_replicate_sync
+--source include/galera_signal_sync_point.inc
diff --git a/mysql-test/suite/galera/t/galera_sp_bf_abort.test b/mysql-test/suite/galera/t/galera_sp_bf_abort.test
new file mode 100644
index 00000000000..b5f28c23b05
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_sp_bf_abort.test
@@ -0,0 +1,350 @@
+#
+# Test cases for stored procedure BF aborts.
+#
+
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source suite/galera/include/galera_have_debug_sync.inc
+
+--connection node_1
+
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
+
+# Control connection for Galera sync point management
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+--connection node_1a
+SET SESSION wsrep_sync_wait = 0;
+
+--connection node_1
+#
+# Case 1a: Procedure does and UPDATE which will suffer BF abort
+# but there is no actual conflict and non-conflicting INSERT.
+# The expected outcome is that both UPDATE and INSERT will succedd
+# and no errors are reported to the client, wsrep_local_replays is
+# incremented by one.
+#
+DELIMITER |;
+CREATE PROCEDURE proc_update_insert()
+BEGIN
+ UPDATE t1 SET f2 = 'b';
+ INSERT INTO t1 VALUES (4, 'd');
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_update_insert
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+#
+# Case 1b: Procedure does and UPDATE which will suffer BF abort
+# but there is no actual conflict and non-conflicting INSERT.
+# An EXIT HANDLER is declared for the procedure.
+# The expected outcome is that both UPDATE and INSERT will succedd
+# and no errors are reported to the client, wsrep_local_replays is
+# incremented by one.
+#
+DELIMITER |;
+CREATE PROCEDURE proc_update_insert_with_exit_handler()
+BEGIN
+ DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
+ UPDATE t1 SET f2 = 'b';
+ INSERT INTO t1 VALUES (4, 'd');
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_update_insert_with_exit_handler
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+#
+# Case 1c: Procedure does and UPDATE which will suffer BF abort
+# but there is no actual conflict and non-conflicting INSERT.
+# A CONTINUE HANDLER is declared for the procedure.
+# The expected outcome is that both UPDATE and INSERT will succedd
+# and no errors are reported to the client, wsrep_local_replays is
+# incremented by one.
+#
+DELIMITER |;
+CREATE PROCEDURE proc_update_insert_with_continue_handler()
+BEGIN
+
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
+ UPDATE t1 SET f2 = 'b';
+ INSERT INTO t1 VALUES (4, 'd');
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+SET SESSION wsrep_sync_wait = 0;
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_update_insert_with_continue_handler
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+#
+# Case 2a: UPDATE and INSERT are run inside a transaction and the transaction
+# will be BF aborted on COMMIT. The expected outcome is that the transaction
+# succeeds and no errors are reported to the client, wsrep_local_replays
+# is incremented by one.
+#
+
+DELIMITER |;
+CREATE PROCEDURE proc_update_insert_transaction()
+BEGIN
+ START TRANSACTION;
+ UPDATE t1 SET f2 = 'b';
+ INSERT INTO t1 VALUES (4, 'd');
+ COMMIT;
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_update_insert_transaction
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+SET SESSION wsrep_sync_wait = 0;
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+#
+# Case 2b: UPDATE and INSERT are run inside a transaction and the transaction
+# will be BF aborted on COMMIT. A CONTINUE HANDLER is declared for the
+# procedure. The expected outcome is that the transaction
+# succeeds and no errors are reported to the client, wsrep_local_replays
+# is incremented by one.
+#
+
+DELIMITER |;
+CREATE PROCEDURE proc_update_insert_transaction_with_continue_handler()
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
+ START TRANSACTION;
+ UPDATE t1 SET f2 = 'b';
+ INSERT INTO t1 VALUES (4, 'd');
+ COMMIT;
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_update_insert_transaction_with_continue_handler
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+SET SESSION wsrep_sync_wait = 0;
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+#
+# Case 2c: UPDATE and INSERT are run inside a transaction and the transaction
+# will be BF aborted on COMMIT. An EXIT HANDLE is declared for the procedure.
+# The expected outcome is that the transaction succeeds and no errors are
+# reported to the client, wsrep_local_replays is incremented by one.
+#
+
+DELIMITER |;
+CREATE PROCEDURE proc_update_insert_transaction_with_exit_handler()
+BEGIN
+ DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
+ START TRANSACTION;
+ UPDATE t1 SET f2 = 'b';
+ INSERT INTO t1 VALUES (4, 'd');
+ COMMIT;
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_update_insert_transaction_with_exit_handler
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+SET SESSION wsrep_sync_wait = 0;
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+
+#
+# Case 3a: Two INSERTs are run inside stored procedure, this time
+# the first INSERT will have a BF abort and real conflict. The expected outcome
+# is that the INSERT fails and an error is reported to the client.
+# wsrep_local_replays is not incremented.
+#
+# Notice that the resulting error code may be both
+# ER_DUP_ENTRY (procedure will exit with cert failure conflict state and
+# will be) or ER_LOCK_DEADLOCK depending on timing.
+#
+DELIMITER |;
+CREATE PROCEDURE proc_insert_insert_conflict()
+BEGIN
+ INSERT INTO t1 VALUES (2, 'd');
+ INSERT INTO t1 VALUES (4, 'd');
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_insert_insert_conflict
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+SET SESSION wsrep_sync_wait = 0;
+--source galera_sp_bf_abort.inc
+--connection node_1
+--error ER_DUP_ENTRY,ER_LOCK_DEADLOCK, ER_ERROR_DURING_COMMIT
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 0 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+
+#
+# Case 3b: Two INSERTs are run inside stored procedure, this time
+# the first INSERT will have a BF abort and real conflict.
+# An EXIT HANDLER is declared for the procedure. The expected outcome
+# is that the INSERT fails and an error is reported to the client.
+# wsrep_local_replays is not incremented.
+#
+DELIMITER |;
+CREATE PROCEDURE proc_insert_insert_conflict_with_exit_handler()
+BEGIN
+ DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT "Conflict exit handler";
+ INSERT INTO t1 VALUES (2, 'd');
+ INSERT INTO t1 VALUES (4, 'd');
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_insert_insert_conflict_with_exit_handler
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+SET SESSION wsrep_sync_wait = 0;
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 0 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+--connection node_1
+
+#
+# Case 3c: Two INSERTs are run inside stored procedure, this time
+# the first INSERT will have a BF abort and real conflict.
+# A CONTINUE HANDLER is declared for the procedure. The expected outcome
+# is that the the first INSERT fails but the second is executed without
+# errors. wsrep_local_replays is not incremented.
+#
+DELIMITER |;
+CREATE PROCEDURE proc_insert_insert_conflict_with_continue_handler()
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT "Conflict continue handler";
+ INSERT INTO t1 VALUES (2, 'd');
+ INSERT INTO t1 VALUES (4, 'd');
+END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
+--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--let $galera_sp_bf_abort_proc = proc_insert_insert_conflict_with_continue_handler
+--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
+SET SESSION wsrep_sync_wait = 0;
+--source galera_sp_bf_abort.inc
+--connection node_1
+--reap
+SET SESSION wsrep_sync_wait = default;
+SELECT * FROM t1;
+--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
+--disable_query_log
+--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 0 AS wsrep_local_replays;
+--enable_query_log
+
+DELETE FROM t1;
+
+
+DROP PROCEDURE proc_update_insert;
+DROP PROCEDURE proc_update_insert_with_continue_handler;
+DROP PROCEDURE proc_update_insert_with_exit_handler;
+DROP PROCEDURE proc_update_insert_transaction;
+DROP PROCEDURE proc_update_insert_transaction_with_continue_handler;
+DROP PROCEDURE proc_update_insert_transaction_with_exit_handler;
+DROP PROCEDURE proc_insert_insert_conflict;
+DROP PROCEDURE proc_insert_insert_conflict_with_exit_handler;
+DROP PROCEDURE proc_insert_insert_conflict_with_continue_handler;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test
index 142f02546b4..d12ae7936cb 100644
--- a/mysql-test/suite/galera/t/galera_var_retry_autocommit.test
+++ b/mysql-test/suite/galera/t/galera_var_retry_autocommit.test
@@ -4,7 +4,9 @@
--source include/galera_cluster.inc
--source include/have_innodb.inc
+--source include/have_debug.inc
--source include/have_debug_sync.inc
+--source include/galera_have_debug_sync.inc
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result
new file mode 100644
index 00000000000..0461f1f1feb
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_A.result
@@ -0,0 +1,40 @@
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (2, 3);
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (3, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (4, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (5, 2);
+SET GLOBAL wsrep_provider_options = 'dbug=d,before_send_state_request';
+SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (6, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (7, 2);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (8, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+SET GLOBAL wsrep_provider_options = 'dbug=d,process_primary_configuration';
+SET GLOBAL wsrep_provider_options = 'signal=before_send_state_request';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+INSERT INTO t1 VALUES (9, 2);
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+DROP TABLE t1;
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result
new file mode 100644
index 00000000000..d878f60ca6b
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_B.result
@@ -0,0 +1,50 @@
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (2, 3);
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (3, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (4, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (5, 2);
+SET GLOBAL wsrep_provider_options = 'dbug=d,before_send_state_request';
+SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=before_send_state_request';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+VARIABLE_NAME VARIABLE_VALUE
+WSREP_DEBUG_SYNC_WAITERS after_shift_to_joining
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (6, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (7, 2);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (8, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+SET GLOBAL wsrep_provider_options = 'dbug=d,process_primary_configuration';
+SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+INSERT INTO t1 VALUES (9, 2);
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+VARIABLE_NAME VARIABLE_VALUE
+WSREP_DEBUG_SYNC_WAITERS process_primary_configuration
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET GLOBAL wsrep_provider_options = 'dbug=';
+DROP TABLE t1;
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result
new file mode 100644
index 00000000000..df0a924029c
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/r/galera_join_with_cc_C.result
@@ -0,0 +1,55 @@
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (2, 3);
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (3, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (4, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (5, 2);
+SET GLOBAL wsrep_provider_options = 'dbug=d,before_send_state_request';
+SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+SET GLOBAL wsrep_provider_options = 'dbug=d,after_shift_to_joining';
+SET GLOBAL wsrep_provider_options = 'signal=before_send_state_request';
+4
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+VARIABLE_NAME VARIABLE_VALUE
+WSREP_DEBUG_SYNC_WAITERS
+INSERT INTO t1 VALUES (6, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+INSERT INTO t1 VALUES (7, 2);
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'dbug=d,process_primary_configuration';
+SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+INSERT INTO t1 VALUES (8, 3);
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+INSERT INTO t1 VALUES (9, 2);
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=process_primary_configuration';
+SET SESSION wsrep_on = 0;
+SET SESSION wsrep_on = 0;
+SET GLOBAL wsrep_provider_options = 'dbug=';
+SET GLOBAL wsrep_provider_options = 'signal=after_shift_to_joining';
+DROP TABLE t1;
+call mtr.add_suppression("WSREP: Send action {\(.*\), STATE_REQUEST} returned -107 \\(Transport endpoint is not connected\\)");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test
new file mode 100644
index 00000000000..e181b6831af
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_A.test
@@ -0,0 +1,262 @@
+#
+# Tests handling of several configuration changes while a joiner gets
+# state transfer
+#
+# Variant A: sending of state transfer request delayed until two more
+# primary configuration changes happen
+#
+# Refs codersihp/galera-bugs#454
+#
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+--source suite/galera/include/galera_have_debug_sync.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Isolate node_1 and update cluster state to force node 1 into joiner mode
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (2, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now reconnect node_1 but first make it block before sending state transfer
+# request
+#
+# THIS IS PC1
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (3, 2);
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+#
+# At this point every node thinks that node_1 is in a JOINER state
+#
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now that node_1 sent state request and became JOINER isolate node_1 again
+# and commit one more action, so that node_1 loses JOINER state
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (4, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Reconnect node_1 again
+#
+# THIS IS PC2
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# After this point node_1 is no longer JOINER and is required to start the
+# whole procedure over because it missed some actions (4th insert into t1)
+#
+
+INSERT INTO t1 VALUES (5, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now let node_1 continue with IST and finish processing PC1, but make it
+# block when processing PC2 just before sending state transfer request
+#
+--connection node_1a
+--let $galera_sync_point = before_send_state_request
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_wait_sync_point.inc
+
+# since PC1 has been processed node_1 must have 3 rows in t1
+# 2 were there before PC1 and one was added while in PC1
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC3
+# It still is blocked before sending state transfer request in PC2.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (6, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC3
+#
+
+INSERT INTO t1 VALUES (7, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC4 and allow node_1
+# to send state transfer request to be delivered in PC4 (and thus get
+# updated to PC4 seqno in state transfer.
+# Note that node_1 still processes PC2.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (8, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC4. node_1 is still processing PC2, waiting to send state trasfer
+# request
+#
+--connection node_1a
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_signal_sync_point.inc
+# sent STR from PC2 into PC4
+
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC3, but should have completed state transfer from
+# PC4 and thus must have 8 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_2
+INSERT INTO t1 VALUES (9, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1a
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC4, still must have 8 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+DROP TABLE t1;
+
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+
+--connection node_2
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+
+--connection node_3
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test
new file mode 100644
index 00000000000..7618f5a112c
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_B.test
@@ -0,0 +1,273 @@
+#
+# Tests handling of several configuration changes while a joiner gets
+# state transfer
+#
+# Variant B: sending of state transfer request is immediate but completion
+# of IST delayed until two more primary configuration changes happen
+#
+# Refs codersihp/galera-bugs#454
+#
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+--source suite/galera/include/galera_have_debug_sync.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Isolate node_1 and update cluster state to force node 1 into joiner mode
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (2, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now reconnect node_1 but first make it block before sending state transfer
+# request
+#
+# THIS IS PC1
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (3, 2);
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+#
+# At this point every node thinks that node_1 is in a JOINER state
+#
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now that node_1 sent state request and became JOINER isolate node_1 again
+# and commit one more action, so that node_1 loses JOINER state
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (4, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Reconnect node_1 again
+#
+# THIS IS PC2
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# After this point node_1 is no longer JOINER and is required to start the
+# whole procedure over because it missed some actions (4th insert into t1)
+#
+
+INSERT INTO t1 VALUES (5, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now let node_1 continue with IST and finish processing PC1, but make it
+# block when processing PC2 right after progressing to JOINER state and
+# before IST happens.
+#
+--connection node_1a
+--let $galera_sync_point = before_send_state_request
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+# Here node_1 is processing PC2 just before sending state request
+
+# since PC1 has been processed node_1 must have 3 rows in t1
+# 2 were there before PC1 and one was added while in PC1
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+# Proceed to sending state transfer request and block right after
+--source include/galera_signal_sync_point.inc # before_send_state_request
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_wait_sync_point.inc
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+
+#
+# Now disconnect and reconnect node_1 again to get PC3
+# It is blocked right after shifting to JOINING state.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (6, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC3
+#
+
+INSERT INTO t1 VALUES (7, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC4 and allow node_1
+# to continue with IST.
+# Note that node_1 still processes PC2 and is joining.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (8, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC4. node_1 is still processing PC2, waiting to send state trasfer
+# request
+#
+--connection node_1a
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+# continue with IST prepared for in PC2
+
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC3, and should have finished state transfer
+# State tranfer request was dilivered before PC3, so node_1 should have
+# received IST up to 4 rows in t1 (what was there before PC2) plus one more
+# INSERT while in PC2.
+#
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_2
+INSERT INTO t1 VALUES (9, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1a
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_wait_sync_point.inc
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+#
+# Now node_1 is processing PC4, still must have 8 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+#--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+--source include/galera_clear_sync_point.inc
+
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+DROP TABLE t1;
+
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+
+--connection node_2
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+
+--connection node_3
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test
new file mode 100644
index 00000000000..68dea95854c
--- /dev/null
+++ b/mysql-test/suite/galera_3nodes/t/galera_join_with_cc_C.test
@@ -0,0 +1,299 @@
+#
+# Tests handling of several configuration changes while a joiner gets
+# state transfer
+#
+# Variant C: sending of state transfer request is scheduled while in non-PRIM
+#
+# Refs codersihp/galera-bugs#454
+#
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+--source suite/galera/include/galera_have_debug_sync.inc
+
+--let $galera_connection_name = node_3
+--let $galera_server_number = 3
+--source include/galera_connect.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, node INT) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 1);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 1 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Isolate node_1 and update cluster state to force node 1 into joiner mode
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (2, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 2 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now reconnect node_1 but first make it block before sending state transfer
+# request
+#
+# THIS IS PC1
+#
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+SET wsrep_sync_wait = 0;
+SET wsrep_on = OFF;
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (3, 2);
+
+--connection node_1a
+--source include/galera_wait_sync_point.inc
+#
+# At this point every node thinks that node_1 is in a JOINER state
+#
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now that node_1 sent state request and became JOINER isolate node_1 again
+# and commit one more action, so that node_1 loses JOINER state
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (4, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 4 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Reconnect node_1 again
+#
+# THIS IS PC2
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# After this point node_1 is no longer JOINER and is required to start the
+# whole procedure over because it missed some actions (4th insert into t1)
+#
+
+INSERT INTO t1 VALUES (5, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 5 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now let node_1 continue with IST and finish processing PC1, but make it
+# block when processing PC2 right after progressing to JOINER state and
+# before IST happens.
+#
+--connection node_1a
+--let $galera_sync_point = before_send_state_request
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+# Here we are processing PC2 just before sending state request
+
+# since PC1 has been processed node_1 must have 3 rows in t1
+# 2 were there before PC1 and one was added while in PC1
+--let $wait_condition = SELECT COUNT(*) = 3 FROM t1;
+--source include/wait_condition.inc
+
+#
+# Now disconnect and reconnect node_1 again to get PC3
+# It still is blocked before sending state transfer request in PC2.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+# Proceed to sending state transfer request
+--connection node_1a
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = before_send_state_request
+--source include/galera_signal_sync_point.inc # before_send_state_request
+#
+# node_1 proceeds to sending state transfer request, it will be delivered only
+# in the next PC which is PC3. Only then the node will shift to JOINING
+#
+--echo 4
+SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_debug_sync_waiters';
+
+--connection node_3
+INSERT INTO t1 VALUES (6, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC3
+#
+
+INSERT INTO t1 VALUES (7, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+# node_1 is stiil processing PC2, it was let to send state transfer request
+# while in non-PRIM. Now it should be able to complete it and shift to
+# JOINING. Make it block on next PC(3) and continue to receive IST
+--connection node_1a
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc # won't need it any more
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_set_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_signal_sync_point.inc
+# continue with IST while still processing PC2
+
+#
+# Now disconnect and reconnect node_1 again to generate PC4.
+#
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=1';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--connection node_3
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+INSERT INTO t1 VALUES (8, 3);
+
+--connection node_2
+--let $wait_condition = SELECT COUNT(*) = 8 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+SET GLOBAL wsrep_provider_options='gmcast.isolate=0';
+
+--connection node_2
+--let $wait_condition = SELECT VARIABLE_VALUE = 3 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+#
+# This is PC4. node_1 should complete IST, complete PC2, and continue
+# with the next item in queue
+#
+--connection node_1a
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+
+#
+# Now node_1 is blocked before processing PC3, and should have finished state
+# transfer started while in PC2.
+# State tranfer request was dilivered in PC3 to donor, so node_1 should have
+# received IST up to 6 rows in t1 (what was there before PC3).
+#
+--let $wait_condition = SELECT COUNT(*) = 6 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_2
+INSERT INTO t1 VALUES (9, 2);
+
+--connection node_3
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1a
+# continue with processing PC3
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_signal_sync_point.inc
+
+# wait for row that follows PC3
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+# wait till PC4
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_wait_sync_point.inc
+#
+# Now node_1 is processing PC4, still must have 7 rows in t1
+#
+--let $wait_condition = SELECT COUNT(*) = 7 FROM t1;
+--source include/wait_condition.inc
+
+# Continue with PC4
+--let $galera_sync_point = process_primary_configuration
+--source include/galera_clear_sync_point.inc
+--source include/galera_signal_sync_point.inc
+--let $galera_sync_point = after_shift_to_joining
+--source include/galera_wait_sync_point.inc
+--source include/galera_clear_sync_point.inc
+--source include/galera_signal_sync_point.inc
+
+--let $wait_condition = SELECT COUNT(*) = 9 FROM t1;
+--source include/wait_condition.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready';
+--source include/wait_condition.inc
+
+DROP TABLE t1;
+
+call mtr.add_suppression("WSREP: Send action {\(.*\), STATE_REQUEST} returned -107 \\(Transport endpoint is not connected\\)");
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+
+--connection node_2
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
+
+--connection node_3
+call mtr.add_suppression("WSREP: Rejecting JOIN message from \(.*\): new State Transfer required.");
diff --git a/mysql-test/suite/innodb/r/foreign-keys.result b/mysql-test/suite/innodb/r/foreign-keys.result
deleted file mode 100644
index 10e0b1f3d7b..00000000000
--- a/mysql-test/suite/innodb/r/foreign-keys.result
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE
-# ADD FOREIGN KEY
-#
-CREATE TABLE `department` (`department_id` INT, `department_people_fk` INT,
-PRIMARY KEY (`department_id`)) engine=innodb;
-CREATE TABLE `title` (`title_id` INT, `title_manager_fk` INT,
-`title_reporter_fk` INT, PRIMARY KEY (`title_id`)) engine=innodb;
-CREATE TABLE `people` (`people_id` INT, PRIMARY KEY (`people_id`)) engine=innodb;
-ALTER TABLE `department` ADD FOREIGN KEY (`department_people_fk`) REFERENCES
-`people` (`people_id`);
-ALTER TABLE `title` ADD FOREIGN KEY (`title_manager_fk`) REFERENCES `people`
-(`people_id`);
-ALTER TABLE `title` ADD FOREIGN KEY (`title_reporter_fk`) REFERENCES `people`
-(`people_id`);
-drop table title, department, people;
-create table t1 (a int primary key, b int) engine=innodb;
-create table t2 (c int primary key, d int,
-foreign key (d) references t1 (a) on update cascade) engine=innodb;
-insert t1 values (1,1),(2,2),(3,3);
-insert t2 values (4,1),(5,2),(6,3);
-flush table t2 with read lock;
-connect con1,localhost,root;
-delete from t1 where a=2;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`d`) REFERENCES `t1` (`a`) ON UPDATE CASCADE)
-update t1 set a=10 where a=1;
-connection default;
-unlock tables;
-connection con1;
-connection default;
-lock table t2 write;
-connection con1;
-delete from t1 where a=2;
-connection default;
-unlock tables;
-connection con1;
-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`d`) REFERENCES `t1` (`a`) ON UPDATE CASCADE)
-connection default;
-unlock tables;
-disconnect con1;
-create user foo;
-grant select,update on test.t1 to foo;
-connect foo,localhost,foo;
-update t1 set a=30 where a=3;
-disconnect foo;
-connection default;
-select * from t2;
-c d
-5 2
-4 10
-6 30
-drop table t2, t1;
-drop user foo;
-create table t1 (f1 int primary key) engine=innodb;
-create table t2 (f2 int primary key) engine=innodb;
-create table t3 (f3 int primary key, foreign key (f3) references t2(f2)) engine=innodb;
-insert into t1 values (1),(2),(3),(4),(5);
-insert into t2 values (1),(2),(3),(4),(5);
-insert into t3 values (1),(2),(3),(4),(5);
-connect con1,localhost,root;
-set debug_sync='alter_table_before_rename_result_table signal g1 wait_for g2';
-alter table t2 add constraint foreign key (f2) references t1(f1) on delete cascade on update cascade;
-connection default;
-set debug_sync='before_execute_sql_command wait_for g1';
-update t1 set f1 = f1 + 100000 limit 2;
-connect con2,localhost,root;
-kill query UPDATE;
-disconnect con2;
-connection default;
-ERROR 70100: Query execution was interrupted
-set debug_sync='now signal g2';
-connection con1;
-show create table t2;
-Table Create Table
-t2 CREATE TABLE `t2` (
- `f2` int(11) NOT NULL,
- PRIMARY KEY (`f2`),
- CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-disconnect con1;
-connection default;
-select * from t2 where f2 not in (select f1 from t1);
-f2
-select * from t3 where f3 not in (select f2 from t2);
-f3
-drop table t3;
-drop table t2;
-drop table t1;
-set debug_sync='reset';
-#
-# MDEV-17595 - Server crashes in copy_data_between_tables or
-# Assertion `thd->transaction.stmt.is_empty() ||
-# (thd->state_flags & Open_tables_state::BACKUPS_AVAIL)'
-# fails in close_tables_for_reopen upon concurrent
-# ALTER TABLE and FLUSH
-#
-CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES(1),(2);
-CREATE TABLE t2 (b INT, KEY(b)) ENGINE=InnoDB;
-INSERT INTO t2 VALUES(2);
-ALTER TABLE t2 ADD FOREIGN KEY(b) REFERENCES t1(a), LOCK=EXCLUSIVE;
-DROP TABLE t2, t1;
-#
-# MDEV-16060 - InnoDB: Failing assertion: ut_strcmp(index->name, key->name)
-#
-CREATE TABLE t1 (`pk` INT PRIMARY KEY) ENGINE=InnoDB;
-CREATE TABLE t2 LIKE t1;
-FLUSH TABLES;
-SET debug_sync='alter_table_intermediate_table_created SIGNAL ready WAIT_FOR go';
-ALTER TABLE t1 ADD FOREIGN KEY(pk) REFERENCES t2(pk) ON UPDATE CASCADE;
-connect con1, localhost, root;
-SET debug_sync='now WAIT_FOR ready';
-SET lock_wait_timeout=1;
-UPDATE t2 SET pk=10 WHERE pk=1;
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-PREPARE stmt FROM 'UPDATE t2 SET pk=10 WHERE pk=1';
-DEALLOCATE PREPARE stmt;
-FLUSH TABLE t2;
-SET debug_sync='now SIGNAL go';
-connection default;
-disconnect con1;
-connection default;
-SET debug_sync='reset';
-SHOW OPEN TABLES FROM test;
-Database Table In_use Name_locked
-DROP TABLE t1, t2;
diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result
index e56e5308909..74d7cbb7d9a 100644
--- a/mysql-test/suite/innodb/r/foreign_key.result
+++ b/mysql-test/suite/innodb/r/foreign_key.result
@@ -113,3 +113,169 @@ CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f);
ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1);
DROP TABLE t1, t2;
+CREATE TABLE t1 (a INT, b INT, KEY idx(a)) ENGINE=InnoDB;
+SET FOREIGN_KEY_CHECKS= OFF;
+ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES tx(x);
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 CHANGE a c INT;
+DROP TABLE t1;
+CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB;
+ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1);
+ALTER TABLE t1 ADD COLUMN f INT;
+SET FOREIGN_KEY_CHECKS= OFF;
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 ADD KEY idx (f1);
+SET FOREIGN_KEY_CHECKS= ON;
+ALTER TABLE t1 DROP f3;
+ALTER TABLE t1 CHANGE f f3 INT;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+#
+# Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE
+# ADD FOREIGN KEY
+#
+CREATE TABLE `department` (`department_id` INT, `department_people_fk` INT,
+PRIMARY KEY (`department_id`)) engine=innodb;
+CREATE TABLE `title` (`title_id` INT, `title_manager_fk` INT,
+`title_reporter_fk` INT, PRIMARY KEY (`title_id`)) engine=innodb;
+CREATE TABLE `people` (`people_id` INT, PRIMARY KEY (`people_id`)) engine=innodb;
+ALTER TABLE `department` ADD FOREIGN KEY (`department_people_fk`) REFERENCES
+`people` (`people_id`);
+ALTER TABLE `title` ADD FOREIGN KEY (`title_manager_fk`) REFERENCES `people`
+(`people_id`);
+ALTER TABLE `title` ADD FOREIGN KEY (`title_reporter_fk`) REFERENCES `people`
+(`people_id`);
+drop table title, department, people;
+create table t1 (a int primary key, b int) engine=innodb;
+create table t2 (c int primary key, d int,
+foreign key (d) references t1 (a) on update cascade) engine=innodb;
+insert t1 values (1,1),(2,2),(3,3);
+insert t2 values (4,1),(5,2),(6,3);
+flush table t2 with read lock;
+delete from t1 where a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`d`) REFERENCES `t1` (`a`) ON UPDATE CASCADE)
+update t1 set a=10 where a=1;
+unlock tables;
+lock table t2 write;
+delete from t1 where a=2;
+unlock tables;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`d`) REFERENCES `t1` (`a`) ON UPDATE CASCADE)
+unlock tables;
+create user foo;
+grant select,update on test.t1 to foo;
+update t1 set a=30 where a=3;
+select * from t2;
+c d
+5 2
+4 10
+6 30
+drop table t2, t1;
+drop user foo;
+#
+# MDEV-17595 - Server crashes in copy_data_between_tables or
+# Assertion `thd->transaction.stmt.is_empty() ||
+# (thd->state_flags & Open_tables_state::BACKUPS_AVAIL)'
+# fails in close_tables_for_reopen upon concurrent
+# ALTER TABLE and FLUSH
+#
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1),(2);
+CREATE TABLE t2 (b INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(2);
+ALTER TABLE t2 ADD FOREIGN KEY(b) REFERENCES t1(a), LOCK=EXCLUSIVE;
+DROP TABLE t2, t1;
+create table t1 (pk int primary key, data int) engine=innodb;
+insert t1 values (1,1),(2,2),(3,3);
+create table t2 (t1_pk int, foreign key (t1_pk) references t1 (pk)) engine=innodb;
+insert t2 values (1),(2);
+insert t2 values (10);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`t1_pk`) REFERENCES `t1` (`pk`))
+flush tables;
+flush status;
+update t1 set data=10 where pk+1>10;
+show status like '%opened_tab%';
+Variable_name Value
+Opened_table_definitions 1
+Opened_tables 1
+flush tables;
+flush status;
+update t2 set t1_pk=11 where t1_pk+1>10;
+show status like '%opened_tab%';
+Variable_name Value
+Opened_table_definitions 1
+Opened_tables 1
+flush tables;
+flush status;
+lock tables t1 write;
+show status like '%opened_tab%';
+Variable_name Value
+Opened_table_definitions 2
+Opened_tables 2
+insert t1 values (4,4);
+show status like '%opened_tab%';
+Variable_name Value
+Opened_table_definitions 2
+Opened_tables 2
+unlock tables;
+create function foo() returns int
+begin
+insert t1 values (5,5);
+return 5;
+end|
+flush tables;
+flush status;
+select foo();
+foo()
+5
+show status like '%opened_tab%';
+Variable_name Value
+Opened_table_definitions 2
+Opened_tables 2
+drop function foo;
+drop table t2, t1;
+CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk)) ENGINE=InnoDB;
+XA START 'xid';
+INSERT INTO t1 VALUES (1,2);
+CREATE TABLE x AS SELECT * FROM t1;
+ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state
+SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 1;
+ALTER TABLE t1 ADD FOREIGN KEY f (a) REFERENCES t1 (pk), LOCK=EXCLUSIVE;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+XA END 'xid';
+XA ROLLBACK 'xid';
+DROP TABLE t1;
+CREATE TABLE t1 (pk INT PRIMARY KEY,
+f1 VARCHAR(10), f2 VARCHAR(10),
+f3 VARCHAR(10), f4 VARCHAR(10),
+f5 VARCHAR(10), f6 VARCHAR(10),
+f7 VARCHAR(10), f8 VARCHAR(10),
+INDEX(f1), INDEX(f2), INDEX(f3), INDEX(f4),
+INDEX(f5), INDEX(f6), INDEX(f7), INDEX(f8)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+(2, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+(3, 'innodb', 'innodb', 'innodb', 'innodb',
+'innodb', 'innodb', 'innodb', 'innodb');
+ALTER TABLE t1 ADD FOREIGN KEY (f1) REFERENCES t1 (f2) ON DELETE SET NULL;
+START TRANSACTION;
+DELETE FROM t1 where f1='mariadb';
+SELECT * FROM t1;
+pk f1 f2 f3 f4 f5 f6 f7 f8
+2 NULL mariadb mariadb mariadb mariadb mariadb mariadb mariadb
+3 innodb innodb innodb innodb innodb innodb innodb innodb
+ROLLBACK;
+ALTER TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f4) ON DELETE CASCADE;
+START TRANSACTION;
+DELETE FROM t1 where f3='mariadb';
+SELECT * FROM t1;
+pk f1 f2 f3 f4 f5 f6 f7 f8
+3 innodb innodb innodb innodb innodb innodb innodb innodb
+ROLLBACK;
+ALTER TABLE t1 ADD FOREIGN KEY (f5) REFERENCES t1 (f6) ON UPDATE SET NULL;
+UPDATE t1 SET f6='update';
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_3` FOREIGN KEY (`f5`) REFERENCES `t1` (`f6`) ON UPDATE SET NULL)
+ALTER TABLE t1 ADD FOREIGN KEY (f7) REFERENCES t1 (f8) ON UPDATE CASCADE;
+UPDATE t1 SET f6='cascade';
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_3` FOREIGN KEY (`f5`) REFERENCES `t1` (`f6`) ON UPDATE SET NULL)
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/foreign_key_debug.result b/mysql-test/suite/innodb/r/foreign_key_debug.result
new file mode 100644
index 00000000000..741200b62b2
--- /dev/null
+++ b/mysql-test/suite/innodb/r/foreign_key_debug.result
@@ -0,0 +1,60 @@
+create table t1 (f1 int primary key) engine=innodb;
+create table t2 (f2 int primary key) engine=innodb;
+create table t3 (f3 int primary key, foreign key (f3) references t2(f2)) engine=innodb;
+insert into t1 values (1),(2),(3),(4),(5);
+insert into t2 values (1),(2),(3),(4),(5);
+insert into t3 values (1),(2),(3),(4),(5);
+connect con1,localhost,root;
+set debug_sync='alter_table_before_rename_result_table signal g1 wait_for g2';
+alter table t2 add constraint foreign key (f2) references t1(f1) on delete cascade on update cascade;
+connection default;
+set debug_sync='before_execute_sql_command wait_for g1';
+update t1 set f1 = f1 + 100000 limit 2;
+connect con2,localhost,root;
+kill query UPDATE;
+disconnect con2;
+connection default;
+ERROR 70100: Query execution was interrupted
+set debug_sync='now signal g2';
+connection con1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `f2` int(11) NOT NULL,
+ PRIMARY KEY (`f2`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+disconnect con1;
+connection default;
+select * from t2 where f2 not in (select f1 from t1);
+f2
+select * from t3 where f3 not in (select f2 from t2);
+f3
+drop table t3;
+drop table t2;
+drop table t1;
+set debug_sync='reset';
+#
+# MDEV-16060 - InnoDB: Failing assertion: ut_strcmp(index->name, key->name)
+#
+CREATE TABLE t1 (`pk` INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+SET debug_sync='alter_table_intermediate_table_created SIGNAL ready WAIT_FOR go';
+ALTER TABLE t1 ADD FOREIGN KEY(pk) REFERENCES t2(pk) ON UPDATE CASCADE;
+connect con1, localhost, root;
+SET debug_sync='now WAIT_FOR ready';
+SET lock_wait_timeout=1;
+UPDATE t2 SET pk=10 WHERE pk=1;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+PREPARE stmt FROM 'UPDATE t2 SET pk=10 WHERE pk=1';
+DEALLOCATE PREPARE stmt;
+FLUSH TABLE t2;
+SET debug_sync='now SIGNAL go';
+connection default;
+disconnect con1;
+connection default;
+SET debug_sync='reset';
+SHOW OPEN TABLES FROM test;
+Database Table In_use Name_locked
+DROP TABLE t1, t2;
diff --git a/mysql-test/suite/innodb/r/innodb-64k.result b/mysql-test/suite/innodb/r/innodb-64k.result
index dc938f236cd..0ecc1b7096b 100644
--- a/mysql-test/suite/innodb/r/innodb-64k.result
+++ b/mysql-test/suite/innodb/r/innodb-64k.result
@@ -1084,3 +1084,10 @@ update t2 set col145=@b;
COMMIT;
drop table t2;
DROP TABLE t1;
+#
+# MDEV-19526 heap number overflow
+#
+CREATE TABLE t1(a SMALLINT NOT NULL UNIQUE AUTO_INCREMENT, KEY(a))
+ENGINE=InnoDB;
+INSERT INTO t1 (a) SELECT seq FROM seq_1_to_8191;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result
index 13cc45e0ef9..c8329156162 100644
--- a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result
+++ b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result
@@ -43,3 +43,5 @@ innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
innodb_stats_drop_locked
+DELETE FROM mysql.innodb_index_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
+DELETE FROM mysql.innodb_table_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
diff --git a/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result b/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result
new file mode 100644
index 00000000000..32d87b4668a
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_sys_var_valgrind.result
@@ -0,0 +1,73 @@
+#
+# Bug #29717909 MEMORY LIFETIME OF VARIABLES BETWEEN CHECK AND UPDATE INCORRECTLY MANAGED
+#
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+NULL
+create table user_stopword_1(value varchar(30)) engine = innodb;
+create table user_stopword_2(value varchar(30)) engine = innodb;
+set @blah = 'test/user_stopword_1';
+SET GLOBAL innodb_ft_server_stopword_table= @blah;
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+test/user_stopword_1
+set @blah = 'test/user_stopword_2';
+SET GLOBAL innodb_ft_server_stopword_table= @blah;
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+test/user_stopword_2
+SET GLOBAL innodb_ft_server_stopword_table= NULL;
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+NULL
+SET GLOBAL innodb_ft_server_stopword_table= default;
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+NULL
+drop table user_stopword_1, user_stopword_2;
+select @@innodb_buffer_pool_filename;
+@@innodb_buffer_pool_filename
+ib_buffer_pool
+set @blah='hello';
+set global innodb_buffer_pool_filename = @blah;
+select @@innodb_buffer_pool_filename;
+@@innodb_buffer_pool_filename
+hello
+set global innodb_buffer_pool_filename="bye";
+select @@innodb_buffer_pool_filename;
+@@innodb_buffer_pool_filename
+bye
+set global innodb_buffer_pool_filename=NULL;
+ERROR 42000: Variable 'innodb_buffer_pool_filename' can't be set to the value of 'NULL'
+select @@innodb_buffer_pool_filename;
+@@innodb_buffer_pool_filename
+bye
+set global innodb_buffer_pool_filename=default;
+select @@innodb_buffer_pool_filename;
+@@innodb_buffer_pool_filename
+ib_buffer_pool
+CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
+(opening_line)) ENGINE=InnoDB;
+CREATE TABLE t2 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
+(opening_line)) ENGINE=InnoDB;
+select @@innodb_ft_aux_table;
+@@innodb_ft_aux_table
+NULL
+set @blah = 'test/t1';
+SET GLOBAL innodb_ft_aux_table = @blah;
+select @@innodb_ft_aux_table;
+@@innodb_ft_aux_table
+test/t1
+set @blah = 'test/t2';
+SET GLOBAL innodb_ft_aux_table = @blah;
+SET GLOBAL innodb_ft_aux_table = NULL;
+select @@innodb_ft_aux_table;
+@@innodb_ft_aux_table
+NULL
+SET GLOBAL innodb_ft_aux_table =default;
+select @@innodb_ft_aux_table;
+@@innodb_ft_aux_table
+NULL
+drop table t1,t2;
diff --git a/mysql-test/suite/innodb/r/read_only_recover_committed.result b/mysql-test/suite/innodb/r/read_only_recover_committed.result
index 593bcae40ee..45e9df65819 100644
--- a/mysql-test/suite/innodb/r/read_only_recover_committed.result
+++ b/mysql-test/suite/innodb/r/read_only_recover_committed.result
@@ -26,6 +26,7 @@ a
1
UPDATE t SET a=3 WHERE a=1;
ERROR HY000: Table 't' is read only
+SET GLOBAL innodb_status_output= @@GLOBAL.innodb_status_output;
# Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.
# In earlier versions, this would return the last committed version
# (empty table)!
diff --git a/mysql-test/suite/innodb/t/foreign-keys.test b/mysql-test/suite/innodb/t/foreign-keys.test
deleted file mode 100644
index a19fe3876f3..00000000000
--- a/mysql-test/suite/innodb/t/foreign-keys.test
+++ /dev/null
@@ -1,160 +0,0 @@
---source include/have_innodb.inc
---source include/have_debug.inc
---source include/have_debug_sync.inc
-
---enable_connect_log
-
---echo #
---echo # Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE
---echo # ADD FOREIGN KEY
---echo #
-
-CREATE TABLE `department` (`department_id` INT, `department_people_fk` INT,
-PRIMARY KEY (`department_id`)) engine=innodb;
-
-CREATE TABLE `title` (`title_id` INT, `title_manager_fk` INT,
-`title_reporter_fk` INT, PRIMARY KEY (`title_id`)) engine=innodb;
-
-CREATE TABLE `people` (`people_id` INT, PRIMARY KEY (`people_id`)) engine=innodb;
-
-ALTER TABLE `department` ADD FOREIGN KEY (`department_people_fk`) REFERENCES
-`people` (`people_id`);
-
-ALTER TABLE `title` ADD FOREIGN KEY (`title_manager_fk`) REFERENCES `people`
-(`people_id`);
-
-ALTER TABLE `title` ADD FOREIGN KEY (`title_reporter_fk`) REFERENCES `people`
-(`people_id`);
-
-drop table title, department, people;
-
-#
-# FK and prelocking:
-# child table accesses (reads and writes) wait for locks.
-#
-create table t1 (a int primary key, b int) engine=innodb;
-create table t2 (c int primary key, d int,
- foreign key (d) references t1 (a) on update cascade) engine=innodb;
-insert t1 values (1,1),(2,2),(3,3);
-insert t2 values (4,1),(5,2),(6,3);
-flush table t2 with read lock; # this takes MDL_SHARED_NO_WRITE
-connect (con1,localhost,root);
---error ER_ROW_IS_REFERENCED_2
-delete from t1 where a=2;
-send update t1 set a=10 where a=1;
-connection default;
-let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock';
-source include/wait_condition.inc;
-unlock tables;
-connection con1;
-reap;
-connection default;
-lock table t2 write; # this takes MDL_SHARED_NO_READ_WRITE
-connection con1;
-send delete from t1 where a=2;
-connection default;
-let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock';
-source include/wait_condition.inc;
-unlock tables;
-connection con1;
---error ER_ROW_IS_REFERENCED_2
-reap;
-connection default;
-unlock tables;
-disconnect con1;
-
-# but privileges should not be checked
-create user foo;
-grant select,update on test.t1 to foo;
-connect(foo,localhost,foo);
-update t1 set a=30 where a=3;
-disconnect foo;
-connection default;
-select * from t2;
-drop table t2, t1;
-drop user foo;
-
-#
-# MDEV-16465 Invalid (old?) table or database name or hang in ha_innobase::delete_table and log semaphore wait upon concurrent DDL with foreign keys
-#
-create table t1 (f1 int primary key) engine=innodb;
-create table t2 (f2 int primary key) engine=innodb;
-create table t3 (f3 int primary key, foreign key (f3) references t2(f2)) engine=innodb;
-insert into t1 values (1),(2),(3),(4),(5);
-insert into t2 values (1),(2),(3),(4),(5);
-insert into t3 values (1),(2),(3),(4),(5);
-connect con1,localhost,root;
-set debug_sync='alter_table_before_rename_result_table signal g1 wait_for g2';
-send alter table t2 add constraint foreign key (f2) references t1(f1) on delete cascade on update cascade;
-connection default;
-let $conn=`select connection_id()`;
-set debug_sync='before_execute_sql_command wait_for g1';
-send update t1 set f1 = f1 + 100000 limit 2;
-connect con2,localhost,root;
-let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock' and info like 'update t1 %';
-source include/wait_condition.inc;
---replace_result $conn UPDATE
-eval kill query $conn;
-disconnect con2;
-connection default;
-error ER_QUERY_INTERRUPTED;
-reap;
-set debug_sync='now signal g2';
-connection con1;
-reap;
-show create table t2;
-disconnect con1;
-connection default;
-select * from t2 where f2 not in (select f1 from t1);
-select * from t3 where f3 not in (select f2 from t2);
-drop table t3;
-drop table t2;
-drop table t1;
-set debug_sync='reset';
-
-
---echo #
---echo # MDEV-17595 - Server crashes in copy_data_between_tables or
---echo # Assertion `thd->transaction.stmt.is_empty() ||
---echo # (thd->state_flags & Open_tables_state::BACKUPS_AVAIL)'
---echo # fails in close_tables_for_reopen upon concurrent
---echo # ALTER TABLE and FLUSH
---echo #
-CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
-INSERT INTO t1 VALUES(1),(2);
-CREATE TABLE t2 (b INT, KEY(b)) ENGINE=InnoDB;
-INSERT INTO t2 VALUES(2);
-ALTER TABLE t2 ADD FOREIGN KEY(b) REFERENCES t1(a), LOCK=EXCLUSIVE;
-DROP TABLE t2, t1;
-
-
---echo #
---echo # MDEV-16060 - InnoDB: Failing assertion: ut_strcmp(index->name, key->name)
---echo #
-CREATE TABLE t1 (`pk` INT PRIMARY KEY) ENGINE=InnoDB;
-CREATE TABLE t2 LIKE t1;
-FLUSH TABLES;
-
-SET debug_sync='alter_table_intermediate_table_created SIGNAL ready WAIT_FOR go';
-send ALTER TABLE t1 ADD FOREIGN KEY(pk) REFERENCES t2(pk) ON UPDATE CASCADE;
-
-connect con1, localhost, root;
-SET debug_sync='now WAIT_FOR ready';
-SET lock_wait_timeout=1; # change to 0 in 10.3
---error ER_LOCK_WAIT_TIMEOUT
-UPDATE t2 SET pk=10 WHERE pk=1;
-PREPARE stmt FROM 'UPDATE t2 SET pk=10 WHERE pk=1';
-DEALLOCATE PREPARE stmt;
-FLUSH TABLE t2;
-SET debug_sync='now SIGNAL go';
-
-connection default;
-reap;
-
-# Cleanup
-disconnect con1;
-
-connection default;
-SET debug_sync='reset';
-SHOW OPEN TABLES FROM test;
-DROP TABLE t1, t2;
diff --git a/mysql-test/suite/innodb/t/foreign_key.test b/mysql-test/suite/innodb/t/foreign_key.test
index 08fe44911b5..29bf91f2f24 100644
--- a/mysql-test/suite/innodb/t/foreign_key.test
+++ b/mysql-test/suite/innodb/t/foreign_key.test
@@ -134,3 +134,206 @@ CREATE TABLE t2 (f INT, KEY(f)) ENGINE=InnoDB;
ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t2 (f);
ALTER IGNORE TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f1);
DROP TABLE t1, t2;
+
+# MDEV-19092 Server crash when renaming the column when
+# FOREIGN_KEY_CHECKS is disabled
+CREATE TABLE t1 (a INT, b INT, KEY idx(a)) ENGINE=InnoDB;
+SET FOREIGN_KEY_CHECKS= OFF;
+ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES tx(x);
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 CHANGE a c INT;
+# Cleanup
+DROP TABLE t1;
+
+CREATE TABLE t1 (f1 INT, f2 INT, f3 INT, KEY idx(f1)) ENGINE=InnoDB;
+ALTER TABLE t1 ADD FOREIGN KEY (f2) REFERENCES t1 (f1);
+ALTER TABLE t1 ADD COLUMN f INT;
+SET FOREIGN_KEY_CHECKS= OFF;
+ALTER TABLE t1 DROP KEY idx;
+ALTER TABLE t1 ADD KEY idx (f1);
+SET FOREIGN_KEY_CHECKS= ON;
+ALTER TABLE t1 DROP f3;
+ALTER TABLE t1 CHANGE f f3 INT;
+# Cleanup
+DROP TABLE t1;
+
+SET FOREIGN_KEY_CHECKS=1;
+
+--echo #
+--echo # Bug #19471516 SERVER CRASHES WHEN EXECUTING ALTER TABLE
+--echo # ADD FOREIGN KEY
+--echo #
+
+CREATE TABLE `department` (`department_id` INT, `department_people_fk` INT,
+PRIMARY KEY (`department_id`)) engine=innodb;
+
+CREATE TABLE `title` (`title_id` INT, `title_manager_fk` INT,
+`title_reporter_fk` INT, PRIMARY KEY (`title_id`)) engine=innodb;
+
+CREATE TABLE `people` (`people_id` INT, PRIMARY KEY (`people_id`)) engine=innodb;
+
+ALTER TABLE `department` ADD FOREIGN KEY (`department_people_fk`) REFERENCES
+`people` (`people_id`);
+
+ALTER TABLE `title` ADD FOREIGN KEY (`title_manager_fk`) REFERENCES `people`
+(`people_id`);
+
+ALTER TABLE `title` ADD FOREIGN KEY (`title_reporter_fk`) REFERENCES `people`
+(`people_id`);
+
+drop table title, department, people;
+
+#
+# FK and prelocking:
+# child table accesses (reads and writes) wait for locks.
+#
+create table t1 (a int primary key, b int) engine=innodb;
+create table t2 (c int primary key, d int,
+ foreign key (d) references t1 (a) on update cascade) engine=innodb;
+insert t1 values (1,1),(2,2),(3,3);
+insert t2 values (4,1),(5,2),(6,3);
+flush table t2 with read lock; # this takes MDL_SHARED_NO_WRITE
+connect (con1,localhost,root);
+--error ER_ROW_IS_REFERENCED_2
+delete from t1 where a=2;
+send update t1 set a=10 where a=1;
+connection default;
+let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock';
+source include/wait_condition.inc;
+unlock tables;
+connection con1;
+reap;
+connection default;
+lock table t2 write; # this takes MDL_SHARED_NO_READ_WRITE
+connection con1;
+send delete from t1 where a=2;
+connection default;
+let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock';
+source include/wait_condition.inc;
+unlock tables;
+connection con1;
+--error ER_ROW_IS_REFERENCED_2
+reap;
+connection default;
+unlock tables;
+disconnect con1;
+
+# but privileges should not be checked
+create user foo;
+grant select,update on test.t1 to foo;
+connect(foo,localhost,foo);
+update t1 set a=30 where a=3;
+disconnect foo;
+connection default;
+select * from t2;
+drop table t2, t1;
+drop user foo;
+
+--echo #
+--echo # MDEV-17595 - Server crashes in copy_data_between_tables or
+--echo # Assertion `thd->transaction.stmt.is_empty() ||
+--echo # (thd->state_flags & Open_tables_state::BACKUPS_AVAIL)'
+--echo # fails in close_tables_for_reopen upon concurrent
+--echo # ALTER TABLE and FLUSH
+--echo #
+CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(1),(2);
+CREATE TABLE t2 (b INT, KEY(b)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(2);
+ALTER TABLE t2 ADD FOREIGN KEY(b) REFERENCES t1(a), LOCK=EXCLUSIVE;
+DROP TABLE t2, t1;
+
+#
+# MDEV-22180 Planner opens unnecessary tables when updated table is referenced by foreign keys
+#
+
+create table t1 (pk int primary key, data int) engine=innodb;
+insert t1 values (1,1),(2,2),(3,3);
+create table t2 (t1_pk int, foreign key (t1_pk) references t1 (pk)) engine=innodb;
+insert t2 values (1),(2);
+error ER_NO_REFERENCED_ROW_2;
+insert t2 values (10);
+flush tables;
+flush status;
+# with ON UPDATE RESTRICT child tables are not opened
+update t1 set data=10 where pk+1>10;
+show status like '%opened_tab%';
+flush tables;
+flush status;
+# neither are parent tables
+update t2 set t1_pk=11 where t1_pk+1>10;
+show status like '%opened_tab%';
+# under LOCK TABLES
+flush tables;
+flush status;
+lock tables t1 write;
+show status like '%opened_tab%';
+insert t1 values (4,4);
+show status like '%opened_tab%';
+unlock tables;
+delimiter |;
+create function foo() returns int
+begin
+ insert t1 values (5,5);
+ return 5;
+end|
+delimiter ;|
+flush tables;
+flush status;
+select foo();
+show status like '%opened_tab%';
+drop function foo;
+drop table t2, t1;
+
+CREATE TABLE t1 (pk INT, a INT, PRIMARY KEY (pk)) ENGINE=InnoDB;
+XA START 'xid';
+INSERT INTO t1 VALUES (1,2);
+--error ER_XAER_RMFAIL
+CREATE TABLE x AS SELECT * FROM t1;
+--connect (con1,localhost,root,,test)
+SET foreign_key_checks= OFF, innodb_lock_wait_timeout= 1;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 ADD FOREIGN KEY f (a) REFERENCES t1 (pk), LOCK=EXCLUSIVE;# Cleanup
+--disconnect con1
+--connection default
+XA END 'xid';
+XA ROLLBACK 'xid';
+DROP TABLE t1;
+
+CREATE TABLE t1 (pk INT PRIMARY KEY,
+ f1 VARCHAR(10), f2 VARCHAR(10),
+ f3 VARCHAR(10), f4 VARCHAR(10),
+ f5 VARCHAR(10), f6 VARCHAR(10),
+ f7 VARCHAR(10), f8 VARCHAR(10),
+ INDEX(f1), INDEX(f2), INDEX(f3), INDEX(f4),
+ INDEX(f5), INDEX(f6), INDEX(f7), INDEX(f8)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+ 'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+ (2, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+ 'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+ (3, 'innodb', 'innodb', 'innodb', 'innodb',
+ 'innodb', 'innodb', 'innodb', 'innodb');
+ALTER TABLE t1 ADD FOREIGN KEY (f1) REFERENCES t1 (f2) ON DELETE SET NULL;
+START TRANSACTION;
+DELETE FROM t1 where f1='mariadb';
+SELECT * FROM t1;
+ROLLBACK;
+
+ALTER TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f4) ON DELETE CASCADE;
+
+START TRANSACTION;
+DELETE FROM t1 where f3='mariadb';
+SELECT * FROM t1;
+ROLLBACK;
+
+ALTER TABLE t1 ADD FOREIGN KEY (f5) REFERENCES t1 (f6) ON UPDATE SET NULL;
+--error ER_ROW_IS_REFERENCED_2
+UPDATE t1 SET f6='update';
+
+ALTER TABLE t1 ADD FOREIGN KEY (f7) REFERENCES t1 (f8) ON UPDATE CASCADE;
+--error ER_ROW_IS_REFERENCED_2
+UPDATE t1 SET f6='cascade';
+DROP TABLE t1;
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/suite/innodb/t/foreign_key_debug.test b/mysql-test/suite/innodb/t/foreign_key_debug.test
new file mode 100644
index 00000000000..75d05801b5f
--- /dev/null
+++ b/mysql-test/suite/innodb/t/foreign_key_debug.test
@@ -0,0 +1,78 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+--enable_connect_log
+
+#
+# MDEV-16465 Invalid (old?) table or database name or hang in ha_innobase::delete_table and log semaphore wait upon concurrent DDL with foreign keys
+#
+create table t1 (f1 int primary key) engine=innodb;
+create table t2 (f2 int primary key) engine=innodb;
+create table t3 (f3 int primary key, foreign key (f3) references t2(f2)) engine=innodb;
+insert into t1 values (1),(2),(3),(4),(5);
+insert into t2 values (1),(2),(3),(4),(5);
+insert into t3 values (1),(2),(3),(4),(5);
+connect con1,localhost,root;
+set debug_sync='alter_table_before_rename_result_table signal g1 wait_for g2';
+send alter table t2 add constraint foreign key (f2) references t1(f1) on delete cascade on update cascade;
+connection default;
+let $conn=`select connection_id()`;
+set debug_sync='before_execute_sql_command wait_for g1';
+send update t1 set f1 = f1 + 100000 limit 2;
+connect con2,localhost,root;
+let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock' and info like 'update t1 %';
+source include/wait_condition.inc;
+--replace_result $conn UPDATE
+eval kill query $conn;
+disconnect con2;
+connection default;
+error ER_QUERY_INTERRUPTED;
+reap;
+set debug_sync='now signal g2';
+connection con1;
+reap;
+show create table t2;
+disconnect con1;
+connection default;
+select * from t2 where f2 not in (select f1 from t1);
+select * from t3 where f3 not in (select f2 from t2);
+drop table t3;
+drop table t2;
+drop table t1;
+set debug_sync='reset';
+
+--echo #
+--echo # MDEV-16060 - InnoDB: Failing assertion: ut_strcmp(index->name, key->name)
+--echo #
+CREATE TABLE t1 (`pk` INT PRIMARY KEY) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+FLUSH TABLES;
+
+SET debug_sync='alter_table_intermediate_table_created SIGNAL ready WAIT_FOR go';
+send ALTER TABLE t1 ADD FOREIGN KEY(pk) REFERENCES t2(pk) ON UPDATE CASCADE;
+
+connect con1, localhost, root;
+SET debug_sync='now WAIT_FOR ready';
+SET lock_wait_timeout=1; # change to 0 in 10.3
+--error ER_LOCK_WAIT_TIMEOUT
+UPDATE t2 SET pk=10 WHERE pk=1;
+PREPARE stmt FROM 'UPDATE t2 SET pk=10 WHERE pk=1';
+DEALLOCATE PREPARE stmt;
+FLUSH TABLE t2;
+SET debug_sync='now SIGNAL go';
+
+connection default;
+reap;
+
+# Cleanup
+disconnect con1;
+
+connection default;
+SET debug_sync='reset';
+SHOW OPEN TABLES FROM test;
+DROP TABLE t1, t2;
+
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/suite/innodb/t/innodb-64k.test b/mysql-test/suite/innodb/t/innodb-64k.test
index 0498544279b..50dc1535aa6 100644
--- a/mysql-test/suite/innodb/t/innodb-64k.test
+++ b/mysql-test/suite/innodb/t/innodb-64k.test
@@ -2,6 +2,7 @@
# Tests for setting innodb-page-size=64k;
--source include/have_innodb.inc
--source include/have_innodb_64k.inc
+--source include/have_sequence.inc
call mtr.add_suppression("InnoDB: Warning: innodb_page_size has been changed from default value *");
call mtr.add_suppression("InnoDB: Resizing redo log from *");
@@ -650,6 +651,15 @@ COMMIT;
drop table t2;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-19526 heap number overflow
+--echo #
+CREATE TABLE t1(a SMALLINT NOT NULL UNIQUE AUTO_INCREMENT, KEY(a))
+ENGINE=InnoDB;
+INSERT INTO t1 (a) SELECT seq FROM seq_1_to_8191;
+DROP TABLE t1;
+
#
# restore environment to the state it was before this test execution
#
diff --git a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test
index 26367b8e6ae..07c77299451 100644
--- a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test
+++ b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test
@@ -56,6 +56,8 @@ WHERE table_name='innodb_stats_drop_locked';
SELECT table_name FROM mysql.innodb_index_stats
WHERE table_name='innodb_stats_drop_locked';
+DELETE FROM mysql.innodb_index_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
+DELETE FROM mysql.innodb_table_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
--disable_query_log
call mtr.add_suppression("Unable to delete statistics for table test.innodb_stats_drop_locked: Lock wait timeout. They can be deleted later using DELETE FROM mysql.innodb_index_stats WHERE database_name");
--enable_query_log
diff --git a/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test b/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test
new file mode 100644
index 00000000000..2e1391355b9
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_sys_var_valgrind.test
@@ -0,0 +1,70 @@
+--source include/have_innodb.inc
+
+--echo #
+--echo # Bug #29717909 MEMORY LIFETIME OF VARIABLES BETWEEN CHECK AND UPDATE INCORRECTLY MANAGED
+--echo #
+
+#Test innodb_ft_server_stopword_table (global variable)
+select @@innodb_ft_server_stopword_table;
+create table user_stopword_1(value varchar(30)) engine = innodb;
+create table user_stopword_2(value varchar(30)) engine = innodb;
+
+set @blah = 'test/user_stopword_1';
+SET GLOBAL innodb_ft_server_stopword_table= @blah;
+select @@innodb_ft_server_stopword_table;
+
+set @blah = 'test/user_stopword_2';
+SET GLOBAL innodb_ft_server_stopword_table= @blah;
+select @@innodb_ft_server_stopword_table;
+
+SET GLOBAL innodb_ft_server_stopword_table= NULL;
+select @@innodb_ft_server_stopword_table;
+
+SET GLOBAL innodb_ft_server_stopword_table= default;
+select @@innodb_ft_server_stopword_table;
+
+drop table user_stopword_1, user_stopword_2;
+
+#Test innodb_buffer_pool_filename (global variable)
+
+select @@innodb_buffer_pool_filename;
+
+set @blah='hello';
+set global innodb_buffer_pool_filename = @blah;
+select @@innodb_buffer_pool_filename;
+
+set global innodb_buffer_pool_filename="bye";
+select @@innodb_buffer_pool_filename;
+
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_buffer_pool_filename=NULL;
+select @@innodb_buffer_pool_filename;
+
+set global innodb_buffer_pool_filename=default;
+select @@innodb_buffer_pool_filename;
+
+#Test innodb_ft_aux_table (global variable)
+CREATE TABLE t1 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
+(opening_line)) ENGINE=InnoDB;
+
+CREATE TABLE t2 ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx
+(opening_line)) ENGINE=InnoDB;
+
+select @@innodb_ft_aux_table;
+
+set @blah = 'test/t1';
+SET GLOBAL innodb_ft_aux_table = @blah;
+select @@innodb_ft_aux_table;
+
+set @blah = 'test/t2';
+SET GLOBAL innodb_ft_aux_table = @blah;
+
+SET GLOBAL innodb_ft_aux_table = NULL;
+select @@innodb_ft_aux_table;
+
+SET GLOBAL innodb_ft_aux_table =default;
+select @@innodb_ft_aux_table;
+
+drop table t1,t2;
diff --git a/mysql-test/suite/innodb/t/read_only_recover_committed.test b/mysql-test/suite/innodb/t/read_only_recover_committed.test
index 402cbeba1b9..b14aeaee388 100644
--- a/mysql-test/suite/innodb/t/read_only_recover_committed.test
+++ b/mysql-test/suite/innodb/t/read_only_recover_committed.test
@@ -53,6 +53,7 @@ SELECT * FROM t;
UPDATE t SET a=3 WHERE a=1;
--let $restart_parameters= --innodb-read-only
--source include/restart_mysqld.inc
+SET GLOBAL innodb_status_output= @@GLOBAL.innodb_status_output;
--echo # Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.
--echo # In earlier versions, this would return the last committed version
--echo # (empty table)!
diff --git a/mysql-test/suite/innodb_fts/r/basic.result b/mysql-test/suite/innodb_fts/r/basic.result
index ae23b93dc84..749787b8e1c 100644
--- a/mysql-test/suite/innodb_fts/r/basic.result
+++ b/mysql-test/suite/innodb_fts/r/basic.result
@@ -125,6 +125,27 @@ id title body
3 Optimizing MySQL In this tutorial we will show ...
4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
5 MySQL vs. YourSQL In the following database comparison ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+ERROR HY000: Table handler out of memory
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+id title body
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))'
+ IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+ERROR 42000: syntax error, unexpected $end
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+ERROR 42000: syntax error, unexpected $end
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('+ MySQL + (>Well < stands)' IN BOOLEAN MODE);
id title body
diff --git a/mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result b/mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result
index 9f5c1f271fc..43f79241626 100644
--- a/mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result
+++ b/mysql-test/suite/innodb_fts/r/innodb_fts_misc_1.result
@@ -913,4 +913,46 @@ DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
+#
+# InnoDB: Failing assertion: result != FTS_INVALID in
+# fts_trx_row_get_new_state
+#
+SET FOREIGN_KEY_CHECKS=1;
+CREATE TABLE t1 (pk INT PRIMARY KEY,
+f1 VARCHAR(10), f2 VARCHAR(10),
+f3 VARCHAR(10), f4 VARCHAR(10),
+f5 VARCHAR(10), f6 VARCHAR(10),
+f7 VARCHAR(10), f8 VARCHAR(10),
+FULLTEXT(f1), FULLTEXT(f2), FULLTEXT(f3), FULLTEXT(f4),
+FULLTEXT(f5), FULLTEXT(f6), FULLTEXT(f7), FULLTEXT(f8),
+INDEX(f1), INDEX(f2), INDEX(f3), INDEX(f4),
+INDEX(f5), INDEX(f6), INDEX(f7), INDEX(f8)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+(2, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+(3, 'innodb', 'innodb', 'innodb', 'innodb',
+'innodb', 'innodb', 'innodb', 'innodb');
+ALTER TABLE t1 ADD FOREIGN KEY (f1) REFERENCES t1 (f2) ON DELETE SET NULL;
+START TRANSACTION;
+DELETE FROM t1 where f1='mariadb';
+SELECT * FROM t1;
+pk f1 f2 f3 f4 f5 f6 f7 f8
+2 NULL mariadb mariadb mariadb mariadb mariadb mariadb mariadb
+3 innodb innodb innodb innodb innodb innodb innodb innodb
+ROLLBACK;
+ALTER TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f4) ON DELETE CASCADE;
+START TRANSACTION;
+DELETE FROM t1 where f3='mariadb';
+SELECT * FROM t1;
+pk f1 f2 f3 f4 f5 f6 f7 f8
+3 innodb innodb innodb innodb innodb innodb innodb innodb
+ROLLBACK;
+ALTER TABLE t1 ADD FOREIGN KEY (f5) REFERENCES t1 (f6) ON UPDATE SET NULL;
+UPDATE t1 SET f6='update';
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_3` FOREIGN KEY (`f5`) REFERENCES `t1` (`f6`) ON UPDATE SET NULL)
+ALTER TABLE t1 ADD FOREIGN KEY (f7) REFERENCES t1 (f8) ON UPDATE CASCADE;
+UPDATE t1 SET f6='cascade';
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_3` FOREIGN KEY (`f5`) REFERENCES `t1` (`f6`) ON UPDATE SET NULL)
+DROP TABLE t1;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
diff --git a/mysql-test/suite/innodb_fts/r/misc_debug2.result b/mysql-test/suite/innodb_fts/r/misc_debug2.result
new file mode 100644
index 00000000000..e9daa2d6b30
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/r/misc_debug2.result
@@ -0,0 +1,6 @@
+call mtr.add_suppression("InnoDB: Table '.*' tablespace is set as discarded.");
+CREATE TABLE mdev21563(f1 VARCHAR(100), FULLTEXT idx(f1))ENGINE=InnoDB;
+set debug_dbug="+d,fts_instrument_sync_request";
+INSERT INTO mdev21563 VALUES('This is a test');
+ALTER TABLE mdev21563 DISCARD TABLESPACE;
+DROP TABLE mdev21563;
diff --git a/mysql-test/suite/innodb_fts/r/stopword.result b/mysql-test/suite/innodb_fts/r/stopword.result
new file mode 100644
index 00000000000..51ededd675e
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/r/stopword.result
@@ -0,0 +1,735 @@
+call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist.");
+select * from information_schema.innodb_ft_default_stopword;
+value
+a
+about
+an
+are
+as
+at
+be
+by
+com
+de
+en
+for
+from
+how
+i
+in
+is
+it
+la
+of
+on
+or
+that
+the
+this
+to
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
+CREATE TABLE articles (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT (title,body)
+) ENGINE=InnoDB;
+INSERT INTO articles (title,body) VALUES
+('MySQL Tutorial','DBMS stands for DataBase ...') ,
+('How To Use MySQL Well','After you went through a ...'),
+('Optimizing MySQL','In this tutorial we will show ...'),
+('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+('MySQL vs. YourSQL','In the following database comparison ...'),
+('MySQL Security','When configured properly, MySQL ...');
+SELECT * FROM articles WHERE MATCH (title,body)
+AGAINST ('the' IN NATURAL LANGUAGE MODE);
+id title body
+SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table;
+SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword;
+SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table;
+set global innodb_ft_server_stopword_table = "not_defined";
+ERROR 42000: Variable 'innodb_ft_server_stopword_table' can't be set to the value of 'not_defined'
+set global innodb_ft_server_stopword_table = NULL;
+create table user_stopword(value varchar(30)) engine = innodb;
+set global innodb_ft_server_stopword_table = "test/user_stopword";
+drop index title on articles;
+create fulltext index idx on articles(title, body);
+SELECT * FROM articles WHERE MATCH (title,body)
+AGAINST ('the' IN NATURAL LANGUAGE MODE);
+id title body
+5 MySQL vs. YourSQL In the following database comparison ...
+CREATE TABLE articles_2 (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT (title,body)
+) ENGINE=InnoDB;
+INSERT INTO articles_2 (title, body)
+VALUES ('test for stopwords','this is it...');
+SELECT * FROM articles_2 WHERE MATCH (title,body)
+AGAINST ('this' IN NATURAL LANGUAGE MODE);
+id title body
+1 test for stopwords this is it...
+insert into user_stopword values("this");
+CREATE TABLE articles_3 (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT (title,body)
+) ENGINE=InnoDB;
+INSERT INTO articles_3 (title, body)
+VALUES ('test for stopwords','this is it...');
+SELECT * FROM articles_3 WHERE MATCH (title,body)
+AGAINST ('this' IN NATURAL LANGUAGE MODE);
+id title body
+create table user_stopword_session(value varchar(30)) engine = innodb;
+insert into user_stopword_session values("session");
+set session innodb_ft_user_stopword_table="test/user_stopword_session";
+CREATE TABLE articles_4 (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT (title,body)
+) ENGINE=InnoDB;
+INSERT INTO articles_4 (title, body)
+VALUES ('test for session stopwords','this should also be excluded...');
+SELECT * FROM articles_4 WHERE MATCH (title,body)
+AGAINST ('session' IN NATURAL LANGUAGE MODE);
+id title body
+SELECT * FROM articles_4 WHERE MATCH (title,body)
+AGAINST ('this' IN NATURAL LANGUAGE MODE);
+id title body
+1 test for session stopwords this should also be excluded...
+CREATE TABLE articles_5 (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT (title,body)
+) ENGINE=InnoDB;
+INSERT INTO articles_5 (title, body)
+VALUES ('test for session stopwords','this should also be excluded...');
+SELECT * FROM articles_5 WHERE MATCH (title,body)
+AGAINST ('session' IN NATURAL LANGUAGE MODE);
+id title body
+1 test for session stopwords this should also be excluded...
+drop table articles;
+drop table articles_2;
+drop table articles_3;
+drop table articles_4;
+drop table articles_5;
+drop table user_stopword;
+drop table user_stopword_session;
+SET GLOBAL innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=default;
+CREATE TABLE articles (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT `idx` (title,body)
+) ENGINE=InnoDB;
+SHOW CREATE TABLE articles;
+Table Create Table
+articles CREATE TABLE `articles` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `title` varchar(200) DEFAULT NULL,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `idx` (`title`,`body`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO articles (title,body) VALUES
+('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+('when To Use MySQL Well','After that you went through a ...'),
+('where will Optimizing MySQL','In what tutorial we will show ...'),
+('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+('MySQL vs. YourSQL','In the following database comparison ...'),
+('MySQL Security','When configured properly, MySQL ...');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+id title body
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+id title body
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE id = 7;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE id = 7;
+id title body
+7 update the record to see will is indexed or not
+DELETE FROM articles WHERE id = 7;
+SET global innodb_ft_server_stopword_table = NULL;
+SET SESSION innodb_ft_enable_stopword = 0;
+select @@innodb_ft_enable_stopword;
+@@innodb_ft_enable_stopword
+0
+SET global innodb_ft_user_stopword_table = NULL;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+id title body
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+id title body
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE id = 8;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+SELECT * FROM articles WHERE id = 8;
+id title body
+8 update the record to see will is indexed or not
+DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE id = 8;
+id title body
+8 update the record to see will is indexed or not
+DELETE FROM articles WHERE id = 8;
+ALTER TABLE articles DROP INDEX idx;
+SHOW CREATE TABLE articles;
+Table Create Table
+articles CREATE TABLE `articles` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `title` varchar(200) DEFAULT NULL,
+ `body` text,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+ANALYZE TABLE articles;
+Table Op Msg_type Msg_text
+test.articles analyze status OK
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+id title body
+2 when To Use MySQL Well After that you went through a ...
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+1 MySQL from Tutorial DBMS stands for DataBase ...
+6 MySQL Security When configured properly, MySQL ...
+2 when To Use MySQL Well After that you went through a ...
+4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
+5 MySQL vs. YourSQL In the following database comparison ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+id title body
+2 when To Use MySQL Well After that you went through a ...
+3 where will Optimizing MySQL In what tutorial we will show ...
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+id title body
+1 MySQL from Tutorial DBMS stands for DataBase ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+9 the record will not index the , will words
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+id title body
+9 the record will not index the , will words
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT COUNT(*),max(id) FROM articles;
+COUNT(*) max(id)
+7 9
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+9 update the record to see will is indexed or not
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+9 update the record to see will is indexed or not
+DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE id = 9;
+id title body
+DROP TABLE articles;
+SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;
+SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
+SET SESSION innodb_ft_user_stopword_table=default;
+CREATE TABLE articles (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT `idx` (title,body)
+) ENGINE=InnoDB;
+INSERT INTO articles (title,body) VALUES
+('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+('when To Use MySQL Well','After that you went through a ...'),
+('where will Optimizing MySQL','In what tutorial we will show ...'),
+('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+('MySQL vs. YourSQL','In the following database comparison ...'),
+('MySQL Security','When configured properly, MySQL ...');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+create table user_stopword(value varchar(30)) engine = innodb;
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+create table server_stopword(value varchar(30)) engine = innodb;
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+insert into user_stopword values("this"),("will"),("the");
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+insert into server_stopword values("what"),("where");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+DELETE FROM user_stopword;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+insert into user_stopword values("this"),("will"),("the");
+ALTER TABLE articles DROP INDEX idx;
+SET SESSION innodb_ft_enable_stopword = 0;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SET SESSION innodb_ft_enable_stopword = 1;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+SET SESSION innodb_ft_enable_stopword = 1;
+SET SESSION innodb_ft_user_stopword_table = default;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+DROP TABLE articles,user_stopword,server_stopword;
+SET innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=default;
+SET SESSION innodb_ft_user_stopword_table=default;
+CREATE TABLE articles (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT `idx` (title,body)
+) ENGINE=InnoDB;
+SHOW CREATE TABLE articles;
+Table Create Table
+articles CREATE TABLE `articles` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `title` varchar(200) DEFAULT NULL,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `idx` (`title`,`body`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO articles (title,body) VALUES
+('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+('when To Use MySQL Well','After that you went through a ...'),
+('where will Optimizing MySQL','In what tutorial we will show ...'),
+('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+('MySQL vs. YourSQL','In the following database comparison ...'),
+('MySQL Security','When configured properly, MySQL ...');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+create table user_stopword(value varchar(30)) engine = innodb;
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+insert into user_stopword values("mysqld"),("DBMS");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
+id title body
+1 MySQL from Tutorial DBMS stands for DataBase ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
+id title body
+4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
+id title body
+set session innodb_ft_user_stopword_table = default;
+create table server_stopword(value varchar(30)) engine = innodb;
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+insert into server_stopword values("root"),("properly");
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
+id title body
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
+id title body
+4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
+id title body
+6 MySQL Security When configured properly, MySQL ...
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+DELETE FROM user_stopword;
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+DELETE FROM server_stopword;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
+id title body
+4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
+id title body
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
+id title body
+1 MySQL from Tutorial DBMS stands for DataBase ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
+id title body
+4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
+DROP TABLE articles,user_stopword,server_stopword;
+SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=default;
+SET SESSION innodb_ft_user_stopword_table=default;
+CREATE TABLE articles (
+id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+title VARCHAR(200),
+body TEXT,
+FULLTEXT `idx` (title,body)
+) ENGINE=InnoDB;
+SHOW CREATE TABLE articles;
+Table Create Table
+articles CREATE TABLE `articles` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `title` varchar(200) DEFAULT NULL,
+ `body` text,
+ PRIMARY KEY (`id`),
+ FULLTEXT KEY `idx` (`title`,`body`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO articles (title,body) VALUES
+('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+('when To Use MySQL Well','After that you went through a ...'),
+('where will Optimizing MySQL','In what tutorial we will show ...'),
+('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+('MySQL vs. YourSQL','In the following database comparison ...'),
+('MySQL Security','When configured properly, MySQL ...');
+SET SESSION innodb_ft_enable_stopword = 0;
+select @@innodb_ft_enable_stopword;
+@@innodb_ft_enable_stopword
+0
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+"In connection 1"
+select @@innodb_ft_enable_stopword;
+@@innodb_ft_enable_stopword
+1
+ANALYZE TABLE articles;
+Table Op Msg_type Msg_text
+test.articles analyze status OK
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+id title body
+2 when To Use MySQL Well After that you went through a ...
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+1 MySQL from Tutorial DBMS stands for DataBase ...
+6 MySQL Security When configured properly, MySQL ...
+2 when To Use MySQL Well After that you went through a ...
+4 1001 MySQL Tricks 1. Never run mysqld as root. 2. ...
+5 MySQL vs. YourSQL In the following database comparison ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+id title body
+2 when To Use MySQL Well After that you went through a ...
+3 where will Optimizing MySQL In what tutorial we will show ...
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+id title body
+1 MySQL from Tutorial DBMS stands for DataBase ...
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SET SESSION innodb_ft_enable_stopword = 1;
+select @@innodb_ft_enable_stopword;
+@@innodb_ft_enable_stopword
+1
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+id title body
+"In connection default"
+select @@innodb_ft_enable_stopword;
+@@innodb_ft_enable_stopword
+0
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+id title body
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+id title body
+SET SESSION innodb_ft_enable_stopword = 1;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+id title body
+"In connection 1"
+SET SESSION innodb_ft_enable_stopword = 1;
+create table user_stopword(value varchar(30)) engine = innodb;
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+insert into user_stopword values("this"),("will"),("the");
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+"In connection default"
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+id title body
+select @@innodb_ft_user_stopword_table;
+@@innodb_ft_user_stopword_table
+NULL
+create table user_stopword_1(value varchar(30)) engine = innodb;
+set session innodb_ft_user_stopword_table = "test/user_stopword_1";
+insert into user_stopword_1 values("when");
+SET SESSION innodb_ft_enable_stopword = 1;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+id title body
+2 when To Use MySQL Well After that you went through a ...
+6 MySQL Security When configured properly, MySQL ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
+id title body
+2 when To Use MySQL Well After that you went through a ...
+6 MySQL Security When configured properly, MySQL ...
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
+id title body
+"In connection 1"
+SET SESSION innodb_ft_enable_stopword = 1;
+SET SESSION innodb_ft_user_stopword_table=default;
+select @@innodb_ft_user_stopword_table;
+@@innodb_ft_user_stopword_table
+NULL
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+NULL
+create table server_stopword(value varchar(30)) engine = innodb;
+SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword";
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+test/server_stopword
+insert into server_stopword values("when"),("the");
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
+id title body
+"In connection default"
+SET SESSION innodb_ft_enable_stopword = 1;
+SET SESSION innodb_ft_user_stopword_table=default;
+select @@innodb_ft_server_stopword_table;
+@@innodb_ft_server_stopword_table
+test/server_stopword
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+insert into server_stopword values("where"),("will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
+id title body
+3 where will Optimizing MySQL In what tutorial we will show ...
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
+id title body
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
+id title body
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
+id title body
+DROP TABLE articles,user_stopword,user_stopword_1,server_stopword;
+SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
+SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;
diff --git a/mysql-test/suite/innodb_fts/t/basic.test b/mysql-test/suite/innodb_fts/t/basic.test
index 58f36be08a5..3c6d64a6fce 100644
--- a/mysql-test/suite/innodb_fts/t/basic.test
+++ b/mysql-test/suite/innodb_fts/t/basic.test
@@ -99,6 +99,26 @@ SELECT * FROM articles WHERE MATCH (title,body)
SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('+ MySQL - (Well stands)' IN BOOLEAN MODE);
+--error 128
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('(((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('(((((((((((((((((((((((((((((((vs))))))))))))))))))))))))))))))),(((to)))'
+ IN BOOLEAN MODE);
+
+--error ER_PARSE_ERROR
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('((((((((((((((((((((((((((((((((Security)))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+--error ER_PARSE_ERROR
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST
+('(((((((((((((((((((((((((((((((((Security))))))))))))))))))))))))))))))))'
+ IN BOOLEAN MODE);
+
# Test sub-expression boolean search. Find rows contain
# "MySQL" and "Well" or "MySQL" and "stands". But rank the
# doc with "Well" higher, and doc with "stands" lower.
diff --git a/mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test b/mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test
index 6ef0452f4c6..e8a3035ba25 100644
--- a/mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test
+++ b/mysql-test/suite/innodb_fts/t/innodb_fts_misc_1.test
@@ -907,4 +907,46 @@ DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
+--echo #
+--echo # InnoDB: Failing assertion: result != FTS_INVALID in
+--echo # fts_trx_row_get_new_state
+--echo #
+SET FOREIGN_KEY_CHECKS=1;
+CREATE TABLE t1 (pk INT PRIMARY KEY,
+ f1 VARCHAR(10), f2 VARCHAR(10),
+ f3 VARCHAR(10), f4 VARCHAR(10),
+ f5 VARCHAR(10), f6 VARCHAR(10),
+ f7 VARCHAR(10), f8 VARCHAR(10),
+ FULLTEXT(f1), FULLTEXT(f2), FULLTEXT(f3), FULLTEXT(f4),
+ FULLTEXT(f5), FULLTEXT(f6), FULLTEXT(f7), FULLTEXT(f8),
+ INDEX(f1), INDEX(f2), INDEX(f3), INDEX(f4),
+ INDEX(f5), INDEX(f6), INDEX(f7), INDEX(f8)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+ 'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+ (2, 'mariadb', 'mariadb', 'mariadb', 'mariadb',
+ 'mariadb', 'mariadb', 'mariadb', 'mariadb'),
+ (3, 'innodb', 'innodb', 'innodb', 'innodb',
+ 'innodb', 'innodb', 'innodb', 'innodb');
+ALTER TABLE t1 ADD FOREIGN KEY (f1) REFERENCES t1 (f2) ON DELETE SET NULL;
+START TRANSACTION;
+DELETE FROM t1 where f1='mariadb';
+SELECT * FROM t1;
+ROLLBACK;
+
+ALTER TABLE t1 ADD FOREIGN KEY (f3) REFERENCES t1 (f4) ON DELETE CASCADE;
+
+START TRANSACTION;
+DELETE FROM t1 where f3='mariadb';
+SELECT * FROM t1;
+ROLLBACK;
+
+ALTER TABLE t1 ADD FOREIGN KEY (f5) REFERENCES t1 (f6) ON UPDATE SET NULL;
+--error ER_ROW_IS_REFERENCED_2
+UPDATE t1 SET f6='update';
+
+ALTER TABLE t1 ADD FOREIGN KEY (f7) REFERENCES t1 (f8) ON UPDATE CASCADE;
+--error ER_ROW_IS_REFERENCED_2
+UPDATE t1 SET f6='cascade';
+DROP TABLE t1;
+
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
diff --git a/mysql-test/suite/innodb_fts/t/misc_debug2.test b/mysql-test/suite/innodb_fts/t/misc_debug2.test
new file mode 100644
index 00000000000..31c026e3db9
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/t/misc_debug2.test
@@ -0,0 +1,11 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/not_embedded.inc
+call mtr.add_suppression("InnoDB: Table '.*' tablespace is set as discarded.");
+
+CREATE TABLE mdev21563(f1 VARCHAR(100), FULLTEXT idx(f1))ENGINE=InnoDB;
+set debug_dbug="+d,fts_instrument_sync_request";
+INSERT INTO mdev21563 VALUES('This is a test');
+ALTER TABLE mdev21563 DISCARD TABLESPACE;
+--source include/restart_mysqld.inc
+DROP TABLE mdev21563;
diff --git a/mysql-test/suite/innodb_fts/t/stopword.opt b/mysql-test/suite/innodb_fts/t/stopword.opt
new file mode 100644
index 00000000000..d6938c3b1ea
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/t/stopword.opt
@@ -0,0 +1 @@
+--innodb-ft-default-stopword
diff --git a/mysql-test/suite/innodb_fts/t/stopword.test b/mysql-test/suite/innodb_fts/t/stopword.test
new file mode 100644
index 00000000000..5105a6d2fec
--- /dev/null
+++ b/mysql-test/suite/innodb_fts/t/stopword.test
@@ -0,0 +1,657 @@
+# This is the basic function tests for innodb FTS
+
+-- source include/have_innodb.inc
+
+call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table not_defined does not exist.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: user stopword table test/user_stopword_session does not exist.");
+
+select * from information_schema.innodb_ft_default_stopword;
+
+# Create FTS table
+CREATE TABLE articles (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT (title,body)
+ ) ENGINE=InnoDB;
+
+# Insert six rows
+INSERT INTO articles (title,body) VALUES
+ ('MySQL Tutorial','DBMS stands for DataBase ...') ,
+ ('How To Use MySQL Well','After you went through a ...'),
+ ('Optimizing MySQL','In this tutorial we will show ...'),
+ ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+ ('MySQL vs. YourSQL','In the following database comparison ...'),
+ ('MySQL Security','When configured properly, MySQL ...');
+
+# "the" is in the default stopword, it would not be selected
+SELECT * FROM articles WHERE MATCH (title,body)
+ AGAINST ('the' IN NATURAL LANGUAGE MODE);
+
+SET @innodb_ft_server_stopword_table_orig=@@innodb_ft_server_stopword_table;
+SET @innodb_ft_enable_stopword_orig=@@innodb_ft_enable_stopword;
+SET @innodb_ft_user_stopword_table_orig=@@innodb_ft_user_stopword_table;
+
+# Provide user defined stopword table, if not (correctly) defined,
+# it will be rejected
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_ft_server_stopword_table = "not_defined";
+set global innodb_ft_server_stopword_table = NULL;
+
+# Define a correct formated user stopword table
+create table user_stopword(value varchar(30)) engine = innodb;
+
+# The set operation should be successful
+set global innodb_ft_server_stopword_table = "test/user_stopword";
+
+drop index title on articles;
+
+create fulltext index idx on articles(title, body);
+
+# Now we should be able to find "the"
+SELECT * FROM articles WHERE MATCH (title,body)
+ AGAINST ('the' IN NATURAL LANGUAGE MODE);
+
+# Nothing inserted into the default stopword, so essentially
+# nothing get screened. The new stopword could only be
+# effective for table created thereafter
+CREATE TABLE articles_2 (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT (title,body)
+ ) ENGINE=InnoDB;
+
+INSERT INTO articles_2 (title, body)
+ VALUES ('test for stopwords','this is it...');
+
+# Now we can find record with "this"
+SELECT * FROM articles_2 WHERE MATCH (title,body)
+ AGAINST ('this' IN NATURAL LANGUAGE MODE);
+
+# Ok, let's instantiate some value into user supplied stop word
+# table
+insert into user_stopword values("this");
+
+# Ok, let's repeat with the new table again.
+CREATE TABLE articles_3 (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT (title,body)
+ ) ENGINE=InnoDB;
+
+INSERT INTO articles_3 (title, body)
+ VALUES ('test for stopwords','this is it...');
+
+# Now we should NOT find record with "this"
+SELECT * FROM articles_3 WHERE MATCH (title,body)
+ AGAINST ('this' IN NATURAL LANGUAGE MODE);
+
+# Test session level stopword control "innodb_user_stopword_table"
+create table user_stopword_session(value varchar(30)) engine = innodb;
+
+insert into user_stopword_session values("session");
+
+set session innodb_ft_user_stopword_table="test/user_stopword_session";
+
+CREATE TABLE articles_4 (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT (title,body)
+ ) ENGINE=InnoDB;
+
+INSERT INTO articles_4 (title, body)
+ VALUES ('test for session stopwords','this should also be excluded...');
+
+# "session" is excluded
+SELECT * FROM articles_4 WHERE MATCH (title,body)
+ AGAINST ('session' IN NATURAL LANGUAGE MODE);
+
+# But we can find record with "this"
+SELECT * FROM articles_4 WHERE MATCH (title,body)
+ AGAINST ('this' IN NATURAL LANGUAGE MODE);
+
+--connect (con1,localhost,root,,)
+CREATE TABLE articles_5 (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT (title,body)
+ ) ENGINE=InnoDB;
+
+INSERT INTO articles_5 (title, body)
+ VALUES ('test for session stopwords','this should also be excluded...');
+
+# "session" should be found since the stopword table is session specific
+SELECT * FROM articles_5 WHERE MATCH (title,body)
+ AGAINST ('session' IN NATURAL LANGUAGE MODE);
+
+--connection default
+drop table articles;
+drop table articles_2;
+drop table articles_3;
+drop table articles_4;
+drop table articles_5;
+drop table user_stopword;
+drop table user_stopword_session;
+
+SET GLOBAL innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=default;
+
+#---------------------------------------------------------------------------------------
+# Behavior :
+# The stopword is loaded into memory at
+# 1) create fulltext index time,
+# 2) boot server,
+# 3) first time FTs is used
+# So if you already created a FTS index, and then turn off stopword
+# or change stopword table content it won't affect the FTS
+# that already created since the stopword list are already loaded.
+# It will only affect the new FTS index created after you changed
+# the settings.
+
+# Create FTS table
+CREATE TABLE articles (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT `idx` (title,body)
+ ) ENGINE=InnoDB;
+
+SHOW CREATE TABLE articles;
+
+# Insert six rows
+INSERT INTO articles (title,body) VALUES
+ ('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+ ('when To Use MySQL Well','After that you went through a ...'),
+ ('where will Optimizing MySQL','In what tutorial we will show ...'),
+ ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+ ('MySQL vs. YourSQL','In the following database comparison ...'),
+ ('MySQL Security','When configured properly, MySQL ...');
+
+# Case : server_stopword=default
+# Try to Search default stopword from innodb, "where", "will", "what"
+# and "when" are all stopwords
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+# boolean No result expected
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+# no result expected
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+# no result expected
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+# Not going to update as where condition can not find record
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+# Update the record
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE id = 7;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+# Delete will not work as where condition do not return
+DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE id = 7;
+DELETE FROM articles WHERE id = 7;
+
+
+
+# Case : Turn OFF stopword list variable and search stopword on OLD index.
+# disable stopword list
+SET global innodb_ft_server_stopword_table = NULL;
+SET SESSION innodb_ft_enable_stopword = 0;
+select @@innodb_ft_enable_stopword;
+SET global innodb_ft_user_stopword_table = NULL;
+
+# search default stopword with innodb_ft_enable_stopword is OFF.
+# No records expected even though we turned OFF stopwod filtering
+# (refer Behavior (at the top of the test) for explanation )
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+# Not going to update as where condition can not find record
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+# Update the record
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE id = 8;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+SELECT * FROM articles WHERE id = 8;
+# Delete will not work as where condition do not return
+DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE id = 8;
+DELETE FROM articles WHERE id = 8;
+
+# Case : Turn OFF stopword list variable and search stopword on NEW index.
+# Drop index
+ALTER TABLE articles DROP INDEX idx;
+SHOW CREATE TABLE articles;
+
+# Create the FTS index Using Alter Table.
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+
+ANALYZE TABLE articles;
+
+# search default stopword with innodb_ft_enable_stopword is OFF.
+# All records expected as stopwod filtering is OFF and we created
+# new FTS index.
+# (refer Behavior (at the top of the test) for explanation )
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+# Update will succeed.
+UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+
+SELECT COUNT(*),max(id) FROM articles;
+# Update the record - uncommet on fix
+#UPDATE articles SET title = "update the record" , body = 'to see will is indexed or not'
+#WHERE id = 9;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+# Delete will succeed.
+DELETE FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE id = 9;
+
+
+DROP TABLE articles;
+
+SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;
+SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
+SET SESSION innodb_ft_user_stopword_table=default;
+
+# Create FTS table
+CREATE TABLE articles (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT `idx` (title,body)
+ ) ENGINE=InnoDB;
+
+# Insert six rows
+INSERT INTO articles (title,body) VALUES
+ ('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+ ('when To Use MySQL Well','After that you went through a ...'),
+ ('where will Optimizing MySQL','In what tutorial we will show ...'),
+ ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+ ('MySQL vs. YourSQL','In the following database comparison ...'),
+ ('MySQL Security','When configured properly, MySQL ...');
+
+# No records expeced for select
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+# Define a correct formated user stopword table
+create table user_stopword(value varchar(30)) engine = innodb;
+# The set operation should be successful
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+# Define a correct formated server stopword table
+create table server_stopword(value varchar(30)) engine = innodb;
+# The set operation should be successful
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+# Add values into user supplied stop word table
+insert into user_stopword values("this"),("will"),("the");
+
+# Drop existing index and create the FTS index Using Alter Table.
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+
+# Add values into server supplied stop word table
+insert into server_stopword values("what"),("where");
+# Follwoing should return result as server stopword list was empty at create index time
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+
+# Delete stopword from user list
+DELETE FROM user_stopword;
+# Drop existing index and create the FTS index Using Alter Table.
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+# Follwoing should return result even though to server stopword list
+# conatin these words. Session level stopword list takes priority
+# Here user_stopword is set using innodb_ft_user_stopword_table
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+
+# Follwoing should return result as user stopword list was empty at create index time
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+
+# Add values into user supplied stop word table
+insert into user_stopword values("this"),("will"),("the");
+
+# Drop existing index and create the FTS index Using Alter Table.
+ALTER TABLE articles DROP INDEX idx;
+SET SESSION innodb_ft_enable_stopword = 0;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+
+# Session level stopword list takes priority
+SET SESSION innodb_ft_enable_stopword = 1;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+
+# Make user stopword list deafult so as to server stopword list takes priority
+SET SESSION innodb_ft_enable_stopword = 1;
+SET SESSION innodb_ft_user_stopword_table = default;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+
+
+DROP TABLE articles,user_stopword,server_stopword;
+
+# Restore Defaults
+SET innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=default;
+SET SESSION innodb_ft_user_stopword_table=default;
+
+#---------------------------------------------------------------------------------------
+# Create FTS table
+CREATE TABLE articles (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT `idx` (title,body)
+ ) ENGINE=InnoDB;
+
+SHOW CREATE TABLE articles;
+
+# Insert six rows
+INSERT INTO articles (title,body) VALUES
+ ('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+ ('when To Use MySQL Well','After that you went through a ...'),
+ ('where will Optimizing MySQL','In what tutorial we will show ...'),
+ ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+ ('MySQL vs. YourSQL','In the following database comparison ...'),
+ ('MySQL Security','When configured properly, MySQL ...');
+
+# No records expeced for select
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+# Define a correct formated user stopword table
+create table user_stopword(value varchar(30)) engine = innodb;
+# The set operation should be successful
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+insert into user_stopword values("mysqld"),("DBMS");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
+
+
+# Drop existing index and create the FTS index Using Alter Table.
+# user stopword list will take effect.
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
+
+# set user stopword list empty
+set session innodb_ft_user_stopword_table = default;
+# Define a correct formated user stopword table
+create table server_stopword(value varchar(30)) engine = innodb;
+# The set operation should be successful
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+insert into server_stopword values("root"),("properly");
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
+
+
+# set user stopword list empty
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+# The set operation should be successful
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+# user stopword list take effect as its session level
+# Result expected for select
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
+
+# set user stopword list
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+DELETE FROM user_stopword;
+# The set operation should be successful
+set global innodb_ft_server_stopword_table = "test/server_stopword";
+DELETE FROM server_stopword;
+# user stopword list take affect as its session level
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+wha* +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('what');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+root +mysql" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('properly');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+DBMS +mysql" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('mysqld');
+
+DROP TABLE articles,user_stopword,server_stopword;
+
+# Restore Values
+SET SESSION innodb_ft_enable_stopword=@innodb_ft_enable_stopword_orig;
+SET GLOBAL innodb_ft_server_stopword_table=default;
+SET SESSION innodb_ft_user_stopword_table=default;
+
+
+#------------------------------------------------------------------------------
+# FTS stopword list test - check varaibles across sessions
+
+# Create FTS table
+CREATE TABLE articles (
+ id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
+ title VARCHAR(200),
+ body TEXT,
+ FULLTEXT `idx` (title,body)
+ ) ENGINE=InnoDB;
+
+SHOW CREATE TABLE articles;
+
+# Insert six rows
+INSERT INTO articles (title,body) VALUES
+ ('MySQL from Tutorial','DBMS stands for DataBase ...') ,
+ ('when To Use MySQL Well','After that you went through a ...'),
+ ('where will Optimizing MySQL','In what tutorial we will show ...'),
+ ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+ ('MySQL vs. YourSQL','In the following database comparison ...'),
+ ('MySQL Security','When configured properly, MySQL ...');
+
+# session varaible innodb_ft_enable_stopword=0 will take effect for new FTS index
+SET SESSION innodb_ft_enable_stopword = 0;
+select @@innodb_ft_enable_stopword;
+
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+
+
+--echo "In connection 1"
+--connection con1
+select @@innodb_ft_enable_stopword;
+
+ANALYZE TABLE articles;
+
+# result expected as index created before setting innodb_ft_enable_stopword varaible off
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+
+SET SESSION innodb_ft_enable_stopword = 1;
+select @@innodb_ft_enable_stopword;
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+# no result expected turned innodb_ft_enable_stopword is ON
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+
+
+--echo "In connection default"
+--connection default
+select @@innodb_ft_enable_stopword;
+# no result expected as word not indexed from connection 1
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("where will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("when");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST ("what" WITH QUERY EXPANSION);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("whe*" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+what +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+from" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+where +(show what)" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@6' IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"where will"@9' IN BOOLEAN MODE);
+
+INSERT INTO articles(title,body) values ('the record will' , 'not index the , will words');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+
+SET SESSION innodb_ft_enable_stopword = 1;
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+the +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('"the will"@11' IN BOOLEAN MODE);
+
+
+--echo "In connection 1"
+--connection con1
+SET SESSION innodb_ft_enable_stopword = 1;
+# Define a correct formated user stopword table
+create table user_stopword(value varchar(30)) engine = innodb;
+# The set operation should be successful
+set session innodb_ft_user_stopword_table = "test/user_stopword";
+# Add values into user supplied stop word table
+insert into user_stopword values("this"),("will"),("the");
+# Drop existing index and create the FTS index Using Alter Table.
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+# no result expected as innodb_ft_user_stopword_table filter it
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+
+
+--echo "In connection default"
+--connection default
+# no result expected as innodb_ft_user_stopword_table filter it from connection1
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+show +will" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('will');
+select @@innodb_ft_user_stopword_table;
+# Define a correct formated user stopword table
+create table user_stopword_1(value varchar(30)) engine = innodb;
+# The set operation should be successful
+set session innodb_ft_user_stopword_table = "test/user_stopword_1";
+insert into user_stopword_1 values("when");
+SET SESSION innodb_ft_enable_stopword = 1;
+# result expected
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
+# Drop existing index and create the FTS index Using Alter Table.
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+# no result expected
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('when');
+
+--echo "In connection 1"
+--connection con1
+SET SESSION innodb_ft_enable_stopword = 1;
+SET SESSION innodb_ft_user_stopword_table=default;
+select @@innodb_ft_user_stopword_table;
+select @@innodb_ft_server_stopword_table;
+# Define a correct formated server stopword table
+create table server_stopword(value varchar(30)) engine = innodb;
+# The set operation should be successful
+SET GLOBAL innodb_ft_server_stopword_table = "test/server_stopword";
+select @@innodb_ft_server_stopword_table;
+insert into server_stopword values("when"),("the");
+# Drop existing index and create the FTS index Using Alter Table.
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+# no result expected
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
+
+disconnect con1;
+--source include/wait_until_disconnected.inc
+
+--echo "In connection default"
+--connection default
+SET SESSION innodb_ft_enable_stopword = 1;
+SET SESSION innodb_ft_user_stopword_table=default;
+select @@innodb_ft_server_stopword_table;
+# result expected
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
+insert into server_stopword values("where"),("will");
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
+ALTER TABLE articles DROP INDEX idx;
+ALTER TABLE articles ADD FULLTEXT INDEX idx (title,body);
+# no result expected
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+when" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('the');
+SELECT * FROM articles WHERE MATCH(title,body) AGAINST("+will +where" IN BOOLEAN MODE);
+SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('where');
+
+
+DROP TABLE articles,user_stopword,user_stopword_1,server_stopword;
+
+# Restore Values
+SET GLOBAL innodb_ft_user_stopword_table=@innodb_ft_user_stopword_table_orig;
+SET GLOBAL innodb_ft_server_stopword_table=@innodb_ft_server_stopword_table_orig;
diff --git a/mysql-test/suite/maria/encrypt-no-key.result b/mysql-test/suite/maria/encrypt-no-key.result
new file mode 100644
index 00000000000..6745670dfac
--- /dev/null
+++ b/mysql-test/suite/maria/encrypt-no-key.result
@@ -0,0 +1,15 @@
+call mtr.add_suppression('Unknown key id 1. Can''t continue');
+set global aria_encrypt_tables= 1;
+create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
+alter table t1 disable keys;
+insert into t1 values (1,1);
+alter table t1 enable keys;
+ERROR HY000: Unknown key id 1. Can't continue!
+repair table t1 use_frm;
+Table Op Msg_type Msg_text
+test.t1 repair warning Number of rows changed from 0 to 1
+test.t1 repair Error Unknown key id 1. Can't continue!
+test.t1 repair Error Unknown key id 1. Can't continue!
+test.t1 repair status OK
+drop table t1;
+set global aria_encrypt_tables= default;
diff --git a/mysql-test/suite/maria/encrypt-no-key.test b/mysql-test/suite/maria/encrypt-no-key.test
new file mode 100644
index 00000000000..2d586c50695
--- /dev/null
+++ b/mysql-test/suite/maria/encrypt-no-key.test
@@ -0,0 +1,14 @@
+#
+# MDEV-18496 Crash when Aria encryption is enabled but plugin not available
+#
+call mtr.add_suppression('Unknown key id 1. Can''t continue');
+
+set global aria_encrypt_tables= 1;
+create table t1 (pk int primary key, a int, key(a)) engine=aria transactional=1;
+alter table t1 disable keys;
+insert into t1 values (1,1);
+error 192;
+alter table t1 enable keys;
+repair table t1 use_frm;
+drop table t1;
+set global aria_encrypt_tables= default;
diff --git a/mysql-test/suite/mariabackup/huge_lsn.result b/mysql-test/suite/mariabackup/huge_lsn.result
index f2202c20968..b519fb1e961 100644
--- a/mysql-test/suite/mariabackup/huge_lsn.result
+++ b/mysql-test/suite/mariabackup/huge_lsn.result
@@ -17,3 +17,7 @@ SELECT * FROM t;
i
1
DROP TABLE t;
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
diff --git a/mysql-test/suite/mariabackup/huge_lsn.test b/mysql-test/suite/mariabackup/huge_lsn.test
index baf577769c0..9b89530a7f1 100644
--- a/mysql-test/suite/mariabackup/huge_lsn.test
+++ b/mysql-test/suite/mariabackup/huge_lsn.test
@@ -9,6 +9,10 @@ let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
let MYSQLD_DATADIR=`select @@datadir`;
call mtr.add_suppression("InnoDB: New log files created");
+let $targetdir_old=$MYSQLTEST_VARDIR/tmp/backup_1;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir_old;
+--enable_result_log
--source include/shutdown_mysqld.inc
perl;
@@ -52,3 +56,7 @@ exec $XTRABACKUP --prepare --target-dir=$targetdir;
SELECT * FROM t;
DROP TABLE t;
rmdir $targetdir;
+let $targetdir= $targetdir_old;
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+--source include/restart_and_restore.inc
+rmdir $targetdir_old;
diff --git a/mysql-test/suite/parts/r/partition_debug.result b/mysql-test/suite/parts/r/partition_debug.result
index d0efd9d7c2a..0a8b8d20520 100644
--- a/mysql-test/suite/parts/r/partition_debug.result
+++ b/mysql-test/suite/parts/r/partition_debug.result
@@ -1,3 +1,4 @@
+FLUSH TABLES;
#
# Bug#13737949: CRASH IN HA_PARTITION::INDEX_INIT
# Bug#18694052: SERVER CRASH IN HA_PARTITION::INIT_RECORD_PRIORITY_QUEUE
diff --git a/mysql-test/suite/parts/t/partition_debug.test b/mysql-test/suite/parts/t/partition_debug.test
index ef12ee99948..183a9b750d6 100644
--- a/mysql-test/suite/parts/t/partition_debug.test
+++ b/mysql-test/suite/parts/t/partition_debug.test
@@ -8,6 +8,10 @@
# Crash tests don't work with embedded
--source include/not_embedded.inc
+# Make sure system tables are not open, as the test will kill the server
+# and it will cause corruption errors in the log
+FLUSH TABLES;
+
# Partitioning test that require debug features
--echo #
diff --git a/mysql-test/suite/perfschema/t/ddl_esms_by_digest.test b/mysql-test/suite/perfschema/t/ddl_esms_by_digest.test
index cea7ea27299..9cf1775c8e5 100644
--- a/mysql-test/suite/perfschema/t/ddl_esms_by_digest.test
+++ b/mysql-test/suite/perfschema/t/ddl_esms_by_digest.test
@@ -1,13 +1,20 @@
# Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/mysql-test/suite/perfschema/t/dml_esms_by_digest.test b/mysql-test/suite/perfschema/t/dml_esms_by_digest.test
index 88729e6a7a8..b71c6f2815b 100644
--- a/mysql-test/suite/perfschema/t/dml_esms_by_digest.test
+++ b/mysql-test/suite/perfschema/t/dml_esms_by_digest.test
@@ -1,13 +1,20 @@
# Copyright (c) 2009, 2010, 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 Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/mysql-test/suite/roles/drop_current_role.result b/mysql-test/suite/roles/drop_current_role.result
new file mode 100644
index 00000000000..d5eafc6c813
--- /dev/null
+++ b/mysql-test/suite/roles/drop_current_role.result
@@ -0,0 +1,5 @@
+create role r;
+set role r;
+drop role r;
+revoke all on *.* from current_role;
+ERROR OP000: Invalid role specification `r`.
diff --git a/mysql-test/suite/roles/drop_current_role.test b/mysql-test/suite/roles/drop_current_role.test
new file mode 100644
index 00000000000..c8d6fc5d9df
--- /dev/null
+++ b/mysql-test/suite/roles/drop_current_role.test
@@ -0,0 +1,9 @@
+--source include/not_embedded.inc
+#
+# MDEV-22521 Server crashes in traverse_role_graph_up or Assertion `user' fails in traverse_role_graph_impl
+#
+create role r;
+set role r;
+drop role r;
+error ER_INVALID_ROLE;
+revoke all on *.* from current_role;
diff --git a/mysql-test/suite/roles/set_default_role_for.result b/mysql-test/suite/roles/set_default_role_for.result
index 7289319a428..fcea28e882a 100644
--- a/mysql-test/suite/roles/set_default_role_for.result
+++ b/mysql-test/suite/roles/set_default_role_for.result
@@ -14,7 +14,7 @@ set default role role_a for user_a@localhost;
set default role invalid_role for user_a@localhost;
ERROR OP000: Invalid role specification `invalid_role`.
set default role role_b for user_a@localhost;
-ERROR OP000: Invalid role specification `role_b`.
+ERROR OP000: User `user_a@localhost` has not been granted role `role_b`
set default role role_b for user_b@localhost;
show grants;
Grants for user_a@localhost
@@ -36,7 +36,7 @@ user host default_role
user_a localhost role_a
user_b localhost role_b
set default role role_b for current_user;
-ERROR OP000: Invalid role specification `role_b`.
+ERROR OP000: User `user_a@localhost` has not been granted role `role_b`
show grants;
Grants for user_b@localhost
GRANT role_b TO 'user_b'@'localhost'
diff --git a/mysql-test/suite/roles/set_default_role_invalid.result b/mysql-test/suite/roles/set_default_role_invalid.result
index 3916bacfd4c..b6036e8de99 100644
--- a/mysql-test/suite/roles/set_default_role_invalid.result
+++ b/mysql-test/suite/roles/set_default_role_invalid.result
@@ -38,3 +38,90 @@ ERROR 42000: SELECT command denied to user 'test_user'@'localhost' for table 'us
drop role test_role;
drop role not_granted_role;
drop user test_user@localhost;
+#
+# MDEV-22312: Bad error message for SET DEFAULT ROLE when user account
+# is not granted the role
+#
+CREATE USER a;
+CREATE USER b;
+CREATE ROLE r1;
+CREATE ROLE r2;
+SET DEFAULT ROLE r1 FOR a;
+ERROR OP000: User `a@%` has not been granted role `r1`
+GRANT r1 TO b;
+GRANT r2 TO b;
+SET DEFAULT ROLE r1 FOR b;
+# Change user b
+SELECT CURRENT_ROLE;
+CURRENT_ROLE
+r1
+SET ROLE r2;
+SELECT CURRENT_ROLE;
+CURRENT_ROLE
+r2
+SET DEFAULT ROLE r1 FOR a;
+ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
+SET DEFAULT ROLE r2;
+# Change user root (session 1: select_priv to b)
+GRANT SELECT ON mysql.* TO b;
+# Change user b (session 1: select_priv)
+SHOW GRANTS FOR b;
+Grants for b@%
+GRANT r1 TO 'b'@'%'
+GRANT r2 TO 'b'@'%'
+GRANT USAGE ON *.* TO 'b'@'%'
+GRANT SELECT ON `mysql`.* TO 'b'@'%'
+SET DEFAULT ROLE r1 FOR a;
+ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
+SELECT CURRENT_ROLE;
+CURRENT_ROLE
+r2
+SET DEFAULT ROLE NONE;
+SELECT CURRENT_ROLE;
+CURRENT_ROLE
+r2
+SET DEFAULT ROLE current_role FOR current_user;
+SET DEFAULT ROLE invalid_role;
+ERROR OP000: Invalid role specification `invalid_role`.
+SET DEFAULT ROLE invalid_role FOR a;
+ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
+SET DEFAULT ROLE none FOR a;
+ERROR 42000: Access denied for user 'b'@'%' to database 'mysql'
+# Change user root (session 2: adding update_priv to user b)
+GRANT UPDATE ON mysql.* TO b;
+# Change user b
+SHOW GRANTS FOR b;
+Grants for b@%
+GRANT r1 TO 'b'@'%'
+GRANT r2 TO 'b'@'%'
+GRANT USAGE ON *.* TO 'b'@'%'
+GRANT SELECT, UPDATE ON `mysql`.* TO 'b'@'%'
+SET DEFAULT ROLE r1 FOR a;
+ERROR OP000: User `a@%` has not been granted role `r1`
+SET DEFAULT ROLE invalid_role;
+ERROR OP000: Invalid role specification `invalid_role`.
+SET DEFAULT ROLE invalid_role FOR a;
+ERROR OP000: Invalid role specification `invalid_role`.
+SET DEFAULT ROLE none FOR a;
+# Change user root (session 3: Grant role to user a)
+GRANT r1 TO a;
+SET DEFAULT ROLE r1 FOR a;
+# Change user a (verify session 3)
+SELECT CURRENT_ROLE;
+CURRENT_ROLE
+r1
+SET DEFAULT ROLE None;
+# Change user b (session 3: role granted to user a)
+SET DEFAULT ROLE r1 FOR a;
+SET DEFAULT ROLE r2 FOR a;
+ERROR OP000: User `a@%` has not been granted role `r2`
+SET DEFAULT ROLE invalid_role;
+ERROR OP000: Invalid role specification `invalid_role`.
+SET DEFAULT ROLE invalid_role FOR a;
+ERROR OP000: Invalid role specification `invalid_role`.
+SELECT user, host, default_role FROM mysql.user where user='a' or user='b';
+user host default_role
+a % r1
+b % r2
+DROP ROLE r1, r2;
+DROP USER a, b;
diff --git a/mysql-test/suite/roles/set_default_role_invalid.test b/mysql-test/suite/roles/set_default_role_invalid.test
index 8e72e316d4b..02fca1107e2 100644
--- a/mysql-test/suite/roles/set_default_role_invalid.test
+++ b/mysql-test/suite/roles/set_default_role_invalid.test
@@ -60,3 +60,110 @@ change_user 'root';
drop role test_role;
drop role not_granted_role;
drop user test_user@localhost;
+
+--echo #
+--echo # MDEV-22312: Bad error message for SET DEFAULT ROLE when user account
+--echo # is not granted the role
+--echo #
+
+CREATE USER a;
+CREATE USER b;
+CREATE ROLE r1;
+CREATE ROLE r2;
+# Role has not been granted to user a, but the role is visible to current_user
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE r1 FOR a;
+# Granting roles to user b
+GRANT r1 TO b;
+GRANT r2 TO b;
+# After granting the role, role can be set as default
+SET DEFAULT ROLE r1 FOR b;
+
+--echo # Change user b
+change_user b;
+SELECT CURRENT_ROLE;
+SET ROLE r2;
+SELECT CURRENT_ROLE;
+# User b has no UPDATE_PRIV for mysql.user
+--error ER_DBACCESS_DENIED_ERROR
+SET DEFAULT ROLE r1 FOR a;
+SET DEFAULT ROLE r2;
+
+--echo # Change user root (session 1: select_priv to b)
+change_user root;
+# Let's grant select_priv to user b
+GRANT SELECT ON mysql.* TO b;
+
+--echo # Change user b (session 1: select_priv)
+change_user b;
+SHOW GRANTS FOR b;
+# User must have update_priv before setting the role
+--error ER_DBACCESS_DENIED_ERROR
+SET DEFAULT ROLE r1 FOR a;
+# Testing the `CURRENT_ROLE` as a special case
+SELECT CURRENT_ROLE;
+SET DEFAULT ROLE NONE;
+SELECT CURRENT_ROLE;
+SET DEFAULT ROLE current_role FOR current_user;
+# Testing of non-existing role
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE invalid_role;
+# Testing of non-existing role for different user
+--error ER_DBACCESS_DENIED_ERROR
+SET DEFAULT ROLE invalid_role FOR a;
+# Testing the `None` role for different user
+-- error ER_DBACCESS_DENIED_ERROR
+SET DEFAULT ROLE none FOR a;
+
+--echo # Change user root (session 2: adding update_priv to user b)
+change_user root;
+# update_priv are enough
+GRANT UPDATE ON mysql.* TO b;
+
+--echo # Change user b
+change_user b;
+SHOW GRANTS FOR b;
+# In all tests in session user a has not been granted the role
+# Testing setting role for different user, should fail with new error
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE r1 FOR a;
+# Testing of non-existing role
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE invalid_role;
+# Testing of non-existing role for different user with update_priv
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE invalid_role FOR a;
+# Testing the `None` role for different user with update_priv
+SET DEFAULT ROLE none FOR a;
+
+--echo # Change user root (session 3: Grant role to user a)
+change_user root;
+# After granting the privilege for a, user b can set default role
+GRANT r1 TO a;
+SET DEFAULT ROLE r1 FOR a;
+
+--echo # Change user a (verify session 3)
+change_user a;
+SELECT CURRENT_ROLE;
+SET DEFAULT ROLE None;
+
+--echo # Change user b (session 3: role granted to user a)
+change_user b;
+# This should set role because b has update_priv
+SET DEFAULT ROLE r1 FOR a;
+# Testing non-granted role r2 still should fail
+-- error ER_INVALID_ROLE
+SET DEFAULT ROLE r2 FOR a;
+# Testing of non-existing role
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE invalid_role;
+# Testing of non-existing role for different user
+--error ER_INVALID_ROLE
+SET DEFAULT ROLE invalid_role FOR a;
+
+# Clear the workspace
+change_user root;
+--sorted_result
+SELECT user, host, default_role FROM mysql.user where user='a' or user='b';
+DROP ROLE r1, r2;
+DROP USER a, b;
diff --git a/mysql-test/suite/roles/set_role-recursive.result b/mysql-test/suite/roles/set_role-recursive.result
index 9e62558fc14..b0d79377183 100644
--- a/mysql-test/suite/roles/set_role-recursive.result
+++ b/mysql-test/suite/roles/set_role-recursive.result
@@ -66,7 +66,7 @@ Grants for test_user@localhost
GRANT USAGE ON *.* TO 'test_user'@'localhost'
GRANT test_role1 TO 'test_user'@'localhost'
set role test_role2;
-ERROR OP000: Invalid role specification `test_role2`.
+ERROR OP000: User `test_user@localhost` has not been granted role `test_role2`
select current_user(), current_role();
current_user() current_role()
test_user@localhost NULL
diff --git a/mysql-test/suite/rpl/extension/checksum.pl b/mysql-test/suite/rpl/extension/checksum.pl
index f94341446cd..8369d1bbdce 100755
--- a/mysql-test/suite/rpl/extension/checksum.pl
+++ b/mysql-test/suite/rpl/extension/checksum.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result
new file mode 100644
index 00000000000..87ed91ced01
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_binlog_dump_slave_gtid_state_info.result
@@ -0,0 +1,34 @@
+include/master-slave.inc
+[connection master]
+SET GLOBAL LOG_WARNINGS=2;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=current_pos;
+include/start_slave.inc
+"Test Case 1: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('')"
+FOUND /using_gtid\(1\), gtid\(\'\'\)/ in mysqld.1.err
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+include/start_slave.inc
+"Test Case 2: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(0), gtid('')"
+FOUND /using_gtid\(0\), gtid\(\'\'\)/ in mysqld.1.err
+CREATE TABLE t (f INT) ENGINE=INNODB;
+INSERT INTO t VALUES(10);
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+include/start_slave.inc
+"Test Case 3: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2')"
+FOUND /using_gtid\(1\), gtid\(\'0-1-2\'\)/ in mysqld.1.err
+SET @@SESSION.gtid_domain_id=10;
+INSERT INTO t VALUES(20);
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+include/start_slave.inc
+"Test Case 4: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2,10-1-1')"
+FOUND /using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\)/ in mysqld.1.err
+"===== Clean up ====="
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+include/start_slave.inc
+DROP TABLE t;
+SET GLOBAL LOG_WARNINGS=default;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_binlog_errors.result b/mysql-test/suite/rpl/r/rpl_binlog_errors.result
index 72844fb9de6..fead3d128e5 100644
--- a/mysql-test/suite/rpl/r/rpl_binlog_errors.result
+++ b/mysql-test/suite/rpl/r/rpl_binlog_errors.result
@@ -7,6 +7,7 @@ include/stop_slave.inc
call mtr.add_suppression("Can't generate a unique log-filename");
call mtr.add_suppression("Writing one row to the row-based binary log failed.*");
call mtr.add_suppression("Error writing file .*");
+call mtr.add_suppression("Could not use master-bin for logging");
SET @old_debug= @@global.debug;
SELECT repeat('x',8192) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166.data';
SELECT repeat('x',10) INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug_46166-2.data';
diff --git a/mysql-test/suite/rpl/r/rpl_binlog_index.result b/mysql-test/suite/rpl/r/rpl_binlog_index.result
index 6611a9ef2c0..0a53c6f76ee 100644
--- a/mysql-test/suite/rpl/r/rpl_binlog_index.result
+++ b/mysql-test/suite/rpl/r/rpl_binlog_index.result
@@ -3,18 +3,22 @@ include/master-slave.inc
CREATE TABLE t1 (a INT);
FLUSH BINARY LOGS;
INSERT INTO t1 VALUES (1);
+include/stop_slave.inc
# Shutdown master
include/rpl_stop_server.inc [server_number=1]
# Move the master binlog files and the index file to a new place
# Restart master with log-bin option set to the new path
# Master has restarted successfully
+include/start_slave.inc
# Create the master-bin.index file with the old format
+include/stop_slave.inc
# Shutdown master
include/rpl_stop_server.inc [server_number=1]
# Move back the master binlog files
# Remove the unneeded master-bin.index file
# Restart master with log-bin option set to default
# Master has restarted successfully
+include/start_slave.inc
# stop slave
include/stop_slave.inc
include/rpl_stop_server.inc [server_number=2]
diff --git a/mysql-test/suite/rpl/r/rpl_conditional_comments.result b/mysql-test/suite/rpl/r/rpl_conditional_comments.result
index 5668322d4aa..f8ceed3fa36 100644
--- a/mysql-test/suite/rpl/r/rpl_conditional_comments.result
+++ b/mysql-test/suite/rpl/r/rpl_conditional_comments.result
@@ -65,5 +65,20 @@ include/diff_tables.inc [master:t1,slave:t1]
# comments
SELECT c1 FROM /*!999999 t1 WHEREN;
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 '/*!999999 t1 WHEREN' at line 1
+insert t1 values (/*!50505 1 /* foo */ */ + 2);
+insert t1 values (/*!999999 10 /* foo */ */ + 20);
+include/show_binlog_events.inc
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; insert t1 values (/*!50505 1 /* foo */ */ + 2)
+master-bin.000001 # Query # # COMMIT
+master-bin.000001 # Gtid # # BEGIN GTID #-#-#
+master-bin.000001 # Query # # use `test`; insert t1 values (/* 999999 10 (* foo *) */ + 20)
+master-bin.000001 # Query # # COMMIT
+select * from t1;
+c1
+62
+3
+20
DROP TABLE t1;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_fail_register.result b/mysql-test/suite/rpl/r/rpl_fail_register.result
new file mode 100644
index 00000000000..4e433636ad9
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_fail_register.result
@@ -0,0 +1,16 @@
+include/master-slave.inc
+[connection master]
+set @old_dbug=@@global.debug_dbug;
+set global debug_dbug='d,fail_com_register_slave';
+stop slave;
+reset slave;
+include/wait_for_slave_to_stop.inc
+start slave;
+stop slave;
+include/wait_for_slave_to_stop.inc
+set global debug_dbug=@old_dbug;
+kill DUMP_THREAD;
+show slave hosts;
+Server_id Host Port Master_id
+start slave;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result b/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result
index 5a746c88458..9709e24fbde 100644
--- a/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result
+++ b/mysql-test/suite/rpl/r/rpl_filter_tables_dynamic.result
@@ -5,6 +5,8 @@ ERROR HY000: This operation cannot be performed as you have a running slave '';
SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6";
ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first
include/stop_slave.inc
+SET @@GLOBAL.replicate_do_table="";
+SET @@GLOBAL.replicate_ignore_table="";
SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3";
SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6";
include/start_slave.inc
diff --git a/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result b/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result
index 19d8e513e6f..338f4b3bbcf 100644
--- a/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result
+++ b/mysql-test/suite/rpl/r/rpl_filter_wild_tables_dynamic.result
@@ -5,6 +5,8 @@ ERROR HY000: This operation cannot be performed as you have a running slave '';
SET @@GLOBAL.replicate_wild_ignore_table="test.b%";
ERROR HY000: This operation cannot be performed as you have a running slave ''; run STOP SLAVE '' first
include/stop_slave.inc
+SET @@GLOBAL.replicate_wild_do_table="";
+SET @@GLOBAL.replicate_wild_ignore_table="";
SET @@GLOBAL.replicate_wild_do_table="test.a%";
SET @@GLOBAL.replicate_wild_ignore_table="test.b%";
include/start_slave.inc
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_crash.result b/mysql-test/suite/rpl/r/rpl_gtid_crash.result
index 5f67901b7f5..630098b18c9 100644
--- a/mysql-test/suite/rpl/r/rpl_gtid_crash.result
+++ b/mysql-test/suite/rpl/r/rpl_gtid_crash.result
@@ -7,6 +7,9 @@ flush tables;
ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1, 0);
+SET sql_log_bin=0;
+call mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again');
+SET sql_log_bin=1;
include/stop_slave.inc
CHANGE MASTER TO master_host = '127.0.0.1', master_port = MASTER_PORT,
MASTER_USE_GTID=CURRENT_POS;
diff --git a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
index 9e360beba2c..5bc891d90fc 100644
--- a/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
+++ b/mysql-test/suite/rpl/r/rpl_mysql_upgrade.result
@@ -2,12 +2,54 @@ include/master-slave.inc
[connection master]
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
call mtr.add_suppression("table or database name 'mysqltest-1'");
-DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
-CREATE DATABASE `#mysql50#mysqltest-1`;
+CREATE DATABASE `mysqltest-1`;
Master position is not changed
-STOP SLAVE SQL_THREAD;
-include/wait_for_slave_sql_to_stop.inc
-Master position has been changed
+SET @old_general_log_state = @@global.general_log;
+SET @old_slow_log_state = @@global.slow_query_log;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL general_log = 'ON';
+SET GLOBAL slow_query_log = 'ON';
+SET GLOBAL log_output = 'FILE';
+ALTER TABLE mysql.slow_log DROP COLUMN thread_id, DROP COLUMN rows_affected;
DROP DATABASE `mysqltest-1`;
-DROP DATABASE `#mysql50#mysqltest-1`;
+SHOW CREATE TABLE mysql.slow_log;
+Table Create Table
+slow_log CREATE TABLE `slow_log` (
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `user_host` mediumtext NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
+ `rows_sent` int(11) NOT NULL,
+ `rows_examined` int(11) NOT NULL,
+ `db` varchar(512) NOT NULL,
+ `last_insert_id` int(11) NOT NULL,
+ `insert_id` int(11) NOT NULL,
+ `server_id` int(10) unsigned NOT NULL,
+ `sql_text` mediumtext NOT NULL
+) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
+Master position has been changed
+SHOW CREATE TABLE mysql.slow_log;
+Table Create Table
+slow_log CREATE TABLE `slow_log` (
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `user_host` mediumtext NOT NULL,
+ `query_time` time(6) NOT NULL,
+ `lock_time` time(6) NOT NULL,
+ `rows_sent` int(11) NOT NULL,
+ `rows_examined` int(11) NOT NULL,
+ `db` varchar(512) NOT NULL,
+ `last_insert_id` int(11) NOT NULL,
+ `insert_id` int(11) NOT NULL,
+ `server_id` int(10) unsigned NOT NULL,
+ `sql_text` mediumtext NOT NULL,
+ `thread_id` bigint(21) unsigned NOT NULL,
+ `rows_affected` int(11) NOT NULL
+) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
+SET GLOBAL general_log = 'OFF';
+SET GLOBAL slow_query_log = 'OFF';
+truncate mysql.slow_log;
+truncate mysql.general_log;
+SET GLOBAL general_log = @old_general_log_state;
+SET GLOBAL slow_query_log = @old_slow_log_state;
+SET GLOBAL log_output = @old_log_output;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_parallel2.result b/mysql-test/suite/rpl/r/rpl_parallel2.result
index f79661ee6fb..644870475dd 100644
--- a/mysql-test/suite/rpl/r/rpl_parallel2.result
+++ b/mysql-test/suite/rpl/r/rpl_parallel2.result
@@ -1,8 +1,10 @@
include/rpl_init.inc [topology=1->2]
*** MDEV-5509: Incorrect value for Seconds_Behind_Master if parallel replication ***
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+set @old_parallel_mode= @@GLOBAL.slave_parallel_mode;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=5;
+set global slave_parallel_mode= optimistic;
include/start_slave.inc
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave");
@@ -127,6 +129,7 @@ UNLOCK TABLES;
UNLOCK TABLES;
include/stop_slave.inc
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+set global slave_parallel_mode= @old_parallel_mode;
include/start_slave.inc
DROP TABLE t1, t2;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_parallel_optimistic_until.result b/mysql-test/suite/rpl/r/rpl_parallel_optimistic_until.result
new file mode 100644
index 00000000000..d3d1a52d5db
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_parallel_optimistic_until.result
@@ -0,0 +1,238 @@
+include/master-slave.inc
+[connection master]
+include/stop_slave.inc
+RESET MASTER;
+RESET SLAVE;
+RESET MASTER;
+CREATE TABLE t1 (a int primary key, b text) ENGINE=InnoDB;
+INSERT INTO t1 SET a=25, b='trx0';
+include/start_slave.inc
+include/stop_slave.inc
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+SET GLOBAL slave_parallel_threads=2;
+SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode;
+SET GLOBAL slave_parallel_mode='optimistic';
+SET @old_max_relay_log_size = @@global.max_relay_log_size;
+SET @@global.max_relay_log_size=4096;
+BEGIN;
+INSERT INTO t1 SET a=1, b='trx1';
+INSERT INTO t1 SET a=2, b='trx1';
+INSERT INTO t1 SET a=3, b='trx1';
+INSERT INTO t1 SET a=4, b='trx1';
+INSERT INTO t1 SET a=5, b='trx1';
+INSERT INTO t1 SET a=6, b='trx1';
+INSERT INTO t1 SET a=7, b='trx1';
+INSERT INTO t1 SET a=8, b='trx1';
+INSERT INTO t1 SET a=9, b='trx1';
+INSERT INTO t1 SET a=10, b='trx1';
+INSERT INTO t1 SET a=11, b='trx1';
+INSERT INTO t1 SET a=12, b='trx1';
+INSERT INTO t1 SET a=13, b='trx1';
+INSERT INTO t1 SET a=14, b='trx1';
+INSERT INTO t1 SET a=15, b='trx1';
+INSERT INTO t1 SET a=16, b='trx1';
+INSERT INTO t1 SET a=17, b='trx1';
+INSERT INTO t1 SET a=18, b='trx1';
+INSERT INTO t1 SET a=19, b='trx1';
+INSERT INTO t1 SET a=20, b='trx1';
+INSERT INTO t1 SET a=21, b='trx1';
+INSERT INTO t1 SET a=22, b='trx1';
+INSERT INTO t1 SET a=23, b='trx1';
+INSERT INTO t1 SET a=24, b='trx1';
+COMMIT;
+FLUSH LOGS;
+BEGIN;
+UPDATE t1 SET b='trx2_0' WHERE a = 25;
+UPDATE t1 SET b='trx2' WHERE a = 25;
+COMMIT;
+INSERT INTO t1 SET a=26,b='trx3';
+*** case 1 UNTIL inside trx2
+BEGIN;
+INSERT INTO t1 SET a= 1;
+SELECT <pos_0> <= <pos_until> AND <pos_until> < <pos_trx2> as "pos_until < trx0 and is within trx2";
+pos_until < trx0 and is within trx2
+1
+CHANGE MASTER TO MASTER_USE_GTID=no;
+START SLAVE UNTIL MASTER_LOG_FILE = 'file_2', MASTER_LOG_POS = <pos_until>;
+ROLLBACK;
+Proof 1: Correct stop
+include/wait_for_slave_sql_to_stop.inc
+SELECT count(*) = 1 as 'trx2 is committed' FROM t1 WHERE b = 'trx2';
+trx2 is committed
+1
+SELECT count(*) = 0 as 'trx3 is not committed' FROM t1 WHERE b = 'trx3';
+trx3 is not committed
+1
+Proof 2: Resume works out
+include/start_slave.inc
+*** case 2 UNTIL inside trx2
+DELETE FROM t1 WHERE a <> 25;
+UPDATE t1 SET b='trx0' WHERE a = 25;
+BEGIN;
+INSERT INTO t1 SET a= 1;
+include/stop_slave.inc
+SELECT <pos_0> <= <pos_until> AND <pos_until> < <pos_trx2> as "pos_until >= trx0 and is within trx2";
+pos_until >= trx0 and is within trx2
+1
+CHANGE MASTER TO MASTER_LOG_FILE = 'file_1', MASTER_LOG_POS = <pos_trx0>, MASTER_USE_GTID=no;
+START SLAVE UNTIL MASTER_LOG_FILE = 'file_2', MASTER_LOG_POS = <pos_until>;
+ROLLBACK;
+Proof 1: Correct stop
+include/wait_for_slave_sql_to_stop.inc
+SELECT count(*) = 1 as 'trx2 is committed' FROM t1 WHERE b = 'trx2';
+trx2 is committed
+1
+SELECT count(*) = 0 as 'trx3 is not committed' FROM t1 WHERE b = 'trx3';
+trx3 is not committed
+1
+Proof 2: Resume works out
+include/start_slave.inc
+*** case 3 UNTIL inside trx1
+DELETE FROM t1 WHERE a <> 25;
+UPDATE t1 SET b='trx0' WHERE a = 25;
+BEGIN;
+INSERT INTO t1 SET a= 1; # block trx1;
+include/stop_slave.inc
+SELECT <pos_until> < <pos_0> as "pos_until before trx2 start position";
+pos_until before trx2 start position
+1
+CHANGE MASTER TO MASTER_LOG_FILE = 'file_1', MASTER_LOG_POS = <pos_trx0>, MASTER_USE_GTID=no;
+START SLAVE UNTIL MASTER_LOG_FILE = 'file_2', MASTER_LOG_POS = <pos_until>;
+ROLLBACK;
+Proof 1: Correct stop
+include/wait_for_slave_sql_to_stop.inc
+SELECT count(*) = 25-1 as 'trx1 is committed' FROM t1 WHERE b = 'trx1';
+trx1 is committed
+1
+SELECT count(*) = 0 as 'trx2 is not committed' FROM t1 WHERE b = 'trx2';
+trx2 is not committed
+1
+Proof 2: Resume works out
+include/start_slave.inc
+*** case 4 Relay-log UNTIL inside trx1
+DELETE FROM t1 WHERE a <> 25;
+UPDATE t1 SET b='trx0' WHERE a = 25;
+BEGIN;
+INSERT INTO t1 SET a= 1; # block trx1;
+include/stop_slave.inc
+CHANGE MASTER TO MASTER_LOG_FILE = 'file_1', MASTER_LOG_POS = <pos_trx0>, MASTER_USE_GTID=no;
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+START SLAVE UNTIL RELAY_LOG_FILE = 'file_2', RELAY_LOG_POS = <pos_until>;
+ROLLBACK;
+Proof 1: Correct stop
+include/wait_for_slave_sql_to_stop.inc
+SELECT count(*) = 25-1 as 'trx1 is committed' FROM t1 WHERE b = 'trx1';
+trx1 is committed
+1
+SELECT count(*) = 0 as 'trx2 is not committed' FROM t1 WHERE b = 'trx2';
+trx2 is not committed
+1
+Proof 2: Resume works out
+include/start_slave.inc
+*** case 5 Relay-log UNTIL inside a "big" trx that spawns few relay logs
+CREATE TABLE t2 (a TEXT) ENGINE=InnoDB;
+FLUSH LOGS;
+include/stop_slave.inc
+BEGIN;
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+INSERT INTO t2 SET a=repeat('a',1024);
+COMMIT;
+INSERT INTO t2 SET a='a';
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+START SLAVE UNTIL RELAY_LOG_FILE = 'file_2', RELAY_LOG_POS = <pos_until>;
+Proof 1: Correct stop
+include/wait_for_slave_sql_to_stop.inc
+Proof 2: Resume works out
+include/start_slave.inc
+include/diff_tables.inc [master:t2,slave:t2]
+*** case 6 Relay-log UNTIL inside a small trx inside a sequence of relay logs
+include/stop_slave.inc
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+BEGIN;
+DELETE FROM t2 LIMIT 1;
+COMMIT;
+COMMIT;
+START SLAVE IO_THREAD;
+include/wait_for_slave_io_to_start.inc
+include/sync_slave_io_with_master.inc
+START SLAVE UNTIL RELAY_LOG_FILE = 'file_2', RELAY_LOG_POS = <pos_until>;
+Proof 1: Correct stop
+include/wait_for_slave_sql_to_stop.inc
+Proof 2: Resume works out
+include/start_slave.inc
+include/diff_tables.inc [master:t2,slave:t2]
+include/stop_slave.inc
+SET GLOBAL max_relay_log_size=@old_max_relay_log_size;
+SET GLOBAL slave_parallel_mode=@old_parallel_mode;
+SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+include/start_slave.inc
+DROP TABLE t1, t2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test
new file mode 100644
index 00000000000..e2cc4b002cc
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_binlog_dump_slave_gtid_state_info.test
@@ -0,0 +1,121 @@
+# ==== Purpose ====
+#
+# Test verifies that Start binlog_dump message will report GTID position
+# requested by slave when log_warnings > 1.
+#
+# ==== Implementation ====
+#
+# Steps:
+# 0 - Have LOG_WARNINGS=2
+# 1 - On a fresh slave server which has not replicated any GTIDs execute
+# "CHANGE MASTER TO MASTER_USE_GTID=current_pos;" command. Start the
+# slave.
+# 2 - In Master error log verify that pattern "using_gtid(1), gtid('')" is
+# present.
+# 3 - On slave server do STOP SLAVE and execute "CHANGE MASTER TO
+# MASTER_USE_GTID=no;" command. Start the slave threads.
+# 4 - In Master error log verify that pattern "using_gtid(0), gtid('')" is
+# present.
+# 5- Execute a DDL and DML on master server. This will generated two GTIDs
+# on the master server ('0-1-2'). Sync the slave server with master.
+# 6 - On slave do STOP SLAVE and execute "CHANGE MASTER TO
+# MASTER_USE_GTID=slave_pos;" command. Start slave threads.
+# 7 - In Master error verify that pattern "using_gtid(1), gtid('0-1-2')" is
+# present.
+# 8 - On Master change domain ID to 10 and execute a DML operation. It will
+# generate a GTID 10-1-1.
+# 9 - On slave do STOP SLAVE and execute "CHANGE MASTER TO
+# MASTER_USE_GTID=slave_pos;" command. Start slave threads.
+# 10 -In Master error verify that pattern "using_gtid(1),
+# gtid('0-1-2,10-1-1')" is present.
+#
+# ==== References ====
+#
+# MDEV-20428: "Start binlog_dump" message doesn't indicate GTID position
+#
+
+--source include/have_binlog_format_mixed.inc
+--source include/have_innodb.inc
+--source include/master-slave.inc
+
+--connection master
+SET GLOBAL LOG_WARNINGS=2;
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=current_pos;
+--source include/start_slave.inc
+
+--connection master
+# Check error log for correct messages.
+let $log_error_= `SELECT @@GLOBAL.log_error`;
+if(!$log_error_)
+{
+ # MySQL Server on windows is started with --console and thus
+ # does not know the location of its .err log, use default location
+ let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.1.err;
+}
+--echo "Test Case 1: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'\'\)
+--source include/search_pattern_in_file.inc
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+--source include/start_slave.inc
+
+--connection master
+--echo "Test Case 2: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(0), gtid('')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(0\), gtid\(\'\'\)
+--source include/search_pattern_in_file.inc
+CREATE TABLE t (f INT) ENGINE=INNODB;
+INSERT INTO t VALUES(10);
+save_master_pos;
+
+--connection slave
+sync_with_master;
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+--source include/start_slave.inc
+
+--connection master
+--echo "Test Case 3: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2\'\)
+--source include/search_pattern_in_file.inc
+SET @@SESSION.gtid_domain_id=10;
+INSERT INTO t VALUES(20);
+save_master_pos;
+
+--connection slave
+sync_with_master;
+
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=slave_pos;
+--source include/start_slave.inc
+
+--connection master
+--echo "Test Case 4: Start binlog_dump to slave_server(#), pos(master-bin.000001, ###), using_gtid(1), gtid('0-1-2,10-1-1')"
+--let SEARCH_FILE=$log_error_
+--let SEARCH_RANGE=-50000
+--let SEARCH_PATTERN=using_gtid\(1\), gtid\(\'0-1-2,10-1-1\'\)
+--source include/search_pattern_in_file.inc
+
+--echo "===== Clean up ====="
+--connection slave
+--source include/stop_slave.inc
+CHANGE MASTER TO MASTER_USE_GTID=no;
+--source include/start_slave.inc
+
+--connection master
+DROP TABLE t;
+SET GLOBAL LOG_WARNINGS=default;
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_binlog_index.test b/mysql-test/suite/rpl/t/rpl_binlog_index.test
index 8586b1d7489..95c49c3d574 100644
--- a/mysql-test/suite/rpl/t/rpl_binlog_index.test
+++ b/mysql-test/suite/rpl/t/rpl_binlog_index.test
@@ -43,7 +43,7 @@ FLUSH BINARY LOGS;
INSERT INTO t1 VALUES (1);
sync_slave_with_master;
-
+--source include/stop_slave.inc
#
# Test on master
#
@@ -58,13 +58,15 @@ source include/rpl_stop_server.inc;
--move_file $master_datadir/master-bin.index $tmpdir/master-bin.index
--echo # Restart master with log-bin option set to the new path
---let $rpl_server_parameters=--log-bin=$tmpdir/master-bin
+--let $rpl_server_parameters=--log-bin=$tmpdir/master-bin --log-bin-index=$tmpdir/master-bin
--let $keep_include_silent=1
source include/rpl_start_server.inc;
--let $keep_include_silent=0
--echo # Master has restarted successfully
-
+--connection slave
+--source include/start_slave.inc
+--connection master
#
# Test master can handle old format with directory path in index file
#
@@ -85,7 +87,10 @@ if (!$is_windows)
--disable_query_log
source include/write_var_to_file.inc;
--enable_query_log
+--sync_slave_with_master
+--source include/stop_slave.inc
+--connection master
--echo # Shutdown master
--let $rpl_server_number=1
source include/rpl_stop_server.inc;
@@ -99,14 +104,17 @@ source include/rpl_stop_server.inc;
--remove_file $tmpdir/master-bin.index
--echo # Restart master with log-bin option set to default
---let $rpl_server_parameters=--log-bin=$master_datadir/master-bin
+--let $rpl_server_parameters=--log-bin=$master_datadir/master-bin --log-bin-index=$master_datadir/master-bin
--let $keep_include_silent=1
source include/rpl_start_server.inc;
--let $keep_include_silent=0
--echo # Master has restarted successfully
+--connection slave
+--source include/start_slave.inc
-connection slave;
+--connection master
+--sync_slave_with_master
--echo # stop slave
--source include/stop_slave.inc
--let $rpl_server_number= 2
diff --git a/mysql-test/suite/rpl/t/rpl_conditional_comments.test b/mysql-test/suite/rpl/t/rpl_conditional_comments.test
index bcc964a92c7..6e4ec8745f4 100644
--- a/mysql-test/suite/rpl/t/rpl_conditional_comments.test
+++ b/mysql-test/suite/rpl/t/rpl_conditional_comments.test
@@ -68,7 +68,17 @@ sync_slave_with_master;
--echo # comments
--connection master
--error 1064
-SELECT c1 FROM /*!999999 t1 WHEREN;
+SELECT c1 FROM /*!999999 t1 WHEREN; #*/
+
+#
+# Bug#28388217 - SERVER CAN FAIL WHILE REPLICATING CONDITIONAL COMMENTS
+#
+insert t1 values (/*!50505 1 /* foo */ */ + 2);
+insert t1 values (/*!999999 10 /* foo */ */ + 20);
+source include/show_binlog_events.inc;
+sync_slave_with_master;
+select * from t1;
+connection master;
DROP TABLE t1;
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_fail_register.test b/mysql-test/suite/rpl/t/rpl_fail_register.test
new file mode 100644
index 00000000000..3a37cc08f44
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_fail_register.test
@@ -0,0 +1,32 @@
+source include/have_debug.inc;
+source include/have_binlog_format_mixed.inc;
+source include/master-slave.inc;
+
+connection slave;
+
+set @old_dbug=@@global.debug_dbug;
+set global debug_dbug='d,fail_com_register_slave';
+
+stop slave;
+reset slave;
+source include/wait_for_slave_to_stop.inc;
+start slave;
+stop slave;
+source include/wait_for_slave_to_stop.inc;
+set global debug_dbug=@old_dbug;
+
+connection master;
+
+let $id=`SELECT id from information_schema.processlist where command='Binlog Dump'`;
+if ($id) {
+ replace_result $id DUMP_THREAD;
+ eval kill $id;
+ let $wait_condition= SELECT count(*)=0 from information_schema.processlist where command='Killed';
+ source include/wait_condition.inc;
+}
+
+show slave hosts;
+
+connection slave;
+start slave;
+source include/rpl_end.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test b/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test
index 97ecc167356..ebededc36b3 100644
--- a/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test
+++ b/mysql-test/suite/rpl/t/rpl_filter_tables_dynamic.test
@@ -51,6 +51,8 @@ SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6";
connection slave;
source include/stop_slave.inc;
+SET @@GLOBAL.replicate_do_table="";
+SET @@GLOBAL.replicate_ignore_table="";
SET @@GLOBAL.replicate_do_table="test.t1,test.t2,test.t3";
SET @@GLOBAL.replicate_ignore_table="test.t4,test.t5,test.t6";
source include/start_slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test b/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test
index c822c81f270..09db91aa4d3 100644
--- a/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test
+++ b/mysql-test/suite/rpl/t/rpl_filter_wild_tables_dynamic.test
@@ -13,6 +13,8 @@ SET @@GLOBAL.replicate_wild_ignore_table="test.b%";
connection slave;
source include/stop_slave.inc;
+SET @@GLOBAL.replicate_wild_do_table="";
+SET @@GLOBAL.replicate_wild_ignore_table="";
SET @@GLOBAL.replicate_wild_do_table="test.a%";
SET @@GLOBAL.replicate_wild_ignore_table="test.b%";
source include/start_slave.inc;
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test
index b81cbd38cd3..84bf76501d8 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test
@@ -21,6 +21,9 @@ INSERT INTO t1 VALUES (1, 0);
--connection server_2
--sync_with_master
+SET sql_log_bin=0;
+call mtr.add_suppression('Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again');
+SET sql_log_bin=1;
--source include/stop_slave.inc
--replace_result $MASTER_MYPORT MASTER_PORT
eval CHANGE MASTER TO master_host = '127.0.0.1', master_port = $MASTER_MYPORT,
diff --git a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
index 1931e2eab2a..f44c883ef4e 100644
--- a/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
+++ b/mysql-test/suite/rpl/t/rpl_mysql_upgrade.test
@@ -14,8 +14,7 @@ call mtr.add_suppression("table or database name 'mysqltest-1'");
connection master;
--disable_warnings
-DROP DATABASE IF EXISTS `#mysql50#mysqltest-1`;
-CREATE DATABASE `#mysql50#mysqltest-1`;
+CREATE DATABASE `mysqltest-1`;
--enable_warnings
sync_slave_with_master;
@@ -34,13 +33,25 @@ if ($before_position == $after_position)
echo Master position is not changed;
}
-#Some log events of the mysql_upgrade's will cause errors on slave.
+# Some log events of the mysql_upgrade previously caused errors on slave,
+# however with MDEV-4851 this should be ok, so we test it:
connection slave;
-STOP SLAVE SQL_THREAD;
-source include/wait_for_slave_sql_to_stop.inc;
+SET @old_general_log_state = @@global.general_log;
+SET @old_slow_log_state = @@global.slow_query_log;
+SET @old_log_output = @@global.log_output;
+SET GLOBAL general_log = 'ON';
+SET GLOBAL slow_query_log = 'ON';
+SET GLOBAL log_output = 'FILE';
connection master;
#With '--force' option, mysql_upgrade always executes all sql statements for upgrading.
+ALTER TABLE mysql.slow_log DROP COLUMN thread_id, DROP COLUMN rows_affected;
+DROP DATABASE `mysqltest-1`;
+sync_slave_with_master;
+
+connection slave;
+SHOW CREATE TABLE mysql.slow_log;
+connection master;
--exec $MYSQL_UPGRADE --skip-verbose --write-binlog --force --user=root > $MYSQLTEST_VARDIR/log/mysql_upgrade.log 2>&1
let $datadir= `select @@datadir`;
@@ -55,8 +66,15 @@ if ($before_position != $after_position)
echo Master position has been changed;
}
-DROP DATABASE `mysqltest-1`;
+sync_slave_with_master;
connection slave;
-DROP DATABASE `#mysql50#mysqltest-1`;
---let $rpl_only_running_threads= 1
+SHOW CREATE TABLE mysql.slow_log;
+SET GLOBAL general_log = 'OFF';
+SET GLOBAL slow_query_log = 'OFF';
+truncate mysql.slow_log;
+truncate mysql.general_log;
+SET GLOBAL general_log = @old_general_log_state;
+SET GLOBAL slow_query_log = @old_slow_log_state;
+SET GLOBAL log_output = @old_log_output;
+
--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_parallel2.test b/mysql-test/suite/rpl/t/rpl_parallel2.test
index 3a9c801175f..8934b15e546 100644
--- a/mysql-test/suite/rpl/t/rpl_parallel2.test
+++ b/mysql-test/suite/rpl/t/rpl_parallel2.test
@@ -8,8 +8,10 @@
--connection server_2
SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+set @old_parallel_mode= @@GLOBAL.slave_parallel_mode;
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads=5;
+set global slave_parallel_mode= optimistic;
--source include/start_slave.inc
--connection server_1
@@ -219,6 +221,7 @@ UNLOCK TABLES;
--connection server_2
--source include/stop_slave.inc
SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+set global slave_parallel_mode= @old_parallel_mode;
--source include/start_slave.inc
--connection server_1
diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test
new file mode 100644
index 00000000000..9e42fae8464
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_until.test
@@ -0,0 +1,466 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/master-slave.inc
+# Format is restricted because the test expects a specific result of
+# relay-logging that splits a transaction into two different files.
+--source include/have_binlog_format_row.inc
+
+#
+# MDEV-15152 Optimistic parallel slave doesn't cope well with START SLAVE UNTIL
+#
+--connection slave
+--source include/stop_slave.inc
+RESET MASTER;
+RESET SLAVE;
+
+--connection master
+RESET MASTER;
+CREATE TABLE t1 (a int primary key, b text) ENGINE=InnoDB;
+--let $a0 = 25
+--eval INSERT INTO t1 SET a=$a0, b='trx0'
+# Memorize the position for replication restart from it
+--let $pos_trx0 = query_get_value(SHOW MASTER STATUS, Position, 1)
+
+--connection slave
+--source include/start_slave.inc
+
+--connection master
+# --connection slave
+--sync_slave_with_master
+--source include/stop_slave.inc
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+SET GLOBAL slave_parallel_threads=2;
+SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode;
+SET GLOBAL slave_parallel_mode='optimistic';
+
+# Run the slave in the following modes one by one.
+#
+# 1. the until position is set in the middle of trx2
+# below $pos_trx0 of the last exec position in the first file
+# 2. and above $pos_trx0
+# In either case trx2 must commit before slave stops.
+# 3. the until postion is inside trx1
+# 4. RELAY log until inside trx1
+# 5. RELAY log until inside a "big" trx
+# 6. RELAY log until inside a trx within a sequence of relay logs
+#
+# Execution flaw for Until_Master_Pos cases follows as:
+# create the transaction trx1, trx2
+# logged at the beginning of two subsequent binlog files.
+# Set the until position to at the middle of the 2rd transaction.
+# Engage the optimistic scheduler while having trx1 execution blocked.
+# Lift the block after trx2 has reached waiting its order to commit.
+# *Proof 1*
+# Observe that the slave applier stops at a correct position.
+# In the bug condition it would stop prematurely having the stop position
+# in the first file, therefore trx2 not committed.
+# Specifically, an internal transaction position until makes the applier to run
+# beyond it to commit commit the current transaction.
+# *Proof 2*
+# Observe the following START SLAVE resumes OK.
+#
+# Auxiliary third trx3 on master is just for triggering the actual stop
+# (whihc is a legacy UNTIL's property).
+# trx0 is to produce a specific value of the last executed binlog file:pos
+# to emulate the bug condition.
+#
+# Intermediate checks via SELECT are supposed to succeed
+# with putting out value 1.
+#
+# NOTE: Relay log until tests have to use explicit log names and position
+# which may require to adjust with future changes to event formats etc.
+#
+
+--connection slave
+SET @old_max_relay_log_size = @@global.max_relay_log_size;
+SET @@global.max_relay_log_size=4096;
+
+--connection master
+# trx1
+--let $a=1
+BEGIN;
+while (`SELECT $a < $a0`)
+{
+ --eval INSERT INTO t1 SET a=$a, b='trx1'
+--inc $a
+}
+COMMIT;
+--let $fil_1 = query_get_value(SHOW MASTER STATUS, File, 1)
+--let $pos_trx1 = query_get_value(SHOW MASTER STATUS, Position, 1)
+
+FLUSH LOGS;
+
+# $pos_0 the offset of the first event of trx2 in new file
+--let $pos_0=query_get_value(SHOW MASTER STATUS, Position, 1)
+# trx2
+--let $a=$a0
+BEGIN;
+--eval UPDATE t1 SET b='trx2_0' WHERE a = $a
+--eval UPDATE t1 SET b='trx2' WHERE a = $a
+COMMIT;
+--let $fil_2=query_get_value(SHOW MASTER STATUS, File, 1)
+--let $pos_trx2=query_get_value(SHOW MASTER STATUS, Position, 1)
+
+# trx3
+--let $a=$a0
+--inc $a
+--eval INSERT INTO t1 SET a=$a,b='trx3'
+--let $pos_trx3=query_get_value(SHOW MASTER STATUS, Position, 1)
+--let $a=
+
+
+--echo *** case 1 UNTIL inside trx2
+
+--connection slave1
+# Blocker to hold off EXEC_MASTER_LOG_POS advance
+BEGIN;
+ --eval INSERT INTO t1 SET a= 1
+--connection slave
+--let $pos_until=`SELECT $pos_trx0 - 1`
+--replace_result $pos_0 <pos_0> $pos_until <pos_until> $pos_trx2 <pos_trx2>
+--eval SELECT $pos_0 <= $pos_until AND $pos_until < $pos_trx2 as "pos_until < trx0 and is within trx2"
+CHANGE MASTER TO MASTER_USE_GTID=no;
+--replace_result $fil_2 file_2 $pos_until <pos_until>
+--eval START SLAVE UNTIL MASTER_LOG_FILE = '$fil_2', MASTER_LOG_POS = $pos_until
+
+--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit"
+--source include/wait_condition.inc
+
+--connection slave1
+# unblock to see the slave applier stops at $until
+ROLLBACK;
+
+--echo Proof 1: Correct stop
+--connection slave
+--source include/wait_for_slave_sql_to_stop.inc
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1)
+if (`SELECT "$file_stop" != "$fil_2" OR $pos_stop < $pos_until`)
+{
+ --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $fil_2:$pos_until.
+ --die
+}
+--eval SELECT count(*) = 1 as 'trx2 is committed' FROM t1 WHERE b = 'trx2'
+--eval SELECT count(*) = 0 as 'trx3 is not committed' FROM t1 WHERE b = 'trx3'
+
+--echo Proof 2: Resume works out
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+
+
+--echo *** case 2 UNTIL inside trx2
+
+--connection slave
+--eval DELETE FROM t1 WHERE a <> $a0
+--eval UPDATE t1 SET b='trx0' WHERE a = $a0
+
+--connection slave1
+# Blocker to hold off EXEC_MASTER_LOG_POS advance
+BEGIN;
+ --eval INSERT INTO t1 SET a= 1
+
+--connection slave
+--source include/stop_slave.inc
+
+--let $pos_until=`SELECT $pos_trx2 - 1`
+--replace_result $pos_trx0 <pos_0> $pos_until <pos_until> $pos_trx2 <pos_trx2>
+--eval SELECT $pos_trx0 <= $pos_until AND $pos_until < $pos_trx2 as "pos_until >= trx0 and is within trx2"
+--replace_result $fil_1 file_1 $pos_trx0 <pos_trx0>
+--eval CHANGE MASTER TO MASTER_LOG_FILE = '$fil_1', MASTER_LOG_POS = $pos_trx0, MASTER_USE_GTID=no
+--replace_result $fil_2 file_2 $pos_until <pos_until>
+--eval START SLAVE UNTIL MASTER_LOG_FILE = '$fil_2', MASTER_LOG_POS = $pos_until
+
+--let $wait_condition= SELECT COUNT(*) > 0 FROM information_schema.processlist WHERE state = "Waiting for prior transaction to commit"
+--source include/wait_condition.inc
+
+--connection slave1
+# unblock to see the slave applier stops at $until
+ROLLBACK;
+
+--echo Proof 1: Correct stop
+--connection slave
+--source include/wait_for_slave_sql_to_stop.inc
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1)
+if (`SELECT "$file_stop" != "$fil_2" OR $pos_stop < $pos_until`)
+{
+ --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $fil_2:$pos_until.
+ --die
+}
+--eval SELECT count(*) = 1 as 'trx2 is committed' FROM t1 WHERE b = 'trx2'
+--eval SELECT count(*) = 0 as 'trx3 is not committed' FROM t1 WHERE b = 'trx3'
+
+--echo Proof 2: Resume works out
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+
+
+--echo *** case 3 UNTIL inside trx1
+
+--connection slave
+--eval DELETE FROM t1 WHERE a <> $a0
+--eval UPDATE t1 SET b='trx0' WHERE a = $a0
+
+
+--connection slave1
+# Blocker to hold off EXEC_MASTER_LOG_POS advance
+BEGIN;
+ --eval INSERT INTO t1 SET a= 1; # block trx1
+
+--connection slave
+--source include/stop_slave.inc
+
+--let $pos_until=`SELECT $pos_0 - 1`
+--replace_result $pos_0 <pos_0> $pos_until <pos_until> $pos_trx2 <pos_trx2>
+--eval SELECT $pos_until < $pos_0 as "pos_until before trx2 start position"
+--replace_result $fil_1 file_1 $pos_trx0 <pos_trx0>
+--eval CHANGE MASTER TO MASTER_LOG_FILE = '$fil_1', MASTER_LOG_POS = $pos_trx0, MASTER_USE_GTID=no
+--replace_result $fil_2 file_2 $pos_until <pos_until>
+--eval START SLAVE UNTIL MASTER_LOG_FILE = '$fil_2', MASTER_LOG_POS = $pos_until
+
+--connection slave1
+# unblock to see the slave applier stops at $until
+ROLLBACK;
+
+--echo Proof 1: Correct stop
+--connection slave
+--source include/wait_for_slave_sql_to_stop.inc
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1)
+if (`SELECT "$file_stop" != "$fil_2" OR $pos_stop < $pos_until`)
+{
+ --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $fil_2:$pos_until.
+ --die
+}
+--eval SELECT count(*) = $a0-1 as 'trx1 is committed' FROM t1 WHERE b = 'trx1'
+--eval SELECT count(*) = 0 as 'trx2 is not committed' FROM t1 WHERE b = 'trx2'
+
+--echo Proof 2: Resume works out
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+
+
+--echo *** case 4 Relay-log UNTIL inside trx1
+
+--connection slave
+--eval DELETE FROM t1 WHERE a <> $a0
+--eval UPDATE t1 SET b='trx0' WHERE a = $a0
+
+--connection slave1
+# Blocker to hold off EXEC_MASTER_LOG_POS advance
+BEGIN;
+ --eval INSERT INTO t1 SET a= 1; # block trx1
+
+--connection slave
+--source include/stop_slave.inc
+--replace_result $fil_1 file_1 $pos_trx0 <pos_trx0>
+--eval CHANGE MASTER TO MASTER_LOG_FILE = '$fil_1', MASTER_LOG_POS = $pos_trx0, MASTER_USE_GTID=no
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+# The following test sets the stop coordinate is set to inside the first event
+# of a relay log that holds events of a transaction started in an earlier log.
+# Peek the stop position in the middle of trx1 (Xid event is here)
+# whose last event follow it
+--let $pos_until=2568
+--let $file_rl=slave-relay-bin.000002
+--let $binlog_file=$file_rl
+--let $info= query_get_value(SHOW RELAYLOG EVENTS IN '$file_rl' FROM $pos_until LIMIT 1, Info, 1)
+
+if (`SELECT "$info" NOT LIKE "COMMIT /* xid=% */"`)
+{
+ --echo *** Unexpected offset. Refine it to point to the correct XID event!
+ --die
+}
+
+# Complicate the test to screw the coordinate away from event boundary.
+--dec $pos_until
+--replace_result $file_rl file_2 $pos_until <pos_until>
+--eval START SLAVE UNTIL RELAY_LOG_FILE = '$file_rl', RELAY_LOG_POS = $pos_until
+
+--connection slave1
+# unblock to see the slave applier stops at $until
+ROLLBACK;
+
+--echo Proof 1: Correct stop
+--connection slave
+--source include/wait_for_slave_sql_to_stop.inc
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1)
+if (`SELECT strcmp("$file_rl","$file_stop") > -1`)
+{
+ --echo *** ERROR: Slave stopped at $file_stop:$pos_stop which is not $file_rl:$pos_until.
+ --die
+}
+
+--eval SELECT count(*) = $a0-1 as 'trx1 is committed' FROM t1 WHERE b = 'trx1'
+--eval SELECT count(*) = 0 as 'trx2 is not committed' FROM t1 WHERE b = 'trx2'
+
+--echo Proof 2: Resume works out
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+
+
+
+--echo *** case 5 Relay-log UNTIL inside a "big" trx that spawns few relay logs
+
+--connection master
+CREATE TABLE t2 (a TEXT) ENGINE=InnoDB;
+FLUSH LOGS;
+
+--sync_slave_with_master
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1)
+--let $records=`SELECT floor(4*@@global.max_relay_log_size / 1024) + 1`
+
+--connection slave
+--source include/stop_slave.inc
+
+--connection master
+# trx4
+BEGIN;
+--let $i=$records
+while ($i)
+{
+ INSERT INTO t2 SET a=repeat('a',1024);
+
+--dec $i
+}
+COMMIT;
+
+# slave will stop there:
+--let $file_trx4 = query_get_value(SHOW MASTER STATUS, File, 1)
+--let $pos_trx4 = query_get_value(SHOW MASTER STATUS, Position, 1)
+
+# trx5
+INSERT INTO t2 SET a='a';
+--let $pos_trx5 = query_get_value(SHOW MASTER STATUS, Position, 1)
+
+--connection slave
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+# Set position inside the transaction though the value
+# specified is beyond that relay log file.
+# The coordianate may point to in a different event in future changes
+# but should not move away from inside this big group of events.
+# So we don't test which event in the transaction it points to.
+--let $pos_until= 4500
+--let $file_rl= slave-relay-bin.000010
+
+--replace_result $file_rl file_2 $pos_until <pos_until>
+--eval START SLAVE UNTIL RELAY_LOG_FILE = '$file_rl', RELAY_LOG_POS = $pos_until
+
+--echo Proof 1: Correct stop
+--connection slave
+--source include/wait_for_slave_sql_to_stop.inc
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Master_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1)
+# It's showed the actual stop occurred before trx5
+if (`SELECT strcmp("$file_trx4", "$file_stop") <> 0 OR $pos_stop >= $pos_trx5 OR count(*) <> $records FROM t2`)
+{
+ --echo *** ERROR: Slave stopped at *binlog* $file_stop:$pos_stop which is not $file_trx4:$pos_trx4.
+ --die
+}
+
+--echo Proof 2: Resume works out
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+
+--let $diff_tables=master:t2,slave:t2
+--source include/diff_tables.inc
+
+
+
+--echo *** case 6 Relay-log UNTIL inside a small trx inside a sequence of relay logs
+
+--connection slave
+--source include/stop_slave.inc
+
+--connection master
+# trx6
+--let $records=`SELECT count(*) FROM t2`
+while ($records)
+{
+ BEGIN;
+ DELETE FROM t2 LIMIT 1;
+ COMMIT;
+--dec $records
+}
+COMMIT;
+
+--connection slave
+START SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_start.inc
+
+--connection master
+--source include/sync_slave_io_with_master.inc
+
+--connection slave
+# The relay-log coordinate is not at an event boundary and
+# also may change across the server version.
+# The test makes its best to check its coherance.
+--let $pos_until= 4100
+--let $file_rl= slave-relay-bin.000015
+
+--let $pos_gtid = 4010
+--let $info= query_get_value(SHOW RELAYLOG EVENTS IN '$file_rl' FROM $pos_gtid LIMIT 1, Info, 1)
+
+if (`SELECT "$info" != "BEGIN GTID 0-1-23"`)
+{
+ --echo *** Unexpected offset. Refine it to point to the correct GTID!
+ --die
+}
+--let $pos_event = 4090
+--let $type= query_get_value(SHOW RELAYLOG EVENTS IN '$file_rl' FROM $pos_event LIMIT 1, Event_type, 1)
+if (`SELECT "$type" != "Delete_rows_v1"`)
+{
+ --echo *** Unexpected offset. Refine it to point to the expected event!
+ --die
+}
+
+--replace_result $file_rl file_2 $pos_until <pos_until>
+--eval START SLAVE UNTIL RELAY_LOG_FILE = '$file_rl', RELAY_LOG_POS = $pos_until
+
+--echo Proof 1: Correct stop
+--connection slave
+--source include/wait_for_slave_sql_to_stop.inc
+--let $file_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1)
+--let $pos_stop= query_get_value(SHOW SLAVE STATUS, Relay_Log_Pos, 1)
+if (`SELECT strcmp("$file_stop", "$file_rl") = -1 OR
+ strcmp("$file_stop", "$file_rl") = 0 AND $pos_stop < $pos_until`)
+{
+ --echo *** ERROR: Slave stopped at *relay* $file_stop:$pos_stop which is not $file_rl:$pos_until.
+ --die
+}
+
+--echo Proof 2: Resume works out
+--source include/start_slave.inc
+--connection master
+--sync_slave_with_master
+
+--let $diff_tables=master:t2,slave:t2
+--source include/diff_tables.inc
+
+#
+# Clean up.
+#
+--connection slave
+--source include/stop_slave.inc
+SET GLOBAL max_relay_log_size=@old_max_relay_log_size;
+SET GLOBAL slave_parallel_mode=@old_parallel_mode;
+SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+--source include/start_slave.inc
+
+--connection master
+DROP TABLE t1, t2;
+
+--sync_slave_with_master
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test b/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test
index 38759c9b16a..b43de60738e 100644
--- a/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test
+++ b/mysql-test/suite/rpl/t/show_status_stop_slave_race-7126.test
@@ -7,7 +7,7 @@
# If everything is okay, the test will end in several seconds; maybe a minute.
# If the problem shows up, it will hang until testcase timeout is exceeded.
---exec $MYSQL_SLAP --silent --socket=$SLAVE_MYSOCK -q "START SLAVE; STOP SLAVE; SHOW GLOBAL STATUS" -c 2 --number-of-queries=100 --create-schema=test
+--exec $MYSQL_SLAP --silent --host=127.0.0.1 -P $SLAVE_MYPORT -q "START SLAVE; STOP SLAVE; SHOW GLOBAL STATUS" -c 2 --number-of-queries=100 --create-schema=test
# All done.
diff --git a/mysql-test/suite/sys_vars/inc/sysvars_server.inc b/mysql-test/suite/sys_vars/inc/sysvars_server.inc
index cffc7e7fa62..29e8d412c07 100644
--- a/mysql-test/suite/sys_vars/inc/sysvars_server.inc
+++ b/mysql-test/suite/sys_vars/inc/sysvars_server.inc
@@ -1,3 +1,4 @@
+--source include/have_perfschema.inc
--source include/word_size.inc
--vertical_results
diff --git a/mysql-test/suite/sys_vars/r/div_precision_increment_func.result b/mysql-test/suite/sys_vars/r/div_precision_increment_func.result
index ee8b7c5691d..ffe23eb3cef 100644
--- a/mysql-test/suite/sys_vars/r/div_precision_increment_func.result
+++ b/mysql-test/suite/sys_vars/r/div_precision_increment_func.result
@@ -50,9 +50,9 @@ INSERT into t1(name, salary, income_tax) values('Record_2', 501, 501*2.5/1000);
INSERT into t1(name, salary, income_tax) values('Record_3', 210, 210*2.5/1000);
SELECT * from t1;
id name salary income_tax
-1 Record_1 100011 250.027
-2 Record_2 501 1.2525
-3 Record_3 210 0.525
+1 Record_1 100011 250.03
+2 Record_2 501 1.25
+3 Record_3 210 0.53
## Creating new connection ##
## Verifying session & global value of variable ##
SELECT @@global.div_precision_increment = 2;
@@ -67,11 +67,11 @@ INSERT into t1(name, salary, income_tax) values('Record_5', 501, 501*2.5/1000);
INSERT into t1(name, salary, income_tax) values('Record_6', 210, 210*2.5/1000);
SELECT * from t1;
id name salary income_tax
-1 Record_1 100011 250.027
-2 Record_2 501 1.2525
-3 Record_3 210 0.525
-4 Record_4 100011 250.027
-5 Record_5 501 1.2525
+1 Record_1 100011 250.03
+2 Record_2 501 1.25
+3 Record_3 210 0.53
+4 Record_4 100011 250.028
+5 Record_5 501 1.253
6 Record_6 210 0.525
## Dropping table t1 ##
drop table t1;
diff --git a/mysql-test/suite/sys_vars/r/max_sort_length_basic.result b/mysql-test/suite/sys_vars/r/max_sort_length_basic.result
index a8876b2c81e..b48b045897c 100644
--- a/mysql-test/suite/sys_vars/r/max_sort_length_basic.result
+++ b/mysql-test/suite/sys_vars/r/max_sort_length_basic.result
@@ -27,14 +27,14 @@ SELECT @@session.max_sort_length = 1024;
@@session.max_sort_length = 1024
1
'#--------------------FN_DYNVARS_084_03-------------------------#'
-SET @@global.max_sort_length = 4;
+SET @@global.max_sort_length = 8;
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
-SET @@global.max_sort_length = 5;
+8
+SET @@global.max_sort_length = 9;
SELECT @@global.max_sort_length;
@@global.max_sort_length
-5
+9
SET @@global.max_sort_length = 8388608;
SELECT @@global.max_sort_length;
@@global.max_sort_length
@@ -48,14 +48,14 @@ SELECT @@global.max_sort_length;
@@global.max_sort_length
65536
'#--------------------FN_DYNVARS_084_04-------------------------#'
-SET @@session.max_sort_length = 4;
+SET @@session.max_sort_length = 8;
SELECT @@session.max_sort_length;
@@session.max_sort_length
-4
-SET @@session.max_sort_length = 5;
+8
+SET @@session.max_sort_length = 9;
SELECT @@session.max_sort_length;
@@session.max_sort_length
-5
+9
SET @@session.max_sort_length = 8388608;
SELECT @@session.max_sort_length;
@@session.max_sort_length
@@ -74,13 +74,13 @@ Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '-1024'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
SET @@global.max_sort_length = 3;
Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '3'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
SET @@global.max_sort_length = 8388609;
Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '8388609'
@@ -92,17 +92,17 @@ Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '0'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
SET @@global.max_sort_length = 65530.34;
ERROR 42000: Incorrect argument type to variable 'max_sort_length'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
SET @@global.max_sort_length = test;
ERROR 42000: Incorrect argument type to variable 'max_sort_length'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
SET @@session.max_sort_length = 8388610;
Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '8388610'
@@ -114,19 +114,19 @@ Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '-1'
SELECT @@session.max_sort_length;
@@session.max_sort_length
-4
+8
SET @@session.max_sort_length = 3;
Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '3'
SELECT @@session.max_sort_length;
@@session.max_sort_length
-4
+8
SET @@session.max_sort_length = 0;
Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '0'
SELECT @@session.max_sort_length;
@@session.max_sort_length
-4
+8
SET @@session.max_sort_length = 65530.34;
ERROR 42000: Incorrect argument type to variable 'max_sort_length'
SET @@session.max_sort_length = 10737418241;
@@ -158,13 +158,13 @@ Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '1'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
SET @@global.max_sort_length = FALSE;
Warnings:
Warning 1292 Truncated incorrect max_sort_length value: '0'
SELECT @@global.max_sort_length;
@@global.max_sort_length
-4
+8
'#---------------------FN_DYNVARS_084_09----------------------#'
SET @@global.max_sort_length = 2048;
SELECT @@max_sort_length = @@global.max_sort_length;
diff --git a/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result b/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result
index a05b85a9bfd..54adf835962 100644
--- a/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result
+++ b/mysql-test/suite/sys_vars/r/replicate_do_db_basic.result
@@ -37,5 +37,9 @@ SET @@GLOBAL.replicate_do_db=null;
SELECT @@GLOBAL.replicate_do_db;
@@GLOBAL.replicate_do_db
+SET @@GLOBAL.replicate_do_db=DEFAULT;
+SELECT @@GLOBAL.replicate_do_db;
+@@GLOBAL.replicate_do_db
+
# Cleanup.
SET @@GLOBAL.replicate_do_db = @save_replicate_do_db;
diff --git a/mysql-test/suite/sys_vars/r/rpl_init_slave_func.result b/mysql-test/suite/sys_vars/r/rpl_init_slave_func.result
index 691f6f10e02..d63a540fe15 100644
--- a/mysql-test/suite/sys_vars/r/rpl_init_slave_func.result
+++ b/mysql-test/suite/sys_vars/r/rpl_init_slave_func.result
@@ -1,6 +1,6 @@
include/master-slave.inc
[connection master]
-connection slave
+include/sync_slave_sql_with_master.inc
SET @start_max_connections= @@global.max_connections;
SET @start_init_slave= @@global.init_slave;
SET NAMES utf8;
@@ -19,18 +19,11 @@ SELECT @@global.init_slave = 'SET @@global.max_connections = @@global.max_connec
1
Expect 1
include/assert.inc [@@global.max_connections = @start_max_connections]
-STOP SLAVE;
-RESET MASTER;
-RESET SLAVE;
-START SLAVE;
-include/wait_for_slave_to_start.inc
+include/restart_slave.inc
+include/sync_slave_sql_with_master.inc
include/assert.inc [@@global.max_connections = @start_max_connections + 1]
SET @@global.init_slave = "SET @a=5";
-STOP SLAVE;
-RESET MASTER;
-RESET SLAVE;
-START SLAVE;
-include/wait_for_slave_to_start.inc
+include/restart_slave.inc
SHOW VARIABLES LIKE 'init_slave';
Variable_name Value
init_slave SET @a=5
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff
index ff3f5ba1d2c..802932602af 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,32bit,xtradb.rdiff
@@ -1214,8 +1214,8 @@
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
--GLOBAL_VALUE 5.6.45
-+GLOBAL_VALUE 5.6.45-86.1
+-GLOBAL_VALUE 5.6.50
++GLOBAL_VALUE 5.6.49-89.0
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff
index 77e8fb638a1..12aeecc58b4 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff
@@ -684,8 +684,8 @@
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
--GLOBAL_VALUE 5.6.45
-+GLOBAL_VALUE 5.6.45-86.1
+-GLOBAL_VALUE 5.6.50
++GLOBAL_VALUE 5.6.49-89.0
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 7c8ce321cb2..ec53b1d34db 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -502,7 +502,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE zlib
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE ENUM
-VARIABLE_COMMENT Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2
+VARIABLE_COMMENT Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy
NUMERIC_MIN_VALUE NULL
NUMERIC_MAX_VALUE NULL
NUMERIC_BLOCK_SIZE NULL
@@ -588,7 +588,7 @@ VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT InnoDB system tablespace size to be set in recovery.
NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 4294967295
+NUMERIC_MAX_VALUE 268435456
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY YES
@@ -826,7 +826,7 @@ VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE INT UNSIGNED
VARIABLE_COMMENT Number of threads performing background key rotation and scrubbing
NUMERIC_MIN_VALUE 0
-NUMERIC_MAX_VALUE 4294967295
+NUMERIC_MAX_VALUE 255
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
READ_ONLY NO
@@ -2401,7 +2401,7 @@ READ_ONLY NO
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME INNODB_VERSION
SESSION_VALUE NULL
-GLOBAL_VALUE 5.6.45
+GLOBAL_VALUE 5.6.50
GLOBAL_VALUE_ORIGIN COMPILE-TIME
DEFAULT_VALUE NULL
VARIABLE_SCOPE GLOBAL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index 9ca6995d7ef..865b5a8ca2f 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -2033,7 +2033,7 @@ DEFAULT_VALUE 1024
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored)
-NUMERIC_MIN_VALUE 4
+NUMERIC_MIN_VALUE 8
NUMERIC_MAX_VALUE 8388608
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 9288912eb57..21f1f905de8 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -2229,7 +2229,7 @@ DEFAULT_VALUE 1024
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored)
-NUMERIC_MIN_VALUE 4
+NUMERIC_MIN_VALUE 8
NUMERIC_MAX_VALUE 8388608
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
diff --git a/mysql-test/suite/sys_vars/r/table_open_cache_basic.result b/mysql-test/suite/sys_vars/r/table_open_cache_basic.result
index bc373003e1d..b805eb8f742 100644
--- a/mysql-test/suite/sys_vars/r/table_open_cache_basic.result
+++ b/mysql-test/suite/sys_vars/r/table_open_cache_basic.result
@@ -1,7 +1,7 @@
SET @start_value = @@global.table_open_cache ;
-SELECT @start_value;
-@start_value
-421
+SELECT @start_value > 400;
+@start_value > 400
+1
'#--------------------FN_DYNVARS_001_01------------------------#'
SET @@global.table_open_cache = 99;
SET @@global.table_open_cache = DeFAULT;
@@ -108,6 +108,6 @@ ERROR 42S02: Unknown table 'global' in field list
SELECT table_open_cache = @@session.table_open_cache ;
ERROR 42S22: Unknown column 'table_open_cache' in 'field list'
SET @@global.table_open_cache = @start_value;
-SELECT @@global.table_open_cache ;
-@@global.table_open_cache
-421
+SELECT @@global.table_open_cache = @start_value ;
+@@global.table_open_cache = @start_value
+1
diff --git a/mysql-test/suite/sys_vars/t/max_sort_length_basic.test b/mysql-test/suite/sys_vars/t/max_sort_length_basic.test
index 9c3b88d3c3c..fcd6db017f1 100644
--- a/mysql-test/suite/sys_vars/t/max_sort_length_basic.test
+++ b/mysql-test/suite/sys_vars/t/max_sort_length_basic.test
@@ -74,9 +74,9 @@ SELECT @@session.max_sort_length = 1024;
# Change the value of max_sort_length to a valid value for GLOBAL Scope #
#########################################################################
-SET @@global.max_sort_length = 4;
+SET @@global.max_sort_length = 8;
SELECT @@global.max_sort_length;
-SET @@global.max_sort_length = 5;
+SET @@global.max_sort_length = 9;
SELECT @@global.max_sort_length;
SET @@global.max_sort_length = 8388608;
SELECT @@global.max_sort_length;
@@ -90,10 +90,10 @@ SELECT @@global.max_sort_length;
# Change the value of max_sort_length to a valid value for SESSION Scope #
##########################################################################
-SET @@session.max_sort_length = 4;
+SET @@session.max_sort_length = 8;
SELECT @@session.max_sort_length;
-SET @@session.max_sort_length = 5;
+SET @@session.max_sort_length = 9;
SELECT @@session.max_sort_length;
SET @@session.max_sort_length = 8388608;
diff --git a/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test b/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test
index 59d0176add2..b7004d1938b 100644
--- a/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test
+++ b/mysql-test/suite/sys_vars/t/replicate_do_db_basic.test
@@ -38,5 +38,8 @@ SELECT @@GLOBAL.replicate_do_db;
SET @@GLOBAL.replicate_do_db=null;
SELECT @@GLOBAL.replicate_do_db;
+SET @@GLOBAL.replicate_do_db=DEFAULT;
+SELECT @@GLOBAL.replicate_do_db;
+
--echo # Cleanup.
SET @@GLOBAL.replicate_do_db = @save_replicate_do_db;
diff --git a/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test b/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test
index 1d57bfeddc5..0e5ff7a3f39 100644
--- a/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test
+++ b/mysql-test/suite/sys_vars/t/rpl_init_slave_func.test
@@ -29,8 +29,13 @@
###############################################################################
source include/master-slave.inc;
---echo connection slave
-connection slave;
+
+# Since a part of slave SQL thread initialisation happens after Slave_SQL_Running
+# has been set to Yes, there is a race condition between initialisation above and
+# init_slave setting given below. Synchronise slave applier with master to ensure
+# init_slave is complete and applier had processed few events like FD.
+--source include/sync_slave_sql_with_master.inc
+
--disable_query_log
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
--enable_query_log
@@ -67,14 +72,15 @@ let $wait_condition= SELECT @@global.max_connections = @start_max_connections;
--let $assert_text= @@global.max_connections = @start_max_connections
--let $assert_cond= @@global.max_connections = @start_max_connections
--source include/assert.inc
-#
-# reset of the server
-STOP SLAVE;
---wait_for_slave_to_stop
-RESET MASTER;
-RESET SLAVE;
-START SLAVE;
-source include/wait_for_slave_to_start.inc;
+
+--source include/restart_slave_sql.inc
+
+# Upon slave start, sync the applier with master, to ensure slave has
+# completed init_slave command execution and processed FD event from the
+# master.
+--connection master
+--source include/sync_slave_sql_with_master.inc
+
#
# wait for the slave threads have set the global variable.
let $wait_timeout= 90;
@@ -88,12 +94,7 @@ let $wait_condition= SELECT @@global.max_connections = @start_max_connections +
# Setting a variable(which is local to a session) and must not be visible
SET @@global.init_slave = "SET @a=5";
#
-STOP SLAVE;
---wait_for_slave_to_stop
-RESET MASTER;
-RESET SLAVE;
-START SLAVE;
-source include/wait_for_slave_to_start.inc;
+--source include/restart_slave_sql.inc
#
SHOW VARIABLES LIKE 'init_slave';
# expect NULL
diff --git a/mysql-test/suite/sys_vars/t/table_open_cache_basic.test b/mysql-test/suite/sys_vars/t/table_open_cache_basic.test
index 7d2549cd87f..1b7fbe5cbc5 100644
--- a/mysql-test/suite/sys_vars/t/table_open_cache_basic.test
+++ b/mysql-test/suite/sys_vars/t/table_open_cache_basic.test
@@ -35,7 +35,7 @@
##########################################################################
SET @start_value = @@global.table_open_cache ;
-SELECT @start_value;
+SELECT @start_value > 400;
--echo '#--------------------FN_DYNVARS_001_01------------------------#'
@@ -165,7 +165,7 @@ SELECT table_open_cache = @@session.table_open_cache ;
##############################
SET @@global.table_open_cache = @start_value;
-SELECT @@global.table_open_cache ;
+SELECT @@global.table_open_cache = @start_value ;
##################################################################
diff --git a/mysql-test/suite/vcol/r/not_supported.result b/mysql-test/suite/vcol/r/not_supported.result
index 06627fccf8b..a3b73d3444f 100644
--- a/mysql-test/suite/vcol/r/not_supported.result
+++ b/mysql-test/suite/vcol/r/not_supported.result
@@ -51,7 +51,7 @@ a b v
flush tables;
select * from t1;
a b v
-1 2 0.3333333330000000000
+1 2 0.3333000000000000000
select * from t5;
a b v
20141010 2 October
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index 5e84a314b38..abbd73cead6 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -409,5 +409,25 @@ aaa
Warnings:
Warning 1918 Encountered illegal value '\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7' when converting to DOUBLE
#
+# MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
+#
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (
+a INT NOT NULL DEFAULT 10,
+b INT AS (a+1) VIRTUAL
+) ENGINE=MyISAM;
+INSERT INTO t1 (b) VALUES (10);
+ERROR HY000: The value specified for computed column 'b' in table 't1' has been ignored
+INSERT INTO t1 (b) VALUES (DEFAULT(a));
+ERROR HY000: The value specified for computed column 'b' in table 't1' has been ignored
+INSERT INTO t1 (b) VALUES (DEFAULT);
+INSERT INTO t1 VALUES (10,10);
+ERROR HY000: The value specified for computed column 'b' in table 't1' has been ignored
+INSERT INTO t1 VALUES (10,DEFAULT(a));
+ERROR HY000: The value specified for computed column 'b' in table 't1' has been ignored
+INSERT INTO t1 VALUES (10, DEFAULT);
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
# End of 10.1 tests
#
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index d753f4c09cf..9440cc533f8 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -365,6 +365,36 @@ SELECT COLUMN_GET(@aaa, 'price' AS DECIMAL) aaa;
SELECT COLUMN_GET(@aaa, 'price' AS INT) aaa;
SELECT COLUMN_GET(@aaa, 'price' AS DOUBLE) aaa;
+
+--echo #
+--echo # MDEV-22579 No error when inserting DEFAULT(non_virtual_column) into a virtual column
+--echo #
+
+SET sql_mode=STRICT_ALL_TABLES;
+CREATE OR REPLACE TABLE t1 (
+ a INT NOT NULL DEFAULT 10,
+ b INT AS (a+1) VIRTUAL
+) ENGINE=MyISAM;
+
+# Testing with a column list
+
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+INSERT INTO t1 (b) VALUES (10);
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+INSERT INTO t1 (b) VALUES (DEFAULT(a));
+INSERT INTO t1 (b) VALUES (DEFAULT);
+
+# Testing without a column list
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+INSERT INTO t1 VALUES (10,10);
+--error ER_WARNING_NON_DEFAULT_VALUE_FOR_VIRTUAL_COLUMN
+INSERT INTO t1 VALUES (10,DEFAULT(a));
+INSERT INTO t1 VALUES (10, DEFAULT);
+
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
index 1e6ebbbd34d..d146b7187e4 100644
--- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
+++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink.result
@@ -15,6 +15,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -32,6 +33,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
@@ -57,6 +59,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -71,6 +74,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
\d |
diff --git a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
index 85c4d858be2..aff02cb413e 100644
--- a/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
+++ b/mysql-test/suite/wsrep/r/mysql_tzinfo_to_sql_symlink_skip.result
@@ -9,6 +9,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -26,6 +27,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/ignored.tab' as time zone. Skipping it.
Warning: Skipping directory 'MYSQLTEST_VARDIR/zoneinfo/posix/posix': to avoid infinite symlink recursion.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
# Silent run
@@ -36,6 +38,7 @@ TRUNCATE TABLE time_zone;
TRUNCATE TABLE time_zone_name;
TRUNCATE TABLE time_zone_transition;
TRUNCATE TABLE time_zone_transition_type;
+START TRANSACTION;
INSERT INTO time_zone (Use_leap_seconds) VALUES ('N');
SET @time_zone_id= LAST_INSERT_ID();
INSERT INTO time_zone_name (Name, Time_zone_id) VALUES ('GMT', @time_zone_id);
@@ -50,6 +53,7 @@ INSERT INTO time_zone_transition_type (Time_zone_id, Transition_type_id, Offset,
(@time_zone_id, 0, 0, 0, 'GMT')
;
Warning: Unable to load 'MYSQLTEST_VARDIR/zoneinfo/posix/garbage' as time zone. Skipping it.
+COMMIT;
ALTER TABLE time_zone_transition ORDER BY Time_zone_id, Transition_time;
ALTER TABLE time_zone_transition_type ORDER BY Time_zone_id, Transition_type_id;
#
diff --git a/mysql-test/t/aria_icp_debug.result b/mysql-test/t/aria_icp_debug.result
new file mode 100644
index 00000000000..fc01ee4fb3b
--- /dev/null
+++ b/mysql-test/t/aria_icp_debug.result
@@ -0,0 +1,34 @@
+set default_storage_engine=aria;
+drop table if exists t0,t1,t2;
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int primary key);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (
+kp1 int,
+kp2 int,
+col char(100),
+key(kp1, kp2)
+);
+insert into t2 select a, a, a from t1;
+select engine from information_schema.tables
+where table_schema=database() and table_name='t2';
+engine
+Aria
+explain
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range kp1 kp1 5 NULL 10 Using index condition
+set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+connect con1, localhost, root,,;
+connection con1;
+set debug_sync='now WAIT_FOR at_icp_check';
+kill query $target_id;
+set debug_sync='now SIGNAL go';
+connection default;
+ERROR 70100: Query execution was interrupted
+set debug_sync='RESET';
+disconnect con1;
+drop table t0,t1,t2;
+set default_storage_engine=default;
diff --git a/mysql-test/t/aria_icp_debug.test b/mysql-test/t/aria_icp_debug.test
new file mode 100644
index 00000000000..bbdd59d6012
--- /dev/null
+++ b/mysql-test/t/aria_icp_debug.test
@@ -0,0 +1,5 @@
+
+set default_storage_engine=aria;
+--source include/icp_debug_kill.inc
+set default_storage_engine=default;
+
diff --git a/mysql-test/t/connect_debug.test b/mysql-test/t/connect_debug.test
index 7a2f2872b79..de7a292ce67 100644
--- a/mysql-test/t/connect_debug.test
+++ b/mysql-test/t/connect_debug.test
@@ -21,3 +21,18 @@ create user 'bad' identified by 'worse';
--exec $MYSQL --default-auth=mysql_old_password --user=bad --password=worse 2>&1
set global debug_dbug=@old_dbug;
drop user bad;
+
+#
+# Bug#29630767 - USE OF UNINITIALIZED VALUE IN LIBMYSQL (CLIENT.CC FUNCTION RUN_PLUGIN_AUTH)
+#
+set global debug_dbug='+d,increase_srv_handshake_scramble_len';
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MASTER_MYPORT MASTER_MYPORT
+--error 2027
+connect con1,localhost,root;
+set global debug_dbug=@old_dbug;
+
+set global debug_dbug='+d,poison_srv_handshake_scramble_len';
+--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR $MASTER_MYPORT MASTER_MYPORT
+--error 2027
+connect con2,localhost,root;
+set global debug_dbug=@old_dbug;
diff --git a/mysql-test/t/create_drop_function.test b/mysql-test/t/create_drop_function.test
index e4d3d684cd5..3c4770e25e3 100644
--- a/mysql-test/t/create_drop_function.test
+++ b/mysql-test/t/create_drop_function.test
@@ -1,3 +1,5 @@
+source include/have_log_bin.inc;
+
SET timestamp=UNIX_TIMESTAMP('2014-09-30 08:00:00');
CREATE FUNCTION f1(str char(20))
@@ -39,3 +41,25 @@ DROP FUNCTION IF EXISTS f1;
SELECT body FROM mysql.proc WHERE name like 'f1';
DROP FUNCTION IF EXISTS f1;
+--echo #
+--echo # 10.1 Test
+--echo #
+--echo # MDEV-22654: Assertion `!is_set() || (m_status == DA_OK_BULK &&
+--echo # is_bulk_op())' failed in Diagnostics_area::set_ok_status on FUNCTION replace
+--echo #
+
+SET GLOBAL log_bin_trust_function_creators=0;
+
+CREATE FUNCTION f(c INT) RETURNS NUMERIC NO SQL RETURN 0;
+
+--error ER_BINLOG_UNSAFE_ROUTINE
+CREATE OR REPLACE FUNCTION f(c INT) RETURNS INT RETURN 0;
+
+--error ER_TOO_LONG_IDENT
+CREATE OR REPLACE FUNCTION sp1_thisisaveryverylongnamelongnameverylongname_thisisaveryverylongname234872934(a INT) RETURNS INT RETURN 0;
+
+DROP FUNCTION IF EXISTS f;
+
+SET GLOBAL log_bin_trust_function_creators=1;
+
+--echo # End of 10.1 Test
diff --git a/mysql-test/t/ctype_binary.test b/mysql-test/t/ctype_binary.test
index 155d8548f77..19a58180187 100644
--- a/mysql-test/t/ctype_binary.test
+++ b/mysql-test/t/ctype_binary.test
@@ -74,6 +74,66 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE COERCIBILITY(a)=2 AND a='a';
EXPLAIN EXTENDED SELECT * FROM t1 WHERE WEIGHT_STRING(a)='a' AND a='a';
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-22111 ERROR 1064 & 1033 and SIGSEGV on CREATE TABLE w/ various charsets on 10.4/5 optimized builds | Assertion `(uint) (table_check_constraints - share->check_constraints) == (uint) (share->table_check_constraints - share->field_check_constraints)' failed
+--echo #
+
+CREATE TABLE t1(a ENUM(0x6100,0x6200,0x6300) CHARACTER SET 'Binary');
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1),(2),(3);
+SELECT HEX(a) FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+--echo 0x00 in the middle or in the end of a value
+
+CREATE TABLE t1 (a ENUM(0x6100));
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1);
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a ENUM(0x610062));
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1);
+SELECT HEX(a) FROM t1;
+DROP TABLE t1;
+
+--echo 0x00 in the beginning of the first value:
+
+CREATE TABLE t1 (a ENUM(0x0061));
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES(1);
+SELECT * FROM t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a ENUM(0x0061), b ENUM('b'));
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1,1);
+SELECT HEX(a), HEX(b) FROM t1;
+DROP TABLE t1;
+
+--echo # 0x00 in the beginning of the second (and following) value of the *last* ENUM/SET in the table:
+
+CREATE TABLE t1 (a ENUM('a',0x0061));
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1),(2);
+SELECT HEX(a) FROM t1 ORDER BY a;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a ENUM('a'), b ENUM('b',0x0061));
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES (1,1);
+INSERT INTO t1 VALUES (1,2);
+SELECT HEX(a), HEX(b) FROM t1 ORDER BY a, b;
+DROP TABLE t1;
+
+--echo 0x00 in the beginning of a value of a non-last ENUM/SET causes an error:
+--replace_regex /'.*t1.frm'/'DIR\/t1.frm'/
+--error ER_NOT_FORM_FILE
+CREATE TABLE t1 (a ENUM('a',0x0061), b ENUM('b'));
+
+
--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/ctype_utf16.test b/mysql-test/t/ctype_utf16.test
index 1febe3d8aea..28c31d639aa 100644
--- a/mysql-test/t/ctype_utf16.test
+++ b/mysql-test/t/ctype_utf16.test
@@ -721,7 +721,7 @@ CREATE TABLE t1 AS SELECT repeat('a',2) as s1 LIMIT 0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('ab'),('AE'),('ab'),('AE');
SELECT * FROM t1 ORDER BY s1;
-SET max_sort_length=4;
+SET max_sort_length=8;
SELECT * FROM t1 ORDER BY s1;
DROP TABLE t1;
SET max_sort_length=DEFAULT;
diff --git a/mysql-test/t/ctype_utf16le.test b/mysql-test/t/ctype_utf16le.test
index 5e29408cbd0..2a8aaeafe59 100644
--- a/mysql-test/t/ctype_utf16le.test
+++ b/mysql-test/t/ctype_utf16le.test
@@ -683,7 +683,7 @@ CREATE TABLE t1 AS SELECT REPEAT('a',2) as s1 LIMIT 0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('ab'),('AE'),('ab'),('AE');
SELECT * FROM t1 ORDER BY s1;
-SET max_sort_length=4;
+SET max_sort_length=8;
SELECT * FROM t1 ORDER BY s1;
DROP TABLE t1;
SET max_sort_length=DEFAULT;
diff --git a/mysql-test/t/ctype_utf32.test b/mysql-test/t/ctype_utf32.test
index bf822291a21..c7835e3c74f 100644
--- a/mysql-test/t/ctype_utf32.test
+++ b/mysql-test/t/ctype_utf32.test
@@ -778,7 +778,7 @@ CREATE TABLE t1 AS SELECT repeat('a',2) as s1 LIMIT 0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('ab'),('AE'),('ab'),('AE');
SELECT * FROM t1 ORDER BY s1;
-SET max_sort_length=4;
+SET max_sort_length=8;
SELECT * FROM t1 ORDER BY s1;
DROP TABLE t1;
SET max_sort_length=DEFAULT;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 51b6d63ee2f..90f7b0fb75c 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1756,7 +1756,7 @@ set @@collation_connection=utf8_bin;
--echo #
--echo # Checking strnxfrm() with odd length
--echo #
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
create table t1 (a varchar(128) character set utf8 collate utf8_general_ci);
insert into t1 values ('a'),('b'),('c');
@@ -2040,6 +2040,18 @@ SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
+--echo #
+--echo # MDEV-23535 SIGSEGV, SIGABRT and SIGILL in typeinfo for Item_func_set_collation (on optimized builds)
+--echo #
+
+SET NAMES utf8;
+CREATE OR REPLACE TABLE t1(a DATETIME) ENGINE=MYISAM;
+INSERT INTO t1 VALUES ('2019-03-10 02:55:05');
+CREATE OR REPLACE TABLE t2(a VARCHAR(50) CHARACTER SET latin1) ENGINE=MYISAM;
+INSERT INTO t2 VALUES ('2019-03-10 02:55:05');
+SELECT * FROM t1 WHERE (SELECT 1,CONCAT(a) FROM t1) = (SELECT 1,CONCAT(a) FROM t2);
+DROP TABLE t1, t2;
+
--echo #
--echo # End of 10.1 tests
diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test
index ffc098ff938..91256d6e096 100644
--- a/mysql-test/t/ctype_utf8mb4.test
+++ b/mysql-test/t/ctype_utf8mb4.test
@@ -1511,7 +1511,7 @@ drop table t1;
--echo #
--echo # Check strnxfrm() with odd length
--echo #
-set max_sort_length=5;
+set max_sort_length=9;
select @@max_sort_length;
create table t1 (a varchar(128) character set utf8mb4 collate utf8mb4_general_ci);
insert into t1 values ('a'),('b'),('c');
diff --git a/mysql-test/t/fast_prefix_index_fetch_innodb.test b/mysql-test/t/fast_prefix_index_fetch_innodb.test
index c3b3440d82d..7112f14bbd5 100644
--- a/mysql-test/t/fast_prefix_index_fetch_innodb.test
+++ b/mysql-test/t/fast_prefix_index_fetch_innodb.test
@@ -1,9 +1,6 @@
-- source include/have_innodb.inc
---disable_warnings
-drop table if exists prefixinno;
---enable_warnings
-
+SET @save_opt= @@GLOBAL.innodb_prefix_index_cluster_optimization;
set global innodb_prefix_index_cluster_optimization = ON;
show variables like 'innodb_prefix_index_cluster_optimization';
@@ -665,4 +662,49 @@ select @cluster_lookups;
select @cluster_lookups_avoided;
DROP TABLE t1;
-set global innodb_prefix_index_cluster_optimization = OFF;
+
+--echo #
+--echo # MDEV-23600 Division by 0 in row_search_with_covering_prefix()
+--echo #
+CREATE TABLE t(c POINT UNIQUE) ENGINE=InnoDB;
+INSERT t SET c=POINT(1,1);
+SELECT * FROM t WHERE c > (SELECT MAX(c) FROM t);
+DROP TABLE t;
+
+--echo #
+--echo # MDEV-12486 Wrong results with innodb_prefix_index_cluster_optimization
+--echo #
+CREATE TABLE wp_blogs (
+ blog_id bigint(20) NOT NULL auto_increment,
+ site_id bigint(20) NOT NULL default '0',
+ domain varchar(200) NOT NULL default '',
+ path varchar(100) NOT NULL default '',
+ registered datetime NOT NULL default '0000-00-00 00:00:00',
+ last_updated datetime NOT NULL default '0000-00-00 00:00:00',
+ public tinyint(2) NOT NULL default '1',
+ archived tinyint(2) NOT NULL default '0',
+ mature tinyint(2) NOT NULL default '0',
+ spam tinyint(2) NOT NULL default '0',
+ deleted tinyint(2) NOT NULL default '0',
+ lang_id int(11) NOT NULL default '0',
+ PRIMARY KEY (blog_id),
+ KEY domain (domain(50),path(5)),
+ KEY lang_id (lang_id)
+) ENGINE=InnoDB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
+
+INSERT INTO wp_blogs (domain, path) VALUES
+('domain.no', '/fondsinvesteringer/'), ('domain.no', '/'),
+('foo', 'bar'), ('bar', 'foo'), ('foo', 'foo'), ('bar', 'bar'),
+('foo', 'foobar'), ('bar', 'foobar'), ('foobar', 'foobar');
+
+SET GLOBAL innodb_prefix_index_cluster_optimization=off;
+SELECT blog_id FROM wp_blogs WHERE domain IN ('domain.no')
+AND path IN ( '/fondsinvesteringer/', '/' );
+
+SET GLOBAL innodb_prefix_index_cluster_optimization=on;
+SELECT blog_id FROM wp_blogs WHERE domain IN ('domain.no')
+AND path IN ( '/fondsinvesteringer/', '/' );
+
+DROP TABLE wp_blogs;
+
+SET GLOBAL innodb_prefix_index_cluster_optimization = @save_opt;
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index ebce8a8480c..56eb7640f65 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -693,5 +693,93 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-21977 main.func_math fails due to undefined behaviour
+--echo #
+
+SELECT 9223372036854775808 DIV 1;
+--error ER_DATA_OUT_OF_RANGE
+SELECT 9223372036854775808 DIV -1;
+--error ER_DATA_OUT_OF_RANGE
+SELECT -9223372036854775808 DIV 1;
+--error ER_DATA_OUT_OF_RANGE
+SELECT -9223372036854775808 DIV -1;
+
+SELECT 9223372036854775808 MOD 1;
+SELECT 9223372036854775808 MOD -1;
+SELECT -9223372036854775808 MOD 1;
+SELECT -9223372036854775808 MOD -1;
+
+SELECT 1 MOD 9223372036854775808;
+SELECT -1 MOD 9223372036854775808;
+SELECT 1 MOD -9223372036854775808;
+SELECT -1 MOD -9223372036854775808;
+
+SELECT 9223372036854775808 MOD 9223372036854775808;
+SELECT 9223372036854775808 MOD -9223372036854775808;
+SELECT -9223372036854775808 MOD 9223372036854775808;
+SELECT -9223372036854775808 MOD -9223372036854775808;
+
+--echo #
+--echo # MDEV-22502 MDB crashes in CREATE TABLE AS SELECT when the precision of returning type = 0
+--echo #
+
+CREATE TABLE t1 (d decimal(5,5));
+INSERT INTO t1 VALUES (0.55555);
+SELECT TRUNCATE(d,0) FROM t1;
+CREATE TABLE t2 AS SELECT TRUNCATE(d,0) FROM t1;
+SELECT * FROM t2;
+SHOW CREATE TABLE t2;
+DROP TABLE t1, t2;
+
+
+--echo #
+--echo # MDEV-22503 MDB limits DECIMAL column precision to 16 doing CTAS with floor/ceil over DECIMAL(X,Y) where X > 16
+--echo #
+
+CREATE TABLE t44 (d1 decimal(38,0) DEFAULT NULL);
+INSERT INTO t44 VALUES (12345678901234567890123456789012345678);
+SELECT FLOOR(d1) FROM t44;
+CREATE TABLE t45 AS SELECT FLOOR(d1) FROM t44;
+SELECT * FROM t45;
+SHOW CREATE TABLE t45;
+DROP TABLE t44, t45;
+
+
+DELIMITER $$;
+CREATE PROCEDURE p1(prec INT, scale INT)
+BEGIN
+ DECLARE maxval VARCHAR(128) DEFAULT '';
+ SET @type= CONCAT('DECIMAL(', prec, ',', scale,')');
+ SET @stmt= CONCAT('CREATE TABLE t1 (a ', @type, ',b ', @type, 'unsigned)');
+ PREPARE stmt FROM @stmt;
+ EXECUTE stmt;
+ DEALLOCATE PREPARE stmt;
+ SET maxval= CONCAT(REPEAT('9', prec-scale), '.', REPEAT('9',scale));
+ INSERT INTO t1 VALUES (maxval, maxval);
+ CREATE TABLE t2 AS SELECT a, b, FLOOR(a) AS fa, FLOOR(b) AS fb FROM t1;
+ SHOW CREATE TABLE t2;
+ SELECT * FROM t2;
+ DROP TABLE t1, t2;
+END;
+$$
+CREATE PROCEDURE p2(prec INT)
+BEGIN
+ DECLARE scale INT DEFAULT 0;
+ WHILE scale < prec AND scale <= 30 DO
+ CALL p1(prec, scale);
+ SET scale= scale + 1;
+ END WHILE;
+END;
+$$
+DELIMITER ;$$
+--vertical_results
+CALL p2(38);
+CALL p2(30);
+--horizontal_results
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index e4a7d62f85e..d50d60206e1 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -2292,3 +2292,16 @@ DROP DATABASE secret;
set GLOBAL sql_mode=default;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc
+
+
+--echo #
+--echo # MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
+--echo #
+
+SET NAMES utf8;
+SET SQL_MODE='';
+CREATE USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
+SELECT * FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE "'abcdefghijklmnopqrstuvwxyz'%";
+SELECT GRANTEE FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE '%觻%';
+DROP USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
+SET SQL_MODE=DEFAULT;
diff --git a/mysql-test/t/grant5.test b/mysql-test/t/grant5.test
index 649bba7d1ca..74a69952124 100644
--- a/mysql-test/t/grant5.test
+++ b/mysql-test/t/grant5.test
@@ -20,6 +20,7 @@ show grants for foo; # role
--error ER_DBACCESS_DENIED_ERROR
show grants for foo@'%'; # user
--connection default
+--disconnect conn_1
drop user test, foo;
drop role foo;
@@ -33,3 +34,24 @@ REVOKE EXECUTE ON PROCEDURE sp FROM u;
--error ER_TABLE_NOT_LOCKED
REVOKE PROCESS ON *.* FROM u;
DROP TABLE t1;
+
+#
+# MDEV-23010 UPDATE privilege at Database and Table level fail to update with SELECT command denied to user
+#
+create database mysqltest1;
+use mysqltest1;
+create table t1(id int);
+insert t1 values(2);
+create user u1@localhost;
+grant select on mysqltest1.t1 to u1@localhost;
+grant update on mysqltest1.* to u1@localhost;
+connect u1, localhost, u1;
+update mysqltest1.t1 set id=1 where id=2;
+connection default;
+disconnect u1;
+drop user u1@localhost;
+drop database mysqltest1;
+
+#
+# End of 10.1 tests
+#
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index 31ca1c253e4..07306b59c35 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -198,4 +198,31 @@ SELECT sum(col1) FROM t1 FORCE INDEX (key1,key2) WHERE (key1 between 10 and 819
drop table t1;
set optimizer_switch=@tmp_optimizer_switch;
+--echo #
+--echo # MDEV-22728: SIGFPE in Unique::get_cost_calc_buff_size from prepare_search_best_index_intersect
+--echo # on optimized builds
+--echo #
+
+SET @save_sort_buffer_size=@@sort_buffer_size;
+SET @save_innodb_file_format= @@innodb_file_format;
+SET @save_innodb_large_prefix= @@innodb_large_prefix;
+SET sort_buffer_size=2048;
+SET GLOBAL innodb_file_format = BARRACUDA;
+SET GLOBAL innodb_large_prefix = ON;
+
+CREATE TABLE t1 (
+ a VARCHAR(1024) CHARACTER SET UTF8 PRIMARY KEY,
+ b INT,
+ c INT,
+ INDEX (b)
+) ENGINE=InnoDB CHARSET utf8 ROW_FORMAT= DYNAMIC;
+INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_100;
+EXPLAIN SELECT * FROM t1 WHERE a='1' OR b < 5;
+SELECT * FROM t1 WHERE a='1' OR b < 5;
+DROP TABLE t1;
+
+SET GLOBAL innodb_file_format = @save_innodb_file_format;
+SET GLOBAL innodb_large_prefix = @save_innodb_large_prefix;
+SET sort_buffer_size= @save_sort_buffer_size;
+
disconnect disable_purge;
diff --git a/mysql-test/t/index_merge_myisam.test b/mysql-test/t/index_merge_myisam.test
index 2cee768706b..b2216bf9485 100644
--- a/mysql-test/t/index_merge_myisam.test
+++ b/mysql-test/t/index_merge_myisam.test
@@ -244,6 +244,55 @@ DROP TABLE t1;
set optimizer_switch= @optimizer_switch_save;
--echo #
+--echo # MDEV-21932: ROR union with index_merge_sort_union=off
+--echo #
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t0 select a+10 from t0;
+insert into t0 select a+20 from t0;
+insert into t0 select a+40 from t0;
+insert into t0 select a+80 from t0;
+insert into t0 select a+160 from t0;
+delete from t0 where a > 300;
+
+create table t1 (
+ f1 int, f2 int, f3 int, f4 int,
+ primary key (f1), key (f3), key(f4)
+) engine=myisam;
+insert into t1 select a+100, a+100, a+100, a+100 from t0;
+insert into t1 VALUES (9,0,2,6), (9930,0,0,NULL);
+analyze table t1;
+
+set optimizer_switch='index_merge_sort_union=off';
+set optimizer_switch='index_merge_union=on';
+
+let $q1=
+select * from t1
+ where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
+ (f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
+eval explain $q1;
+eval $q1;
+
+insert into t1 values (52,0,1,0),(53,0,1,0);
+insert into t1 values (50,0,1,0),(51,0,1,0);
+insert into t1 values (48,0,1,0),(49,0,1,0);
+insert into t1 values (46,0,1,0),(47,0,1,0);
+insert into t1 values (44,0,1,0),(45,0,1,0);
+analyze table t1;
+
+let $q2=
+select * from t1
+ where (( f3 = 1 or f1 = 7 ) and f1 < 10) or
+ (f3 between 2 and 2 and ( f3 = 1 or f4 < 7 ));
+eval explain $q2;
+eval $q2;
+
+drop table t0,t1;
+
+set optimizer_switch= @optimizer_switch_save;
+
+--echo #
--echo # MDEV-16695: Estimate for rows of derived tables is very high when we are using index_merge union
--echo #
@@ -270,3 +319,5 @@ explain select * from (select * from t0 where key1 = 3 or key2 =3) as Z where Z.
select * from (select * from t0 where key1 = 3 or key2 =3) as Z where Z.key8 > 5;
set @@optimizer_switch= @optimizer_switch_save;
drop table t0;
+
+--echo # End of 10.1 tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 5b3fa7b653c..0ab2930e3f5 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1936,3 +1936,15 @@ SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (t
SELECT count(*) FROM information_schema.columns WHERE table_schema='test' AND (table_name='tt1' AND column_name='c1') OR (table_name='tt2' AND column_name='c2');
SELECT column_name FROM information_schema.columns WHERE (table_name, column_name) IN (('tt1','c1'),('tt2', 'c2')) ORDER BY column_name;
DROP TABLE tt1, tt2;
+
+--echo #
+--echo # MDEV-13242 Wrong results for queries with row constructors and information_schema
+--echo #
+
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
+SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a',193);
+
+
+--echo #
+--echo # End of 10.1 tests
+--echo #
diff --git a/mysql-test/t/innodb_ext_key.combinations b/mysql-test/t/innodb_ext_key.combinations
new file mode 100644
index 00000000000..6ad97eaf75b
--- /dev/null
+++ b/mysql-test/t/innodb_ext_key.combinations
@@ -0,0 +1,5 @@
+[on]
+optimizer_switch=extended_keys=on
+
+[off]
+optimizer_switch=extended_keys=off
diff --git a/mysql-test/t/innodb_ext_key.test b/mysql-test/t/innodb_ext_key.test
index bec4462df08..c936e4b5170 100644
--- a/mysql-test/t/innodb_ext_key.test
+++ b/mysql-test/t/innodb_ext_key.test
@@ -1,9 +1,4 @@
---source include/have_innodb.inc
-
---disable_warnings
-DROP TABLE IF EXISTS t1,t2,t3,t4;
-DROP DATABASE IF EXISTS dbt3_s001;
---enable_warnings
+--source include/innodb_prefix_index_cluster_optimization.inc
SET SESSION STORAGE_ENGINE='InnoDB';
@@ -19,32 +14,12 @@ use dbt3_s001;
--enable_result_log
--enable_query_log
-set @save_ext_key_optimizer_switch=@@optimizer_switch;
-
-set optimizer_switch='extended_keys=off';
explain
select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
flush status;
select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
show status like 'handler_read%';
-set optimizer_switch='extended_keys=on';
-explain
-select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
-flush status;
-select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01';
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=off';
-explain
-select count(*) from lineitem
- where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
-flush status;
-select count(*) from lineitem
- where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
explain
select count(*) from lineitem
where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
@@ -53,16 +28,6 @@ select count(*) from lineitem
where l_orderkey=130 and l_linenumber=2 and l_shipdate='1992-07-01';
show status like 'handler_read%';
-set optimizer_switch='extended_keys=off';
-explain
-select count(*) from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
-flush status;
-select count(*) from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
explain
select count(*) from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
@@ -71,16 +36,6 @@ select count(*) from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=off';
-explain
-select l_orderkey, l_linenumber from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-flush status;
-select l_orderkey, l_linenumber from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
explain
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
@@ -89,21 +44,12 @@ select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=off';
explain
select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
flush status;
select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
show status like 'handler_read%';
-set optimizer_switch='extended_keys=on';
-explain
-select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
-flush status;
-select min(l_orderkey) from lineitem where l_shipdate='1992-07-01';
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=off';
explain
select min(l_orderkey) from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
@@ -112,25 +58,6 @@ select min(l_orderkey) from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=on';
-explain
-select min(l_orderkey) from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-flush status;
-select min(l_orderkey) from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1001 and 2000;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=off';
-explain
-select max(l_linenumber) from lineitem
- where l_shipdate='1992-07-01' and l_orderkey=130;
-flush status;
-select max(l_linenumber) from lineitem
- where l_shipdate='1992-07-01' and l_orderkey=130;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
explain
select max(l_linenumber) from lineitem
where l_shipdate='1992-07-01' and l_orderkey=130;
@@ -139,7 +66,6 @@ select max(l_linenumber) from lineitem
where l_shipdate='1992-07-01' and l_orderkey=130;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=off';
explain
select l_orderkey, l_linenumber
from lineitem use index (i_l_shipdate, i_l_receiptdate)
@@ -152,20 +78,6 @@ select l_orderkey, l_linenumber
or l_receiptdate='1992-07-01' and l_orderkey=5603;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=on';
-explain
-select l_orderkey, l_linenumber
- from lineitem use index (i_l_shipdate, i_l_receiptdate)
- where l_shipdate='1992-07-01' and l_orderkey=130
- or l_receiptdate='1992-07-01' and l_orderkey=5603;
-flush status;
-select l_orderkey, l_linenumber
- from lineitem use index (i_l_shipdate, i_l_receiptdate)
- where l_shipdate='1992-07-01' and l_orderkey=130
- or l_receiptdate='1992-07-01' and l_orderkey=5603;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=off';
explain
select l_orderkey, l_linenumber
from lineitem use index (i_l_shipdate, i_l_receiptdate)
@@ -178,20 +90,6 @@ select l_orderkey, l_linenumber
or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=on';
-explain
-select l_orderkey, l_linenumber
- from lineitem use index (i_l_shipdate, i_l_receiptdate)
- where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
- or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-flush status;
-select l_orderkey, l_linenumber
- from lineitem use index (i_l_shipdate, i_l_receiptdate)
- where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
- or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=off';
explain
select l_orderkey, l_linenumber from lineitem
where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
@@ -202,28 +100,6 @@ select l_orderkey, l_linenumber from lineitem
or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=on';
-explain
-select l_orderkey, l_linenumber from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
- or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-flush status;
-select l_orderkey, l_linenumber from lineitem
- where l_shipdate='1992-07-01' and l_orderkey between 1 and 1000
- or l_receiptdate='1992-07-01' and l_orderkey between 5001 and 6000;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=off';
---replace_column 9 #
-explain
-select max(l_orderkey) from lineitem
- where l_partkey between 1 and 10 group by l_partkey;
-flush status;
-select max(l_orderkey) from lineitem
- where l_partkey between 1 and 10 group by l_partkey;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
--replace_column 9 #
explain
select max(l_orderkey) from lineitem
@@ -233,17 +109,6 @@ select max(l_orderkey) from lineitem
where l_partkey between 1 and 10 group by l_partkey;
show status like 'handler_read%';
-set optimizer_switch='extended_keys=off';
---replace_column 9 #
-explain
-select max(l_orderkey) from lineitem
- where l_suppkey in (1,4) group by l_suppkey;
-flush status;
-select max(l_orderkey) from lineitem
- where l_suppkey in (1,4) group by l_suppkey;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
--replace_column 9 #
explain
select max(l_orderkey) from lineitem
@@ -255,23 +120,6 @@ show status like 'handler_read%';
create index i_p_retailprice on part(p_retailprice);
-set optimizer_switch='extended_keys=off';
---replace_column 9 #
-explain
-select o_orderkey, p_partkey
- from part use index (i_p_retailprice),
- lineitem use index (i_l_partkey), orders
- where p_retailprice > 1100 and o_orderdate='1997-01-01'
- and o_orderkey=l_orderkey and p_partkey=l_partkey;
-flush status;
-select o_orderkey, p_partkey
- from part use index (i_p_retailprice),
- lineitem use index (i_l_partkey), orders
- where p_retailprice > 1100 and o_orderdate='1997-01-01'
- and o_orderkey=l_orderkey and p_partkey=l_partkey;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
--replace_column 9 #
explain
select o_orderkey, p_partkey
@@ -296,8 +144,6 @@ create table t0 (a int);
insert into t0 values (1), (2), (3), (4), (5);
create index i_p_size on part(p_size);
-set optimizer_switch='extended_keys=on';
-
explain
select * from t0, part ignore index (primary)
where p_partkey=t0.a and p_size=1;
@@ -320,7 +166,6 @@ use test;
set @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='materialization=on,semijoin=on';
-SET optimizer_switch='extended_keys=on';
CREATE TABLE t1 (a int, b int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
@@ -339,10 +184,7 @@ set optimizer_switch=@save_optimizer_switch;
--echo # (valgrinf complains fixed by the patch for bug #914560)
--echo #
-set @save_optimizer_switch=@@optimizer_switch;
-
SET optimizer_switch = 'derived_with_keys=on';
-SET optimizer_switch = 'extended_keys=on';
CREATE TABLE t1 (a varchar(1)) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('j'), ('v');
@@ -382,24 +224,12 @@ INSERT INTO t2 VALUES
(10), (11), (12), (13), (14),
(15), (16), (17), (18), (19), (24);
-set @save_optimizer_switch=@@optimizer_switch;
-
-SET optimizer_switch = 'extended_keys=off';
-EXPLAIN
-SELECT a FROM t1 AS t, t2
- WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
-SELECT a FROM t1 AS t, t2
- WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
-
-SET optimizer_switch = 'extended_keys=on';
EXPLAIN
SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
SELECT a FROM t1 AS t, t2
WHERE c = a AND b IN (SELECT b FROM t1, t2 WHERE b = t.b);
-set optimizer_switch=@save_optimizer_switch;
-
DROP TABLE t1,t2;
--echo #
@@ -413,13 +243,11 @@ CREATE TABLE t2 (b int) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES (4), (6);
INSERT INTO t2 (b) VALUES (0), (8);
-set @save_optimizer_switch=@@optimizer_switch;
set @save_join_cache_level=@@join_cache_level;
SET join_cache_level=3;
SET optimizer_switch='join_cache_hashed=on';
SET optimizer_switch='join_cache_bka=on';
-SET optimizer_switch='extended_keys=on';
EXPLAIN
SELECT * FROM t1, t2 WHERE b=a;
@@ -448,24 +276,11 @@ KEY c4 (c4)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-set @save_optimizer_switch=@@optimizer_switch;
-
-set session optimizer_switch='extended_keys=off';
-INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
- ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
-INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
- ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
-
-DELETE FROM t1;
-
-set session optimizer_switch='extended_keys=on';
INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
-set optimizer_switch=@save_optimizer_switch;
-
DROP TABLE t1;
--echo #
@@ -474,8 +289,6 @@ DROP TABLE t1;
--echo # (performance regression introduced in the patch for mdev-3851)
--echo #
-set @save_optimizer_switch=@@optimizer_switch;
-
create table t1 (a int not null) engine=innodb;
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -489,14 +302,6 @@ select
A.a + 10 * B.a, A.a + 10 * B.a, A.a + 10 * B.a
from t1 A, t1 B;
-set optimizer_switch='extended_keys=off';
-explain
-select * from t1, t2 where t2.a=t1.a and t2.b < 2;
-flush status;
-select * from t1, t2 where t2.a=t1.a and t2.b < 2;
-show status like 'handler_read%';
-
-set optimizer_switch='extended_keys=on';
explain
select * from t1, t2 where t2.a=t1.a and t2.b < 2;
flush status;
@@ -522,15 +327,6 @@ alter table t3 add primary key (pk1, pk2);
alter table t3 add key (col1, col2);
analyze table t1,t3;
-set optimizer_switch='extended_keys=off';
---replace_column 9 #
-explain
-select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
---replace_column 9 #
-explain
-select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
-
-set optimizer_switch='extended_keys=on';
--replace_column 9 #
explain
select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
@@ -544,8 +340,6 @@ drop table t1,t2,t3;
--echo # Bug mdev-4340: performance regression with extended_keys=on
--echo #
-set @save_optimizer_switch=@@optimizer_switch;
-
CREATE TABLE t1 (
page_id int(8) unsigned NOT NULL AUTO_INCREMENT,
page_namespace int(11) NOT NULL DEFAULT '0',
@@ -649,13 +443,6 @@ INSERT INTO t3 VALUES
(97,'text-6009',''),(98,'text-7009',''),(99,'text-8009',''),(100,'text-9009','');
-set optimizer_switch='extended_keys=off';
-EXPLAIN
-SELECT * FROM t1, t2 IGNORE INDEX (PRIMARY), t3
- WHERE page_id=rev_page AND rev_text_id=old_id AND page_namespace=4 AND page_title='Sandbox'
-ORDER BY rev_timestamp ASC LIMIT 10;
-
-set optimizer_switch='extended_keys=on';
EXPLAIN
SELECT * FROM t1, t2 IGNORE INDEX (PRIMARY), t3
WHERE page_id=rev_page AND rev_text_id=old_id AND page_namespace=4 AND page_title='Sandbox'
@@ -674,14 +461,10 @@ create table t2 (a bigint not null unique auto_increment, b varchar(10), primary
insert into t1 (b) values (null), (null), (null);
insert into t2 (b) values (null), (null), (null);
-set optimizer_switch='extended_keys=on';
explain select a from t1 where b is null order by a desc limit 2;
select a from t1 where b is null order by a desc limit 2;
explain select a from t2 where b is null order by a desc limit 2;
select a from t2 where b is null order by a desc limit 2;
-set optimizer_switch='extended_keys=off';
-explain select a from t2 where b is null order by a desc limit 2;
-select a from t2 where b is null order by a desc limit 2;
explain select a from t2 where b is null order by a desc;
select a from t2 where b is null order by a desc;
@@ -691,8 +474,6 @@ select a from t2 where b is null order by a desc,a,a;
drop table t1, t2;
-set optimizer_switch=@save_optimizer_switch;
-
--echo #
--echo # MDEV-10325: Queries examines all rows of a tables when it should not
--echo #
@@ -828,7 +609,6 @@ explain format= json
select * from t1 force index(k1) where f2 <= 5 and pk2 <=5 and pk1 = 'abc' and f1 <= '3';
drop table t1;
-set optimizer_switch=@save_ext_key_optimizer_switch;
set global innodb_file_format = @save_innodb_file_format;
set global innodb_large_prefix = @save_innodb_large_prefix;
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/innodb_icp_debug.result b/mysql-test/t/innodb_icp_debug.result
new file mode 100644
index 00000000000..5a169650c8e
--- /dev/null
+++ b/mysql-test/t/innodb_icp_debug.result
@@ -0,0 +1,34 @@
+set default_storage_engine=innodb;
+drop table if exists t0,t1,t2;
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int primary key);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (
+kp1 int,
+kp2 int,
+col char(100),
+key(kp1, kp2)
+);
+insert into t2 select a, a, a from t1;
+select engine from information_schema.tables
+where table_schema=database() and table_name='t2';
+engine
+InnoDB
+explain
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range kp1 kp1 5 NULL 11 Using index condition
+set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+connect con1, localhost, root,,;
+connection con1;
+set debug_sync='now WAIT_FOR at_icp_check';
+kill query $target_id;
+set debug_sync='now SIGNAL go';
+connection default;
+ERROR 70100: Query execution was interrupted
+set debug_sync='RESET';
+disconnect con1;
+drop table t0,t1,t2;
+set default_storage_engine=default;
diff --git a/mysql-test/t/innodb_icp_debug.test b/mysql-test/t/innodb_icp_debug.test
new file mode 100644
index 00000000000..4aa08c61e87
--- /dev/null
+++ b/mysql-test/t/innodb_icp_debug.test
@@ -0,0 +1,6 @@
+--source include/have_innodb.inc
+
+set default_storage_engine=innodb;
+--source include/icp_debug_kill.inc
+set default_storage_engine=default;
+
diff --git a/mysql-test/t/insert_debug-master.opt b/mysql-test/t/insert_debug-master.opt
new file mode 100644
index 00000000000..824f656cbd5
--- /dev/null
+++ b/mysql-test/t/insert_debug-master.opt
@@ -0,0 +1 @@
+--innodb_autoinc_lock_mode=2
diff --git a/mysql-test/t/insert_debug.test b/mysql-test/t/insert_debug.test
new file mode 100644
index 00000000000..b35d6b838da
--- /dev/null
+++ b/mysql-test/t/insert_debug.test
@@ -0,0 +1,54 @@
+source include/have_innodb.inc;
+source include/have_debug.inc;
+source include/have_debug_sync.inc;
+
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+
+connect (con1, localhost, root,,);
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+
+connection default;
+
+let $conn0_id= `SELECT CONNECTION_ID()`;
+
+CREATE TABLE t1(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL);
+INSERT INTO t1(c1, c2, c3) VALUES('A1','B1','IT1'), ('A2','B2','IT1'), ('A3','B3','IT1'), ('A4','B4','IT1'), ('A5','B5','IT1'), ('A6','B6','IT1'), ('A7','B7','IT1');
+
+CREATE TABLE t2(c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10) NOT NULL, c3 VARCHAR(10) NOT NULL);
+INSERT INTO t2(c1, c2, c3) VALUES ('A3','B3','IT2'), ('A2','B2','IT2'), ('A4','B4','IT2'), ('A5','B5','II2');
+
+CREATE TABLE result(id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, c1 VARCHAR(10) NOT NULL, c2 VARCHAR(10),
+c3 VARCHAR(10), update_count INT DEFAULT 0, UNIQUE KEY uniq_idx (c1,c2), PRIMARY KEY (id)) ENGINE = innodb;
+
+# Insert one row from 't1' into the 'result' table and wait on a debug sync
+# point. The next insert statement from an session 2 inserts values that would
+# lead to unique key clash, when this insert resumes.
+# The subsequent inserts of this statement(after resume) will fail because of a
+# clash with the unique index, and are expected to update the row which clashes
+# with the unique key.
+# Without the fix for bug#30194841 a stale auto increment value, would cause a
+# collision with existing auto increment column value and ends up updating that
+# colliding row, instead of the row colliding with the unique index.
+SET DEBUG_SYNC = "ha_write_row_end WAIT_FOR flushed EXECUTE 1";
+send INSERT INTO result(c1, c2, c3) SELECT * FROM t1 ON DUPLICATE KEY UPDATE c2=t1.c2, c3='UT1', update_count=update_count+1;
+
+# While session 1 is waiting (after one insert), insert rows that will cause a clash
+# with the inserts of session 1 on the unique key.
+connection con1;
+
+# Wait for the session 1 to hit the debug sync point.
+let $wait_condition=SELECT 1 FROM information_schema.processlist WHERE id = $conn0_id AND state LIKE '%ha_write_row_end%';
+--source include/wait_condition.inc
+
+INSERT INTO result(c1, c2, c3) SELECT * FROM t2 ON DUPLICATE KEY UPDATE c2=t2.c2, c3='UT2', update_count=update_count+1;
+
+# Signal to resume the insert statement in session 1
+SET DEBUG_SYNC = "now SIGNAL flushed";
+connection default;
+reap;
+SELECT * FROM result;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE result;
+SET DEBUG_SYNC = "RESET";
diff --git a/mysql-test/t/limit_rows_examined.test b/mysql-test/t/limit_rows_examined.test
index 45ee483c7aa..346a0478891 100644
--- a/mysql-test/t/limit_rows_examined.test
+++ b/mysql-test/t/limit_rows_examined.test
@@ -576,3 +576,20 @@ EXECUTE ps;
drop view v;
drop table t1, t2;
+
+--echo #
+--echo # 10.1 Test
+--echo #
+--echo # MDEV-17729: Assertion `! is_set() || m_can_overwrite_status'
+--echo # failed in Diagnostics_area::set_error_status
+--echo #
+set @old_mode= @@sql_mode;
+
+CREATE TABLE t1(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,k INT, c CHAR(20));
+INSERT INTO t1 (k,c) VALUES(0,'0'), (0,'0'),(0,'0'),(0,'0'),(0,'0'),(0,'0'),(0,'0');
+
+SET @@sql_mode='STRICT_TRANS_TABLES';
+INSERT INTO t1 (c) SELECT k FROM t1 LIMIT ROWS EXAMINED 2;
+
+SET @@sql_mode=@old_mode;
+DROP TABLE t1;
diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test
index f822ec8d758..0196e62f12f 100644
--- a/mysql-test/t/log_tables.test
+++ b/mysql-test/t/log_tables.test
@@ -58,7 +58,7 @@ select * from general_log where argument like '%general_log%';
#
# Check some basic queries interfering with the log tables.
-# In our test we'll use a tbale with verbose comments to the short
+# In our test we'll use a table with verbose comments to the short
# command type names, used in the tables
#
@@ -471,6 +471,24 @@ drop table slow_log_new, general_log_new;
use test;
#
+# Bug#69953 / MDEV-4851
+# Log tables should be modifable on LOG_OUTPUT != TABLE
+#
+#
+
+SET GLOBAL LOG_OUTPUT = 'FILE';
+SET GLOBAL slow_query_log = 1;
+SET GLOBAL general_log = 1;
+
+ALTER TABLE mysql.slow_log ADD COLUMN comment_text TEXT NOT NULL;
+ALTER TABLE mysql.general_log ADD COLUMN comment_text TEXT NOT NULL;
+
+SET GLOBAL LOG_OUTPUT = 'NONE';
+ALTER TABLE mysql.slow_log DROP COLUMN comment_text;
+ALTER TABLE mysql.general_log DROP COLUMN comment_text;
+
+
+#
# Bug#27857 (Log tables supplies the wrong value for generating
# AUTO_INCREMENT numbers)
#
diff --git a/mysql-test/t/myisam_icp_debug.result b/mysql-test/t/myisam_icp_debug.result
new file mode 100644
index 00000000000..cb45a0e2274
--- /dev/null
+++ b/mysql-test/t/myisam_icp_debug.result
@@ -0,0 +1,32 @@
+drop table if exists t0,t1,t2;
+create table t0(a int primary key);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(a int primary key);
+insert into t1 select A.a + B.a* 10 + C.a * 100 from t0 A, t0 B, t0 C;
+create table t2 (
+kp1 int,
+kp2 int,
+col char(100),
+key(kp1, kp2)
+);
+insert into t2 select a, a, a from t1;
+select engine from information_schema.tables
+where table_schema=database() and table_name='t2';
+engine
+MyISAM
+explain
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range kp1 kp1 5 NULL 11 Using index condition
+set debug_sync='handler_index_cond_check SIGNAL at_icp_check WAIT_FOR go';
+select * from t2 where kp1 between 10 and 20 and kp2 +1 >100;
+connect con1, localhost, root,,;
+connection con1;
+set debug_sync='now WAIT_FOR at_icp_check';
+kill query $target_id;
+set debug_sync='now SIGNAL go';
+connection default;
+ERROR 70100: Query execution was interrupted
+set debug_sync='RESET';
+disconnect con1;
+drop table t0,t1,t2;
diff --git a/mysql-test/t/myisam_icp_debug.test b/mysql-test/t/myisam_icp_debug.test
new file mode 100644
index 00000000000..d5b1af799fa
--- /dev/null
+++ b/mysql-test/t/myisam_icp_debug.test
@@ -0,0 +1 @@
+--source include/icp_debug_kill.inc
diff --git a/mysql-test/t/mysqlbinlog_row_minimal.test b/mysql-test/t/mysqlbinlog_row_minimal.test
index 39cae408d4e..57bae4247e1 100644
--- a/mysql-test/t/mysqlbinlog_row_minimal.test
+++ b/mysql-test/t/mysqlbinlog_row_minimal.test
@@ -33,6 +33,35 @@ FLUSH BINARY LOGS;
DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-16372 ER_BASE64_DECODE_ERROR upon replaying binary log with system table
+--echo #
+
+FLUSH BINARY LOGS;
+CREATE TABLE t1 (pk INT PRIMARY KEY);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t1 VALUES (1), (2) ON DUPLICATE KEY UPDATE pk= pk + 10;
+
+--let $binlog = query_get_value(SHOW MASTER STATUS, File, 1)
+
+FLUSH BINARY LOGS;
+--exec $MYSQL_BINLOG --verbose $datadir/$binlog > $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
+--echo Proof: two subsequent patterns must be found
+--let SEARCH_PATTERN= ### UPDATE `test`.`t1`
+--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
+--source include/search_pattern_in_file.inc
+--let SEARCH_PATTERN= ### INSERT INTO `test`.`t1`
+--let SEARCH_FILE= $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
+--source include/search_pattern_in_file.inc
+
+DROP TABLE t1;
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
+SELECT * FROM t1;
+
+--echo # Cleanup
+DROP TABLE t1;
+--remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog.sql
#
# MDEV-14605 ON UPDATE CURRENT_TIMESTAMP fields by multi-table UPDATE are not logged with binlog_row_image=MINIMAL
#
@@ -64,11 +93,12 @@ UPDATE t1 t1 INNER JOIN t2 t2 ON t1.ref_id = t2.id
WHERE t1.id = 1;
--let $binlog = query_get_value(SHOW MASTER STATUS, File, 1)
+--let $binlog_end= query_get_value(SHOW MASTER STATUS, Position, 1)
FLUSH BINARY LOGS;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
---replace_regex /\d{6} *\d*:\d\d:\d\d/<date>/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /@3=\d*/@3=X/ /CRC32 0x[0-9a-f]+/CRC32 XXX/
---exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --start-position=$binlog_pos
+--replace_regex /table id \d*/table id TID/ /mapped to number \d*/mapped to number TID/ /at \d*/at POS/ /end_log_pos \d*/end_log_pos END_LOG_POS/ /GTID \d*-\d*-\d*/GTID D-S-N/ /\d{6} *\d*:\d\d:\d\d/<date>/ /SET TIMESTAMP=\d*/SET TIMESTAMP=X/ /exec_time=\d*/exec_time=x/ /@3=\d*/@3=X/ /CRC32 0x[0-9a-f]+/CRC32 XXX/ /thread_id=\d*/thread_id=TID/
+--exec $MYSQL_BINLOG --verbose --verbose --base64-output=DECODE-ROWS $datadir/$binlog --start-position=$binlog_pos --stop-position=$binlog_end
DROP TABLE t1,t2;
diff --git a/mysql-test/t/mysqld--defaults-file.test b/mysql-test/t/mysqld--defaults-file.test
index 3bfe0aa891f..91d30eb1617 100644
--- a/mysql-test/t/mysqld--defaults-file.test
+++ b/mysql-test/t/mysqld--defaults-file.test
@@ -29,3 +29,19 @@ exec $MYSQLD --defaults-file=with.ext --print-defaults 2>&1;
--error 1
exec $MYSQLD --defaults-file=no_extension --print-defaults 2>&1;
+--echo #
+--echo # MDEV-21374: When "--help --verbose" prints out configuration file paths,
+--echo # the --defaults-file option is not considered
+--echo #
+
+--echo # Test on `defaults-file`
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+exec $MYSQLD --defaults-file=$MYSQLTEST_VARDIR/my.cnf --help --verbose | grep -A 1 'Default options are read';
+
+--echo # Test on `defaults-extra-file`
+# <first-defaults> = `/etc/my.cnf /etc/mysql/my.cnf`
+# Using sysconfdir configuration, we don't always have `/etc/mysql/my.cnf`, so replace them with a regex as well.
+copy_file $MYSQLTEST_VARDIR/my.cnf $MYSQLTEST_VARDIR/my_test.cnf;
+--replace_regex /.*my_test.cnf/<first-defaults> MYSQLTEST_VARDIR\/my_test.cnf/
+exec $MYSQLD --defaults-extra-file=$MYSQLTEST_VARDIR/my_test.cnf --help --verbose | grep -A 1 'Default options are read';
+remove_file $MYSQLTEST_VARDIR/my_test.cnf;
diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test
index 8924d2c45da..ec6e0f01189 100644
--- a/mysql-test/t/mysqld--help.test
+++ b/mysql-test/t/mysqld--help.test
@@ -23,7 +23,8 @@ perl;
log-slow-queries pid-file slow-query-log-file log-basename
datadir slave-load-tmpdir tmpdir socket thread-pool-size
large-files-support lower-case-file-system system-time-zone
- collation-server character-set-server log-tc-size version.*/;
+ collation-server character-set-server log-tc-size table-cache
+ table-open-cache max-connections version.*/;
# Plugins which may or may not be there:
@plugins=qw/innodb archive blackhole federated partition
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 7382bd455c8..3f33e4a1d64 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -2678,3 +2678,39 @@ select count(*) from t2;
--remove_file $MYSQLTEST_VARDIR/tmp/t2.txt
drop tables t2, t1;
+
+
+--echo #
+--echo # MDEV-22037: Add ability to skip content of some tables
+--echo # (work around for MDEV-20939)
+--echo #
+
+use mysql;
+
+--echo # check that all tables we need are not empty
+
+select count(*) >= 1 from mysql.proc;
+select count(*) >= 1 from mysql.db;
+
+
+--exec $MYSQL_DUMP mysql --ignore-table-data=mysql.db >$MYSQLTEST_VARDIR/tmp/MDEV-20939.sql
+
+
+--echo # for proc we have CREATE and INSERT for all other only CREATE
+
+let SEARCH_RANGE=500000000;
+let SEARCH_FILE=$MYSQLTEST_VARDIR/tmp/MDEV-20939.sql;
+let SEARCH_PATTERN=INSERT INTO `proc`;
+source include/search_pattern_in_file.inc;
+let SEARCH_PATTERN=INSERT INTO `db`;
+source include/search_pattern_in_file.inc;
+let SEARCH_PATTERN=CREATE TABLE `db`;
+source include/search_pattern_in_file.inc;
+let SEARCH_PATTERN=CREATE TABLE `proc`;
+source include/search_pattern_in_file.inc;
+
+--remove_file $MYSQLTEST_VARDIR/tmp/MDEV-20939.sql
+use test;
+
+
+--echo # End of 10.1 tests
diff --git a/mysql-test/t/nested_profiling.test b/mysql-test/t/nested_profiling.test
new file mode 100644
index 00000000000..ba89aefc647
--- /dev/null
+++ b/mysql-test/t/nested_profiling.test
@@ -0,0 +1,42 @@
+# ==== Purpose ====
+#
+# Test verifies that "init_connect" and "init_slave" system variables work
+# fine when "profiling=on".
+#
+# ==== Implementation ====
+#
+# Steps:
+# 0 - Create regular user without super privilege so that "init_connect"
+# variable is effective.
+# 1 - Enable profiling.
+# 2 - Start a new connection which will try to execute the statements
+# specified in "init_connect". No assert should be reported.
+# 3 - Execute SHOW PROFILES to verify that statements specified in
+# "init_connect" are displayed as part of profiling.
+#
+# ==== References ====
+#
+# MDEV-22706: Assertion `!current' failed in PROFILING::start_new_query
+#
+--source include/not_embedded.inc
+--source include/have_profiling.inc
+
+SET @saved_profiling=@@GLOBAL.profiling;
+SET @saved_init_connect=@@GLOBAL.init_connect;
+SET GLOBAL init_connect="set @a=2;set @b=3";
+SET GLOBAL profiling=on;
+
+create user mysqltest1@localhost;
+connect (con1,localhost,mysqltest1,,);
+connection con1;
+SELECT @a, @b;
+--replace_column 2 #
+SHOW PROFILES;
+
+#========== Clean up ===========
+connection default;
+disconnect con1;
+DROP USER mysqltest1@localhost;
+
+SET GLOBAL profiling=@saved_profiling;
+SET GLOBAL init_connect=@saved_init_connect;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 999c7314139..3e614ed3316 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -12,6 +12,8 @@ call mtr.add_suppression("Out of sort memory; increase server sort buffer size")
# Test old ORDER BY bug
#
+--source include/have_sequence.inc
+
CREATE TABLE t1 (
id int(6) DEFAULT '0' NOT NULL,
idservice int(5),
@@ -2157,3 +2159,55 @@ select * from t1 order by b;
set @@sort_buffer_size= @save_sort_buffer_size;
drop table t1;
+--echo #
+--echo # MDEV-22715: SIGSEGV in radixsort_for_str_ptr and in native_compare/my_qsort2 (optimized builds)
+--echo #
+
+SET @save_sort_buffer_size= @@sort_buffer_size;
+SET @save_max_sort_length= @@max_sort_length;
+SET max_sort_length=8;
+SET sort_buffer_size=1024;
+CREATE TABLE t1(a INT, b DECIMAL(65), c BLOB);
+INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_25;
+INSERT INTO t1 SELECT seq, seq, seq from seq_1_to_25;
+SELECT * FROM t1 ORDER BY a,b;
+SET @@sort_buffer_size= @save_sort_buffer_size;
+SET @@max_sort_length= @save_max_sort_length;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-22390: Assertion `m_next_rec_ptr >= m_rawmem' failed in Filesort_buffer::spaceleft |
+--echo # SIGSEGV in __memmove_avx_unaligned_erms from my_b_write (on optimized)
+--echo #
+
+SET @save_max_sort_length= @@max_sort_length;
+SET @save_sort_buffer_size= @@sort_buffer_size;
+SET @save_max_length_for_sort_data= @@max_length_for_sort_data;
+SET max_sort_length=8;
+SET sort_buffer_size=1024;
+# needed to make sure we use addon fields
+SET max_length_for_sort_data=7000;
+CREATE TABLE t1(a VARCHAR(64), b VARCHAR(2048))DEFAULT CHARSET=utf8;
+INSERT INTO t1 SELECT seq,seq from seq_1_to_100;
+--source include/analyze-format.inc
+ANALYZE FORMAT=JSON SELECT * FROM t1 ORDER BY a LIMIT 5;
+SELECT * FROM t1 ORDER BY a LIMIT 5;
+SET max_sort_length= @save_max_sort_length;
+SET sort_buffer_size= @save_sort_buffer_size;
+SET max_length_for_sort_data= @save_max_length_for_sort_data;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-23596: Assertion `tab->ref.use_count' failed in join_read_key_unlock_row
+--echo #
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT, KEY(b));
+INSERT INTO t1 VALUES (0, 1),(1, 2);
+CREATE TABLE t2 SELECT * FROM t1;
+
+EXPLAIN SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.b ORDER BY t1.b LIMIT 1) AS c FROM t2;
+
+DROP TABLE t1,t2;
+
+--echo # end of 10.1 tests
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 0f965cc810a..b82485dfc5c 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -2971,5 +2971,49 @@ SELECT 1 FROM t1 WHERE a XOR 'a';
DROP TABLE t1;
--echo #
+--echo # Bug #25207522: INCORRECT ORDER-BY BEHAVIOR ON A PARTITIONED TABLE
+--echo # WITH A COMPOSITE PREFIX INDEX
+--echo #
+create table t1(id int unsigned not null,
+ data varchar(2) default null,
+ key data_idx (data(1),id)
+) default charset=utf8
+partition by range (id) (
+ partition p10 values less than (10),
+ partition p20 values less than (20)
+);
+insert t1 values (6, 'ab'), (4, 'ab'), (5, 'ab'), (16, 'ab'), (14, 'ab'), (15, 'ab'), (5, 'ac'), (15, 'aa') ;
+select id from t1 where data = 'ab' order by id;
+drop table t1;
+
+create table t1(id int unsigned not null,
+ data text default null,
+ key data_idx (data(1),id)
+) default charset=utf8
+partition by range (id) (
+ partition p10 values less than (10),
+ partition p20 values less than (20)
+);
+insert t1 values (6, 'ab'), (4, 'ab'), (5, 'ab'), (16, 'ab'), (14, 'ab'), (15, 'ab'), (5, 'ac'), (15, 'aa') ;
+select id from t1 where data = 'ab' order by id;
+drop table t1;
+
+--echo #
+--echo # MDEV-5628: Assertion `! is_set()' or `!is_set() ||
+--echo # (m_status == DA_OK_BULK && is_bulk_op())' fails on UPDATE on a
+--echo # partitioned table with subquery (MySQL:71630)
+--echo #
+
+CREATE TABLE t1 (a INT) PARTITION BY HASH(a) PARTITIONS 2;
+
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+
+--error ER_SUBQUERY_NO_1_ROW
+UPDATE t1 SET a = 7 WHERE a = ( SELECT b FROM t2 ) ORDER BY a LIMIT 6;
+
+DROP TABLE t1,t2;
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/processlist_notembedded.test b/mysql-test/t/processlist_notembedded.test
index dc970cf5709..90750b40e62 100644
--- a/mysql-test/t/processlist_notembedded.test
+++ b/mysql-test/t/processlist_notembedded.test
@@ -1,6 +1,7 @@
source include/have_debug.inc;
source include/have_debug_sync.inc;
source include/not_embedded.inc;
+source include/count_sessions.inc;
--echo #
--echo # MDEV-20466: SHOW PROCESSLIST truncates query text on \0 bytes
@@ -10,9 +11,9 @@ connect (con1,localhost,root,,);
connection con1;
-let $q= `select CONCAT("SELECT user FROM mysql.user WHERE user ='some", CHAR(0), "' or sleep (30)")`;
+let $q= `select CONCAT("SELECT user FROM mysql.user WHERE user ='some", CHAR(0), "sleep'")`;
-SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync';
+SET DEBUG_SYNC= 'before_join_optimize SIGNAL in_sync WAIT_FOR go';
--disable_query_log
--send_eval $q;
--enable_query_log
@@ -27,8 +28,15 @@ let SEARCH_PATTERN=sleep;
source include/search_pattern_in_file.inc;
remove_file $MYSQLTEST_VARDIR/tmp//MDEV-20466.text;
+SET DEBUG_SYNC= 'now SIGNAL go';
+
+connection con1;
+reap;
disconnect con1;
+connection default;
SET DEBUG_SYNC = 'RESET';
+source include/wait_until_count_sessions.inc;
+
--echo End of 5.5 tests
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index a97b0b1c815..e98d59fcb9e 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -1718,6 +1718,23 @@ drop table t1;
set GLOBAL query_cache_size=1355776;
SET GLOBAL userstat=default;
+--echo #
+--echo # MDEV-5924: MariaDB could crash after changing the query_cache size
+--echo #
+
+SET GLOBAL query_cache_size= 50*1024;
+SET GLOBAL query_cache_type= 1;
+SET query_cache_type= 1;
+
+CREATE TABLE t1 (pk INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM v1 WHERE pk IN (5178922,5178924,6911605,6584899,1754348,7735031,9583206,8377182,6309967,3110885,7197937,5582397,9811721,8310302,7001831,3687942,8454635,8743988,9524703,3313583,1376007,5276565,7238861,5307189,2242691,2052764,8160476,7668014,5891525,9070968,1989181,3014068,5365005,2974655,6877822,7813446,6188705,1028564,6426696,6098205,7231857,2749710,4996963,9879425,2995803,8160614,1934799,1981216,3673522,2135299,4803054,8515609,1825485,5805694,8211425,3712249,8013259,3496368,4339706,2326187,3236816,8158416,5749801,6339492,2517486,1769729,2576400,8177368,5471847,4670669,5694046,5155990,1219314,1304321,7951736,2381942,1467330,3329376,6069503,3821151,8118179,4575775,5291671,4757186,6241302,9809112,5388351,3356292,5753921,8776535,7101943,8558868,6655212,5498901,1629516,8016143,1156005,1280700,9236450,8289703,4549957,5404968,3594833,3034667,3167602,7983322,3939941,8382949,9258422,6927947,9639236,3246566,3144943,5516067,5266540,3760726,6491516,9515090,7776229,1582824,4031951,3336517,5871612,4268432,2600433,6188018,6158355,6442214,7808502,7692871,9180969,3982238,9212692,9944381,3932525,5937118,6315460,2464477,1933151,3393646,4244674,7036026,1470764,3015029,2453765,9876129,2097534,3467391,4287658,8120651,4975540,4454101,7758102,6087905,2167022,7575454,5370086,8289703,7460235,8734512,7346801,6660293,5826843,4305511,8093597,8970031,9104476,1784973,9245925,6893890,4996414,3144393,1145568,2702056,4984878,5602859,7088073,2044113,5248275,6037094,2185287,1791564,3180374,8750991,9187011,6411453,9600372,4819671,3105667,2837051,1252548,3729003,7986618,8305633,5684432,4528808,8670104,4132202,2101516,5218475,6885513,4886413,1288803,9584167,6524475,3943649,6195846,4204986,5435592,8877334,9276275,8848358,3583435,6662216,7178298,1973526,5917205,9156387,8877334,4559432,2792144,9831634,8846710,6979858,5287277,2220718,9358123,4140029,1263122,8049789,9508361,3597030,8504348,4525924,9062866,1880691,9788375,4746612,7711822,9735366,9227523,9701721,2832519,4498870,3725021,4836151,2351181,7339935,9890686,7641098,1797607,1571838,3258377,6244186,5147476,6760543,9151580,2465576,2545776,6846237,4037582,8310440,2503616,1998245,1716445,2364913,4665039,8420440,1187728,1065917,1734710,5826705,8538681,8311950,4662017,7804519,7696853,7385116,8674362,2787612,2393341,1652313,2254364,3852737,4177108,7013641,8654037,9062728,7826629,2569396,1039138,2572692,9001892,3470550,4859359,5218887,6479568,1424621,3535644,7808639,7817291,8825149,6060302,2830047,7787765,5971313,9603256,1800491,3429214,9350021,8716796,1972564,6054946,6445510,9234802,5616729,6064559,2048233,9458511,1597244,3902862,2530120,5723846,3463821,9008346,3055130,2941696,8774337,3095367,2195037,6208480,9869262,3615295,9916641,1078002,1815597,7737228,1412261,6588607,9740173,6696411,7740386,1641326,9269546,3848754,7745193,6819458,5297164,1280975,1224395,5247589,7793533,5314743,8814025,2579010,7882659,6753128,9558349,8710067,7898727,4209106,2634902,7311233,1644897,8363449,6201339,1770828,3572174,5493408,8835449,5644332,5096115,7116088,1534484,3204544,1772064,2091903,6744476,9183166,5546005,1030075,7387725,1300888,5799789,7340209,7356552,7677627,9410995,5775894,9442581,5718353,6544937,9809524,7171569,4565475,1397293,6687759,1509353,3715682,8607208,3506118,3910827,1890167,1559341,4150329,9679336,9756927,1292373,3445419,2105361,6594238,4234237,8359466,7352432,1492462,9482818,1601226,8561614,4186584,5849365,1460189,9139495,3113357,8384460,7229660,8701553,7786254,4606399,2057708,1638992,1083221,8147293,9569198,4776550,2539871,8040039,7104141,8090713,7242568,2361480,6913940,7958053,1414596,3451461,9160644,7901473,8289703,5428588,3063232,2302291,5366378,8216918,8033447,8048965,8636322,7807952,7146026,6589569,2882644,1971328,7786392,5357864,4637985,2137222,9819961,9039932,8900680,1666732,8126968,1652999,7199035,8229003,7845581,8902328,8100051,9506164,8168579,8786560,4753890,6941268,5035552,2919860,9570983,4751968,4566574,7540023,1621963,7924270,7578750,6669494,5857192,6409805,2030792,4401779,5737991,8241088,4739746,2776901,7373718,8786697,9211593,6219741,1758331,3863586,6932754,5006164,8200302,5925033,1962127,2728149,8540191,9044326,6171264,4224899,9248672,5911026,6974502,1950317,4998611,2561569,2891845,3243957,8806335,8058303,8791778,1475708,3335281,7841186,9153228,5532135,5453994,5966369,4194824,3612686,8645385,9952621,1211349,2806289,4358520,7454330,5964035,2415313,8897384,6479431,1467330,6496185,8941055,8369903,5015502,5586105,4288482,3266204,1793212,6083923,6920394,1272048,7913696,1253234,3975372,9038970,7229522,7319061,4729995,9990386,5756942,4622741,8179565,1901840,2060729,6308593,2311767,6058517,9440521,4506286,2667724,2707412,9264328,7481658,7283767,4022613,7292282,7722808,1607543,3303695,9334091,4429382,7483169,2624877,7084777,1376693,3797668,1654510,6480667,4619720,9884094,5862548,9422256,4009429,6273574,8836135,8204696,7987167,1890991,6920944,2501831,7627502,3287765,9907714,8246444,2397872,6005920,6982330,5250473,8604049,6665649,4658172,8910156,2989349,2872344,5909790,5837142,1457168,6535461,2226623,1763137,9385314,1692550,9805267,2558547,7501022,7434143,5598876,5709976,6785263,6020614,1443572,3101684,3374557,4787536,3978530,9441757,1930130,9930648,8580841,9180145,1442749,9766128,9032516,7260009,3941177,6559494,9137985,4546386,3074356,5515518,9012878,2276748,4035247,9025100,6259704,9377487,4794540,5761474,2752593,3987731,8114746,2718948,3247390,3037689,3311660,8790679,5536666,2222091,5232482,8974563,4368682,3214843,8420028,8806335,8848220,7466827,6930969,8109664,5539825,4431991,9777114,1658630,1989456,4565338,4458084,9845504,1885635,9934494,5555755,2949661,1578155,8792465,5856231,1098190,3172134,3951339,2971771,6514724,7918090,8303161,8927734,5148162,3115005,8331726,8686172,9277099,5245941,8956710,9073989,9181930,1564422,7557327,9082504,3478927,5851699,1516220,6011001,3210998,7561996,3128875,3419052,8286682,3075180,4222702,9359085,4364151,5275878,8327606,8856597,5770950,4176971,9744155,7107299,3555694,8808120,1351837,1360076,6263137,8084533,7500198,4953704,5528839,7879226,7829376,8476745,9084976,9013153,9360595,1519927,9272705,2386062,6703552,2987976,2653991,7962310,6720443,7441421,9816116,8835861,1495346,2436462,3964523,5086776,2948287,9331619,3395294,2654541,4939971,5529388,2443054,8942016,4211166,4622741,4996826,3370712,8998596,8414672,6178268,8606521,4673553,8279541,6275634,5673858,3244918,1834274,1526931,7676940,2071578,4389968,8847671,8347793,5627304,3150848,6094223,3139175,7662246,4629882,6958709,6080078,6604812,6250503,8088928,8115158,5547515,6602340,9526214,7144378,6659744,2319869,8054733,1483261,5373657,5053268,2558273,4960433,3183807,8498855,9974731,2374801,8405883,1960617,4945877,2526550,7739700,5407440,6752304,8544998,3976608,6499618,1631164,8728744,3698516,8548431,5066864,5619064,5310623,6882492,6150802,6524063,6251052,3584671,8603775,2213165,7723495,4073150,9552993,9999450,8793975,6491241,4660095,9930786,4196609,8377456,4691268,3305343,4692779,5583221,8125320,4233688,4325836,7907516,4892318,4463714,3417266,1417343,9836441,1187866,2645751,7921936,2998275,2052352,5054229,9570159,9308273,7085052,4329132,6040390,5786056,7763320,5193618,8289703,5839752,2938400,9261032,2333740,8758682,8836135,3190261,2023376,1993301,8853439,8487869,8288879,1314758,9366775,4800720,2819610,1451126,3274719,2042053,9648025,2290206,7490997,1195281,1606033,1245407,3106765,2140518,9124389,8877197,7443206,5344268,1341262,5363906,7709762,3759902,4991333,2916427,3489913,1779754,4042251,5729888,4771057,3584533,4547760,5565505,7738327,7732559,5686904,2558273,2051116,4332153,9457275,9341644,4819946,2643692,7991149,1085830,4004486,4451492,8963714,3540176,4449020,5051483,2061691,2676651,5276153,9197860,7980850,3026428,2856414,8852752,4922805,8302612,1072509,9081542,9056823,8404922,6097930,3939804,4919097,7398712,5407302,6692565,2214401,5561660,7238311,9212554,4992568,6093811,5223144,1899368,7665542,4582092,7409286,9964294,1835372,4815963,3387054,7423294,9401657,1044494,8743713,6644226,8916748,6272750,6561965,4788223,4657897,3687393,6183486,3993774,6385223,8807159,2952682,2643692,7253280,2452804,5163818,3558853,6846511,3127502,1926834,8465347,4805801,2904479,2171691,8575622,3015853,8413299,9511245,3628479,4821868,1020324,9179046,5233032,4244400,3795471,2762893,2857376,7661010,6360778,4951644,1309265,8922927,7212219,2014862,9049407,5376403,5611511,2232940,5183456,2757949,4638946,6997848,7474517,6429168,1501800,5802124,8222274,9924880,8694000,3835708,8349304,5278213,1097091,5408126,6541915,8095245,3619415,6916961,2786102,4845352,7466827,3578079,8144683,4338470,1635971,9640609,3117614,1855010,5728103,6300903,7430709,1900192,3673660,6037643,5595443,7049072,6462951,3585632,8084533,1853363,8477294,2266586,1465270,1276580,2511856,2895828,4337097,3626968,7087249,8985000,9414840,7458724,1141174,7457214,1602325,4407272,7694519,5595306,3399688,8429092,5586380,2441543,4488845,6415573,9871047,2366287,5840713,7647552,8970306,3026016,8186569,5060821,9175888,2428634,4199768,7791061,9595565,2325363,2228820,2966415,5135116,7646453,5928054,6217681,2612930,8201812,4628372,4872955,3597305,5363082,6790893,7307388,2064025,6947860,9389984,2415451,4464401,8022598,7566390,6675811,3299850,6845413,9396438,2775527,1796508,1665359,7119934,1264907,2772644,8598693,4670669,2209182,5293182,1299514,7853683,7307525,3205093,1643661,5012481,3448440,2148208,6146820,6530380,5167251,4132614,4331054,9009719,4979522,3280487,7764144,6472427,9053253,4821456,3984985,4425674,7194503,2939361,6038879,6136795,9609985,1561401,3836807,7960662,8419204,4684951,6060989,9063690,5382308,6334548,5833572,9388198,8814849,5744033,4868148,1200775,6155197,5857192,1321624,9067535,4156234,2739959,4067108,3602661,8168441,4998748,5604919,4829833,5483520,9798538,3330474,2504852,4206909,1574035,1379440,9239746,3629440,8028366,1766845,8773513,1564834,9511657,7040695,7232955,4622467,6376022,7167312,3728591,2885940,4396835,8868270,7126800,9963195,6857360,8126831,5344406,3878555,7389236,9083740,5007949,4776962,9162017,8039764,2822631,7905044,1516357,9784667,6493438,7841873,9634292,3971252,2542480,3446517,4340805,4752929,6867660,3490188,3628890,9403579,5384231,3443496,9004089,6138854,1594360,7386215,9240707,3856857,5428863,2509521,9643905,7018722,9202941,5178375,4411254,7385116,1032135,5022506,3187652,5829727,7550186,7026824,2408035,9947540,9273666,7087936,3519851,2677337,8457244,2005661,4680969,7654968,2781570,4380081,5025390,3519851,9721084,1380264,2092041,1889892,2931121,7856018,3507766,5226303,4501617,8759506,6521591,6303924,5419250,4346023,2481506,6510330,3082870,7123367,4848236,7687789,8214035,6017868,4840545,8739181,4010116,7725280,6304473,6717834,6878509,8717071,7901062,6616348,4601318,7868927,3206878,3577255,2269744,3181472,1819305,4741119,5834259,1561264,7062255,9452194,2613754,3131347,7384979,6041351,2607711,7039733,7047561,2902420,1954162,9234252,9188522,8082885,4378570,3174057,3865371,2107696,6976425,7944458,9164901,7252593,5173294,8744537,1974624,9989013,4207321,5217926,2511032,1816970,1975036,7593170,5195953,3204681,2588897,5102981,1978607,2856002,7484954,7652359,6692153,1021011,7428237,5203643,2542892,8071487,3258789,8846160,9323516,7058685,6720581,9020843,3444595,1471038,4219131,5868041,4378570,3913986,5849914,1166580,6608795,5926269,9542007,7833496,7679412,9654891,2661956,2453765,9437225,8606246,1918182,2806838,9062179,7191619,1914337,6861343,9976791,2286773,4190429,2203964,6232238,7523681,6100128,7373992,6461715,7533432,4364425,3069549,5995483,3859741,9647476,2696838,9232879,3760177,9996704,3229263,1862838,5615081,5493682,2845703,2029144,3163070,6955413,6317382,9031143,8281463,4034286,6611404,5656692,6529281,2557037,7679138,3738891,7174179,1447692,4899871,1031311,2919723,9078796,6147369,9996154,1052597,5393844,9947265,8596496,4228469,3644683,5696243,9690322,3616119,1088714,2409408,9116287,6616210,8487594,6966949,9066986,8876098,1753799,3326492,2843505,4818298,3586044,6671554,9584304,9400833,3439788,9963745,9062454,5329025,4675338,4869110,9144851,4437484,6226333,2525177,6007293,2460083,9634979,2118820,6699844,6908035,2795578,3744247,9154464,7273742,2250106,4507247,1230575,4279830,6382064,2348434,8891067,3391723,4348358,9550247,3103195,8312500,1096817,1399078,1557693,9679061,5311035,8970581,3799728,4678497,3626144,2506088,5866256,6802154,2960510,8350540,3022857,9459060,2306274,6918197,1693374,6662902,2821807,9658737,3177215,7515991,7572296,6487258,7247650,3706619,2758773,1652862,7224166,6737197,6782653,9508499,6613464,6106307,7986755,3156753,1912689,1157928,3418365,2435089,6668395,2821121,4458084,6213150,7384841,4956588,5656692,9468399,7376190,1529541,7625167,8110488,4155548,4326660,9321182,7022293,2455001,2438247,6575973,6285659,7469299,7221694,2205200,8063247,1420089,6965988,1546844,1101211,1029525,1977233,7771560,1325469,1002197,7301620,8807983,6497558,9104614,4806625,6226608,6400192,4939971,1838119,5926544,5520736,1008239,7172256,2969299,1701065,2148345,9481033,6402252,3724060,5954696,3031097,1415832,4303314,2261367,1832077,2679534,9446289,6289642,5956481,6198181,4659408,2550033,5247451,2534515,3963287,5095428,2133926,2739273,8188217,3215667,3772262,5836044,9515914,7171432,1232360,3201110,3740264,8057205,2948013,2683380,3211685,3389938,5149536,5809814,2937438,1515121,2497161,1916946,9803070,3426055,2634490,2554565,6387695,1088165,3881027,9005325,4338607,8863464,7781997,8261825,4775314,5127700,7733795,7307662,2691619,7675155,7405029,3044555,5825195,7004577,1170974,5709426,6961456,8078491,6280166,4126296,6142974,3652511,6972854,8634674,3751251,3765670,8268692,6040664,6930145,7486328,5643508,7432495,6320541,5509338,5313095,5205291,1573486,7694519,9343841,2139007,5612060,4143325,1307479,9871459,7109771,6907073,8700454,8613937,1154495,8917709,7844482,8447906,4566436,7239135,8489517,6052200,3839691,8229141,2835678,4199905,4175323,8708282,8194808,4871032,1574859,5727005,5008087,8324310,1463348,2027908,8441726,9971160,4810195,5793334,3275268,9397537,4217071,9775192,7305740,5373931,9941085,2398422,1982727,9201156,4322540,4933517,4495849,5232894,6585449,7331008,2030380,7920013,2480133,3811264,4413452,9220382,1735946,9804443,7867004,1716995,4794265,9334091,9085937,6289505,6787734,2436599,6362701,1682113,9238510,2713180,9974731,8810867,5440124,1605346,7554306,2156448,8995162,1488616,5659713,9083602,1474746,8179290,3266479,6432189,3670639,3946395,9397125,2223464,2407348,7623107,5608078,1825759,9384216,8912216,1553573,3422897,2014999,9478012,3343109,1127990,4734252,2919174,6914352,5589126,6739257,9217086,7136825,6427658,1636795,4750732,8867584,3355194,6962417,7476028,3676681,3311248,7041381,5358688,6461715,2466674,1160812,5658477,7668701,3436492,1520339,1155868,7340484,5543807,9931472,4916351,4708572,9482269,6733489,3684921,1550277,1217529,7894882,8505722,1027053,1472686,7768676,7660186,6224548,1642013,7472045,9516738,9112304,7475891,9356063,7386627,1142272,2380706,6537246,8979507,5205017,6678558,9957977,7552108,7161132,8668594,6944839,1344284,2669509,6835388,1734024,1395782,1526519,2048233,4932006,8337219,7240371,8092910,5380798,6250778,3054855,9382293,7395965,8190826,7143417,6188568,4846725,3462585,3192459,4239730,2046173,3249038,7091369,8025619,6921768,7681472,3949142,9657363,7432083,9947952,7155502,5621810,9702407,4531005,9706253,6277420,4844802,7171432,7510910,7433593,5931900,8650329,8901092,5858154,4095260,4981582,3058837,1055618,3214157,8112823,8584686,2161529,9165863,8723663,3921676,9294815,7104553,2218933,4856338,6214111,9738388,4507385,9814605,5619476,3073944,6663589,6171264,3944747,7595642,2061828,1291549,3983886,9349472,8080001,1524597,7195190,5899627,8965774,1866134,8026992,2628311,2957077,8510116,9107772,6343338,8253860,4008056,8646896,4668334,3932388,3253845,5886444,5178100,2396499,2014038,2950347,5752685,4460418,2222091,3933761,6116195,6655349,5753921,7576416,4029617,9855392,7905731,3363021,5107925,9814193,8291625,3396118,7727340,8709106,7378662,2883880,9994369,1283721,6381515,9586502,9243728,1684173,5730987,8065444,5034179,1582687,1839355,8079864,3111434,6681854,4377883,6971893,4306335,6193237,1788269,6387695,2837463,4385025,5243469,3174743,4987213,4790969,8780242,4800720,2618560,4176147,4818984,7139160,2503341,3850814,9791671,2962158,9929962,5429962,5096252,3986495,4558197,7627365,9094863,9817352,4991607,7182281,5376953,5630050,8035095,2510208,6003860,2938125,7106887,3171859,1955535,7287338,1773712,7754669,7495941,8222000,4877899,7259323,4678359,1366531,4223800,3587005,3707168,2965866,2295425,1219451,7376739,3728454,9970886,6685424,5303894,2315887,9703781,2909561,2175811,2323165,7140121,5034454,7728713,5091583,6640106,2812194,1678405,8201538,2672393,4156784,8321426,5984634,2550033,2953506,6023086,1902389,1477493,4717636,4315399,2133514,6376846,5195816,4818298,9213790,2461318,1505645,7708389,3072433,4026733,2905441,4950271,9309646,2427673,3788604,5009185,8055969,6708496,2996353,3267303,8261962,7856567,5043243,5857742,4757736,8148254,6347595,3138214,7927566,9555328,1061660,9522094,7344879,3679702,9596115,2885391,5208862,1187316,2430694,6269180,7927566,8208404,1305557,1094345,3691787,5673171,5388214,4610794,3382659,1052047,6508132,9796203,1656845,1468566,2053451,3425094,7553344,4655014,8623550,3527130,1465820,9716827,3031921,7952148,3823211,9178497,9751296,2261642,4323776,9275726,9396713,8665298,9065475,3965347,4339019,9221206,8415771,3620239,6043273,4017669,5966918,7879364,1225357,1557693,1418029,5619750,3420288,4062301,4727935,8520965,4057769,9912384,1385345,3190261,1635009,5948928,9135787,8316482,4085784,7848876,2012527,4822143,2933731,4295349,4014236,6482864,3328826,7162643,2271255,2981796,9557113,9432693,9047897,6868209,5119186,8063522,3421249,8389816,6970932,1526794,9981323,6666061,8019989,2235137,9397674,2172653,4471405,9574966,1193222,2005249,3118026,1768218,3572723,3890502,7165664,9276138,4645675,1415008,1691864,3969055,9891784,3438964,9327087,8777359,2208221,2164550,3255218,9043640,4385986,8827209,9126037,7295166,6357345,1478454,2973831,9655166,1058364,2829772,8735198,6611129,8250564,6625549,2459808,6358993,6145446,6513763,8809906,3443222,1175506,7884445,5938491,3910003,2754791,6642028,6344024,7692321,7374542,4383651,1791976,6447158,1875610,7949401,4899871,5562210,9243316,1815460,1476806,2551406,6766448,3296005,1213958,2557037,9905792,9026611,9817352,3179687,7716079,5693908,2177871,2351318,7162918,6483001,7673095,6473388,7181182,7209884,9192642,2536437,6816848,3608978,9982421,6441802,3296966,8742614,5900588,7242019,3370437,5003005,1180038,9520996,3764846,3674896,3289688,2631469,9101318,2526824,8989807,5007400,7113479,5401260,7174453,3273345,5511123,2270706,1593536,6365859,5335891,1730178,7051544,7387725,6149566,5393157,4172851,1414047,7900924,7161407,4330230,4966888,5813796,5835769,2828125,9380371,6140365,6038192,7937316,2771408,5123031,4912918,4870758,1837982,4010116,2574890,6298431,3201385,2466812,6776748,3491561,2513092,7227188,6759307,5692810,9042953,7330047,3757431,8803588,5969116,6781829,1129501,8984313,9088272,2991958,5577041,1259963,3164169,1823287,5426803,6726211,7632995,2600433,4440368,5447265,5885894,7922348,5123031,7642471,7846130,9620559,1999069,5252807,7059509,5707778,4822280,9482543,3017227,8660079,8191787,6408432,2930847,9877914,8539230,9252243,2676239,4667510,2959274,3407928,5126190,6587783,7850250,7819076,3590988,2506912,4833679,3799865,6584762,2210281,4922119,8892715,4637023,7906829,3403945,1856384,9367874,3473297,7413269,3380325,2544815,4784790,7654968,9615203,6342239,9971298,4251541,2117309,4519607,7946517,3183120,1297866,6738845,1051910,3286804,8972640,3738891,2159606,7285964,5103530,6586410,7077911,4817749,6329193,7722259,1603561,5926681,9375427,3019973,4063812,9994644,6939620,2578460,4693328,6574325,7145065,7464492,9687576,1096542,1156280,6125946,6278930,8918533,8050064,3693298,2677200,1683486,6537109,2888824,4219543,1459091,8626159,3761962,7572845,9624130,3825820,3968780,9332580,1971603,1976409,3816619,2862869,9997940,2307785,6790069,4718322,6846374,8813613,1777969,3496368,4872543,9539810,7721435,7458587,2303665,3877731,4899459,2769210,5956069,4456573,4572067,7691223,1483673,7730087,9200744,7586166,8124221,3849990,6962142,1059600,8411376,1920242,4776962,5097625,6823440,6225646,9569747,6536422,7835830,9529373,6981643,4710769,5347152,2032440,9251419,6622802,7945831,8088516,5485855,2476974,2988937,5269012,3038101,7923171,9959075,7870986,2211242,2853256,9069732,7463119,3007064,6093948,3587417,7560760,3138900,7839126,1839767,7027923,5026901,8167617,6376571,7295303,8993240,9487762,3256179,5992187,1379440,4252777,2920959,7083404,4800170,3793411,8635635,1105880,1255706,5607391,8953414,8598556,2320556,7952972,5181121,5320098,5126464,5088424,8310302,2346237,9359497,9002166,7384567,9643218,4989135,3976333,5771224,3207702,6949234,5828079,1304595,2371093,1488204,6173599,6773727,8357406,6408294,9555328,4717910,9692520,1911865,6779769,5003417,3555969,6274536,2307785,9147460,4669708,8062423,2040130,4858810,8818420,2114013,7345428,1764511,8593612,3003219,2669921,6790618,1456893,4204849,9576339,4165985,6714675,8679168,5553833,9517425,4499008,9095275,5443008,2026672,2348159,7412719,4820083,2114974,7480285,6037643,2184051,8626983,2354614,6275634,6289505,8980880,7612533,9296875,2471069,1254608,5995071,1334533,9300170,7675155,9326675,8334060,1420776,9482681,6162338,3772125,9906066,7634506,9190582,6864776,4980621,4321441,2985504,1883026,7451583,1762176,2202453,6793502,6691879,2246124,2810958,2945541,5521011,6893066,9458099,9021118,3825271,6098617,2557449,1967208,7262207,4133438,1194869,4129455,7893096,7865768,4447372,3305892,5086364,4075759,3208389,6939208,4536224,8330490,7111282,5166290,9741546,2888275,8646896,8943939,6785263,8600479,9068771,9970336,1762588,9280670,1178115,1618530,3697692,9509460,6584213,6604125,3295181,7342956,8532638,7602783,2369445,9894943,3896545,5538314,9294677,8260726,6422164,2759735,1321487,3750839,8825698,9824768,3100723,1905136,5832061,8110076,3261810,3254257,4751968,2966964,2386199,6297744,8689193,9639648,4221878,6668258,6972305,7666915,9481719,7949813,2905578,2983993,4068893,1119064,5430648,8445571,1074844,9077972,5795669,9986267,2391555,9248260,9822845,8139328,2283752,1693374,2869735,4131240,6762603,8740417,8077941,2270980,2107284,3566955,7001831,5853759,8375259,3725296,9212966,6295822,7248474,3069274,3972213,5722198,6054946,5055191,8563949,9722595,9314178,1884674,9386138,3497467,6645874,9457138,1390701,1110000,9389160,2602355,2966140,1065917,1773025,4560668,8858108,9937103,9985168,4180130,1220413,3248764,1978744,8799468,8390914,3350250,1365570,5284805,7485504,8485122,2234451,2189544,2404602,6783477,5243881,6506759,1344696,7390609,4827224,8981018,9410720,7455017,4858947,2450195,3420425,7191207,9621932,8185333,4497222,9738250,4422927,8697296,8542800,1031723,7697265,4978424,7184341,8407806,1947021,6649032,3291748,8159240,5358276,1976959,1654510,5760513,1439041,4238906,4916351,4981994,6522415,5391647,4358245,9611770,1479003,5523620,4626174,8002960,7481796,3053894,8994476,3166503,5167526,6147781,4260742,2627899,4039230,4318557,6865875,3765258,6450592,5683197,2331268,5849777,2020767,6841018,1609466,3505157,6818222,9844543,1439590,1806671,4161727,7229934,9302505,7736267,8379104,4578521,1070449,2215637,9368972,1574035,7941986,9432556,1309539,1029113,2759872,6681716,6356933,2844879,7301071,7437988,8677932,7377288,9637863,6880569,6660156,3174057,5158874,5587478,8644012,8555709,2346786,7618026,9019470,7005401,9906204,1703262,4032501,7838989,8333786,1762863,3143569,9122741,3526306,2465850,5283157,4307983,3519302,7056213,3846557,7551559,6949920,1160125,7774307,5189910,6339355,2794616,7558563,6337158,4785751,8296295,8522476,1073608,4164199,9388610,6213287,8196319,8426071,9106262,8256332,2998275,9091156,4796463,4509582,6045196,5527465,9914581,7866455,6419692,9112030,1833175,4547760,9400970,2865753,2384552,8228454,8048828,3656906,7353118,2841583,6660018,9567001,7639175,4403564,3567642,6511566,7309448,8705261,7249710,5712310,2257522,1211624,2218246,7110458,4687561,3014617,1655746,4319107,5145690,5181259,4268157,7204940,2313140,8344085,1324645,8695922,1282760,1873413,4350143,6906112,2536437,9478836,5441497,9173278,8342300,8581115,2676376,3102645,5790725,3300399,2581344,1209014,7187911,4402877,6129516,9254028,8025482,7049758,7237350,6868759,6244735,7693283,1226455,6558395,6015396,6962966,5222869,9681259,5745407,3885696,6958709,6495498,1543685,9283279,5948654,9869125,5851013,2692443,9506988,8744674,4460968,4648147,3575607,1954162,4647460,8678619,3831451,7477539,7618713,7850387,9041580,9737701,4016433,4211715,7136001,1026779,5677841,1975311,8964263,7656478,5381347,7785430,8208404,4928024,3792312,2912307,4417709,7512557,4328857,9718750,5635406,5338775,7167449,1241424,3586044,4579208,2104400,1230850,8892166,5830688,9494354,6495361,4289169,8081100,6983703,6889770,2306961,5557952,7257400,4796051,2386474,3050186,7518600,3436630,6901718,7799987,3918792,9866241,8053634,5555618,7658538,3985122,6106307,4879959,3976608,9416625,6934402,4309494,6746124,1595596,5348388,2456649,5898254,4907012,1169189,4647735,5388626,6224136,9518524,2193664,2929748,9683593,4296173,3884460,1203933,4047058,8309890,5801712,9778625,5489837,8029602,6043823,1441375,1160125,5433120,4456710,7173080,1354446,1911590,3964248,7478637,7652221,1706008,7592483,2295013,5852111,9839462,9779861,7191894,7055389,4018493,3069549,7088897,2740234,8468368,7775405,2202453,1168365,6172912,1716995,6445648,1971328,6488357,9616577,6997436,4256210,4597885,4251403,6260665,4079055,5777130,4956176,1926696,4624389,3939117,7569137,8367843,3940353,6426834,5414031,2072952,1567993,3523422,5414718,2348022,6912017,1646820,1932601,7998428,9695816,9699523,1423660,1212448,3342422,7540847,6507171,9365539,3629714,2051803,7540298,3961776,9458236,1759292,7292007,5433807,1079238,6490966,9811035,2019119,3625869,5026763,8080276,6429992,5289886,5218612,9552169,2538909,9989013,8544448,8159515,6794601,4868148,7567077,4892868,5590774,5479263,8266906,3542373,2303253,3980590,2714279,2693130,7217575,1203659,2055099,9571945,6062225,1927520,1273422,6836624,1369415,1206130,3703598,5902236,9379959,3092895,3758117,9898788,7712097,9604354,1842376,1853500,4512878,3268402,3922088,6190216,8310577,5100921,7714981,6142974,6286895,6352264,8973876,8173522,9187973,8870880,2830322,8990081,9592819,8423873,4667098,3257827,1758468,2822631,2489883,3597442,8758407,3192733,9264739,3965072,4136734,4235610,1190887,2005386,6793365,8823089,9379272,2474227,2320968,8770904,6902542,9323104,5511398,8132461,2687774,9538986,7251495,8858795,2219345,1334396,3525619,9166824,3521362,6780456,2744628,6460342,3387741,4477172,2120056,1148727,2329895,1354995,9301132,2203689,1208877,8199890,9995468,3802337,5022644,2997863,2789672,5896057,8815811,6691329,1890853,3052383,8181900,4440643,3005828,5410736,9325714,7986343,2078857,7098373,9154190,1204071,8104995,1948257,1367492,1446594,4737823,6863677,6014160,5766830,8911804,3673385,7483993,9615615,1196792,2820159,5404418,2107421,2103164,4727249,9409347,8449142,6057556,8186843,2250930,2623092,2266860,3613098,8221176,3921401,1190063,1504409,3352722,9422119,7835418,6958709,2368209,4004486,4603790,8584686,4846313,5992187,1894561,9653381,9572631,3024642,3194107,7834320,4545974,6243225,5866668,5358825,6606872,5392471,1362960,9954544,4158294,7925231,6069641,9396301,2946640,7708389,5514968,6014709,1372299,3421661,5150497,4008468,5298126,2243103,7428649,8902191,7824295,2916702,9393417,3995971,7999801,1792938,2502792,8146469,2937164,6939071,5904022,8729019,9300720,4910720,6877136,9117935,3636032,9279434,1667831,2534515,8511627,9510559,1428466,3602523,6937561,3283370,7483444,3457229,2033676,2848999,9641845,6750656,3414657,9519485,2771545,7396926,5259674,8880355,3356979,7401870,7537002,7822784,7258224,7619949,1351837,3986770,5388900,2783355,5885345,7711685,7533843,8645797,5894409,7084091,2023925,9585128,3241348,5181808,8486633,7509124,4420455,2102203,7391571,6408020,4552703,5873672,2610733,5396316,5814620,7840362,9709548,5589263,4772842,6615524,1190475,4657211,4590332,7197799,6405685,2400756,4575637,7341857,1358840,9191680,5042007,5779602,2113876,8623138,6945663,8385284,6030639,1211624,8272674,3876358,5544769,8496246,3642486,2145874,6711380,2377685,7096176,7819900,7232131,8041687,5540786,4132888,1181274,3310287,6814514,8714462,1154083,6763565,8845474,6383575,1052734,4477722,8870193,9541183,5229187,8721603,5181121,6255996,2205200,6456222,2373291,1638992,8686996,9980773,8556671,2596588,8093048,3568054,8504623,7560211,8314971,7435653,9206100,4283401,6929321,7892547,6791992,1301025,7579025,2009506,7302032,6144348,1744049,4652954,4263351,2906402,5619476,5228500,9547088,4249618,3318664,9977890,4474014,5451385,3122970,4170928,6637084,5580062,3993637,6038879,2408584,4396011,7067474,1791290,3602249,5070022,4352478,5560974,5258575,3315643,7344192,6619781,4021240,2025161,2780471,2710296,7075027,5007125,6253387,7836242,2111541,1915847,1898132,8355621,7295303,5968704,1875610,7719787,9693756,3544433,4869796,7704544,1145706,3255493,6317245,3472610,1031860,7589187,1587219,2316024,4919235,4710357,8832290,8419067,9547775,1521026,7727890,1486557,8126968,6568695,9818313,4580718,7411621,1897857,3689453,8011749,5526229,1439590,8686996,6624313,9006011,1031448,7397201,7323867,1022659,7661285,8611053,3187515,2266174,7030807,1988632,5002456,1447555,3030685,2144638,9576477,4895065,6220428,6371353,4662017,9210083,5910064,9719985,6841293,2452667,9932708,9657226,7213043,4825027,6706710,9017822,1225082,2321380,5676330,3470275,4499008,9314453,1728942,7214279,5987243,5545181,1679092,4130966,3308502,1485870,3416030,4101303,8604049,4545288,2805877,1714660,7760848,5083892,8944076,8083297,4341766,6709320,7851348,6984664,5069198,3818130,8206207,6047531,6206283,2856552,1208740,7201782,8676147,8264846,4168457,4111053,4267471,6577621,1911727,1806671,5765869,4645263,9599685,4241104,9358261,2449234,8053222,9979949,7151107,1476669,2177322,6751754,1148864,1124420,7578201,5074142,1534347,3101135,8968246,2674316,5595993,3296829,1451263,9923645,3144943,9086761,5283157,1004257,4766937,7540847,3200012,2027496,3750564,3505432,5908416,9821609,3038925,8026718,5832611,6608383,9044326,6085433,6710281,7287475,6673751,9109970,6131713,8546234,6405960,5238250,1616333,1514984,6766036,2796127,5320922,7186264,8038940,6961318,2970397,8315383,1568405,8081375,4109130,7023391,7482070,1615234,2262878,9819137,4189880,1166305,1107666,7260147,2496063,1575958,6237045,1971740,8670928,6546585,3623809,8240676,3325531,5762435,4368408,4905502,4432128,6977523,5828079,7759201,8335571,8038803,2721008,9185089,3098388,5313919,6298019,5243469,1023483,4491729,7177612,1928619,5698440,4224899,1935623,4813766,4405349,8582626,1045181,9804031,9238922,2783630,3260299,8215820,3778030,2175399,7035339,5900039,7653457,9932296,8077117,6630218,7855743,2438110,8619705,4472229,5127288,2822357,5519500,7355453,5281784,1621139,9760635,1564010,5795806,1028564,1467605,5366516,5515106,4708984,8016555,4503128,6819732,4639083,2340744,7748764,2092453,2947463,7022430,6272064,3833236,3221023,2265899,3006378,2264389,9246887,5345092,3754959,8768981,1659179,9620010,1245819,6007843,2458297,6713989,5858016,8057067,8871841,4948623,1234832,6412139,5526779,6626510,4506011,5199249,7400085,1258590,1335357,2441131,9518112,9328323,7513244,3718154,2872482,8686172,9312942,6069915,4521530,3169250,7329635,2481369,9345626,2539459,6019790,7796005,9426788,2333190,2661682,3400787,6518432,2717163,6953353,8526733,1576919,1944000,9968826,4507247,3821975,3500900,5690200,9840835,7295028,8545684,1834411,5398788,4384613,5723571,6194335,7624618,2287048,1958282,6211776,7065826,3871688,7312057,9001205,7084503,8918945,8507644,6545211,6089553,6200378,6205596,5275878,5133193,3368927,6631866,2766326,1216979,2129257,6648345,5746505,3151260,1655197,6860656,8165008,3309600,9723968,1857208,5513595,5124679,9537612,9171768,9135513,3667617,5696105,5065490,1733062,1155456,7295852,8720642,4797424,8729431,8618469,2940185,1174819,8349166,5381072,4946838,9492019,6145721,8015182,2375488,8656646,7076538,8943801,5053405,9153228,6228530,9325851,8660079,5352508,6609756,8235595,3863174,6553588,5775894,5746368,7021057,6976562,6134460,3887207,3048950,2425750,9270370,2942520,1540664,3841339,4136734,4060379,6738983,2458023,8454223,6641342,3450637,7791198,2164138,2475189,2497436,5165878,1277404,9094314,4799072,8011611,2963394,9312530,8679718,6637908,5223281,1418579,9493942,6712203,2990997,8991867,8163360,4156784,2006210,2811096,4720794,8685211,6300903,6822616,2452804,7695617,2647125,7638488,7735992,9739898,5805557,2532318,6160552,5288925,7921936,3402160,8034545,2010192,3913024,7668701,8862503,8278717,8186294,5577865,2893081,5138687,9538436,7876892,3328140,5435317,4574264,1331100,9287811,6335372,2491119,5052169,8125869,5954284,6572814,9105850,7187225,7311096,9235763,4366760,3604034,9326538,5971450,2090805,3220886,7086151,2029556,9172729,6246246,1085006,8185333,1558105,7721298,1673873,8433761,5778503,2401443,1425445,3955734,7078598,6142837,9639099,8200164,1102584,2389770,4702804,7423568,6611816,5854034,6531890,4533752,5199249,7982772,7802185,7578750,3470687,5305953,2196548,8727920,3662261,1259277,1384796,4084274);
+
+# Cleanup
+DROP VIEW v1;
+DROP TABLE t1;
+
--echo End of 5.5 tests
--echo #
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 30f4419bd7e..e47d549cf61 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -1720,6 +1720,22 @@ select * from t1;
drop table t1;
--echo #
+--echo # MDEV-22191: Range access is not picked when index_merge_sort_union is turned off
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_optimizer_switch="index_merge_sort_union=OFF";
+CREATE TABLE t1 (a INT, INDEX(a));
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+explain
+SELECT * FROM t1 WHERE a > 5;
+SELECT * FROM t1 WHERE a > 5;
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1;
+
+--echo # End of 5.5 tests
+
+--echo #
--echo # BUG#13731380: RANGE OPTIMIZER CALLS RECORDS_IN_RANGE() FOR OPEN RANGE
--echo #
diff --git a/mysql-test/t/range_innodb.test b/mysql-test/t/range_innodb.test
index a17ef3f1146..03e9e2f0678 100644
--- a/mysql-test/t/range_innodb.test
+++ b/mysql-test/t/range_innodb.test
@@ -46,6 +46,32 @@ explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250;
drop table t0,t1,t2;
+
+--echo #
+--echo # MDEV-10466: constructing an invalid SEL_ARG
+--echo #
+
+create table t1 (
+ pk int, a int, b int,
+ primary key (pk), index idx1(b), index idx2(b)
+) engine=innodb;
+insert into t1 values (1,6,0),(2,1,0),(3,5,2),(4,8,0);
+create table t2 (c int) engine=innodb;
+insert into t2 values (1),(2);
+create table t3 (d int) engine=innodb;
+insert into t3 values (3),(-1),(4);
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='extended_keys=on';
+
+explain
+select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
+select pk, a, b from t1,t2,t3 where b >= d and pk < c and b = '0';
+
+set optimizer_switch=@save_optimizer_switch;
+
+drop table t1,t2,t3;
+
CREATE TABLE t1 (
pk INT PRIMARY KEY, f1 INT, f2 CHAR(1), f3 CHAR(1),
KEY(f1), KEY(f2)
@@ -87,3 +113,5 @@ select * from t1 where a=10 and b=10;
DROP TABLE t0,t1;
set @@global.debug_dbug="-d";
set @@optimizer_switch= @optimizer_switch_save;
+
+--echo # End of 10.1 tests
diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test
index 7df326edb44..1d0256b1b7e 100644
--- a/mysql-test/t/selectivity.test
+++ b/mysql-test/t/selectivity.test
@@ -1266,5 +1266,17 @@ set optimizer_switch= @save_optimizer_switch;
set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
drop table t1,t2;
+--echo #
+--echo # MDEV-21495: Conditional jump or move depends on uninitialised value in sel_arg_range_seq_next
+--echo #
+
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 SELECT seq, seq from seq_1_to_100;
+set optimizer_use_condition_selectivity=4;
+ANALYZE TABLE t1 PERSISTENT FOR ALL;
+SELECT * from t1 WHERE a = 5 and b = 5;
+set optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
+drop table t1;
+
--echo # End of 10.1 tests
diff --git a/mysql-test/t/stat_tables_innodb.test b/mysql-test/t/stat_tables_innodb.test
index 04e81de8f9d..008ca6911e9 100644
--- a/mysql-test/t/stat_tables_innodb.test
+++ b/mysql-test/t/stat_tables_innodb.test
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
+--source include/have_sequence.inc
SET SESSION STORAGE_ENGINE='InnoDB';
@@ -9,4 +10,23 @@ set optimizer_switch='extended_keys=on';
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
+--echo #
+--echo # MDEV-22851: Engine independent index statistics are incorrect for large tables on Windows.
+--echo #
+
+CREATE TABLE t1(a INT) ENGINE=INNODB;
+INSERT INTO t1 SELECT 1 FROM seq_1_to_60000;
+
+SET @save_use_stat_tables= @@use_stat_tables;
+SET use_stat_tables= preferably;
+SELECT count(*) FROM t1;
+CREATE INDEX idx ON t1(a);
+ANALYZE TABLE t1 PERSISTENT FOR COLUMNS (a) INDEXES (idx);
+SELECT * FROM mysql.index_stats where table_name='t1';
+SELECT * FROM mysql.column_stats where table_name='t1';
+SET use_stat_tables= @save_use_stat_tables;
+DROP TABLE t1;
+
+--echo # end of 10.1 tests
+
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/stat_tables_partition.test b/mysql-test/t/stat_tables_partition.test
index 1316e5cca11..11b74818d82 100644
--- a/mysql-test/t/stat_tables_partition.test
+++ b/mysql-test/t/stat_tables_partition.test
@@ -11,7 +11,33 @@ CREATE TABLE t1 (pk int PRIMARY KEY, a bit(1), INDEX idx(a)
INSERT INTO t1 VALUES (1,1),(2,0),(3,0),(4,1);
ANALYZE TABLE t1;
+DROP TABLE t1;
-SET use_stat_tables = DEFAULT;
+--echo #
+--echo # MDEV-21472: ALTER TABLE ... ANALYZE PARTITION ... with EITS reads and locks all rows
+--echo #
+CREATE TABLE t1 (
+ id int(11) auto_increment primary key,
+ c1 int(11) DEFAULT NULL
+) PARTITION BY RANGE (id) (
+ PARTITION p0 VALUES LESS THAN (4),
+ PARTITION p1 VALUES LESS THAN MAXVALUE
+);
-DROP TABLE t1;
+insert into t1(c1) values (1),(1),(1),(1), (1),(1),(1),(1);
+insert into t1(c1) select c1 from t1;
+insert into t1(c1) select c1 from t1;
+
+select count(*) from t1;
+select count(*) from t1 where id <4;
+flush status;
+set session use_stat_tables='preferably';
+
+--echo # Must NOT show "Engine-independent statistics collected":
+alter table t1 analyze partition p0;
+
+--echo # Should not have Handler_read_rnd_next=34
+show session status like 'Handler_read_rnd%';
+drop table t1;
+
+SET use_stat_tables = DEFAULT;
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index d5a40419185..8f1ad51ca50 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -2075,3 +2075,91 @@ insert into t1 values(2,1),(1,2);
select (select c1 from t1 group by c1,c2 order by c1 limit 1) as x;
(select c1 from t1 group by c1,c2 order by c1 limit 1);
drop table t1;
+
+--echo #
+--echo # MDEV-22498: SIGSEGV in Bitmap<64u>::merge on SELECT
+--echo #
+
+set @save_sql_select_limit= @@sql_select_limit;
+SET sql_select_limit=0;
+
+CREATE TABLE t1(b INT, c INT);
+CREATE TABLE t2(a INT, b INT);
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+INSERT INTO t2 VALUES (1,1),(2,2),(3,3);
+
+let $query=
+SELECT sum(a), t2.a, t2.b FROM t2 HAVING t2.a IN (SELECT t2.b FROM t1);
+
+eval EXPLAIN EXTENDED $query;
+eval $query;
+
+SET @@sql_select_limit= @save_sql_select_limit;
+
+eval EXPLAIN EXTENDED $query;
+eval $query;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-17606: Query returns wrong results (while using CHARACTER SET utf8)
+--echo #
+
+CREATE TABLE t1(l1 varchar(10), i2 int);
+INSERT INTO t1 VALUES ('e',2),('o',6),('x',4);
+CREATE TABLE t2 (v1 varchar(10) CHARACTER SET utf8, KEY v1 (v1(3)));
+INSERT INTO t2 VALUES ('k'),('rid'),('f'),('x');
+
+EXPLAIN EXTENDED SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+SELECT * FROM t1 where ( t1.l1 < ANY (SELECT MAX(t2.v1) FROM t2));
+DROP TABLE t1, t2;
+
+--echo #
+--echo # MDEV-19232: Floating point precision / value comparison problem
+--echo #
+
+CREATE TABLE t1 (region varchar(60), area decimal(10,0), population decimal(11,0));
+INSERT INTO t1 VALUES ('Central America and the Caribbean',91,11797);
+INSERT INTO t1 VALUES ('Central America and the Caribbean',442,66422);
+
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='subquery_cache=on';
+
+SELECT
+population, area, population/area,
+cast(population/area as DECIMAL(20,9)) FROM t1 LIMIT 1;
+
+SELECT * FROM t1 A
+WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = B.region);
+
+SET optimizer_switch='subquery_cache=off';
+SELECT * FROM t1 A
+WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = B.region);
+
+SET @@optimizer_switch= @save_optimizer_switch;
+
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 VALUES (2),(3);
+EXPLAIN
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+
+EXPLAIN
+SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1);
+
+EXPLAIN
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
+SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1);
+
+DROP TABLE t1,t2;
+
+--echo # end of 10.1 tests
diff --git a/mysql-test/t/subselect_exists2in.test b/mysql-test/t/subselect_exists2in.test
index 5a8ddb3612f..7ffb4bf0633 100644
--- a/mysql-test/t/subselect_exists2in.test
+++ b/mysql-test/t/subselect_exists2in.test
@@ -828,5 +828,117 @@ DROP TABLE t1;
--echo # End of 10.0 tests
+--echo #
+--echo # MDEV-23221: A subquery causes crash
+--echo #
+create table t1 (
+location_code varchar(10),
+country_id varchar(10)
+);
+insert into t1 values ('HKG', 'HK');
+insert into t1 values ('NYC', 'US');
+insert into t1 values ('LAX', 'US');
+
+create table t2 (
+container_id varchar(10),
+cntr_activity_type varchar(10),
+cntr_dest varchar(10)
+);
+insert into t2 values ('AAAA1111', 'VSL', 'NYC');
+insert into t2 values ('AAAA1111', 'CUV', 'NYC');
+insert into t2 values ('BBBB2222', 'VSL', 'LAX');
+insert into t2 values ('BBBB2222', 'XYZ', 'LAX');
+
+let $query=
+select
+ (select country_id from t1 where location_code = cl1.cntr_dest) as dest_cntry,
+ (select
+ max(container_id)
+ from t2 as cl2
+ where
+ cl2.container_id = cl1.container_id and
+ cl2.cntr_activity_type = 'CUV' and
+ exists (select location_code
+ from t1
+ where
+ location_code = cl2.cntr_dest and
+ country_id = dest_cntry)
+ ) as CUV
+from
+ t2 cl1;
+
+--echo # Must not crash or return an error:
+eval $query;
+
+eval prepare s from "$query";
+execute s;
+execute s;
+
+drop table t1,t2;
+
+--echo #
+--echo # MDEV-20557: SQL query with duplicate table aliases consistently crashes server
+--echo # (Just a testcase)
+--echo #
+
+create table t1 (id int, id2 int);
+create table t2 (id int, id2 int, a int);
+create table t3 (id int);
+create table t4 (id int);
+
+--error ER_NOT_SUPPORTED_YET
+select (select 1 from t1 where (exists
+ (select 1 from t2
+ where t2.a = (select t4.id from t4 where t4.id = t3.id) and t2.id2 = t1.id2))) dt
+from t3;
+
+drop table t1,t2,t3,t4;
+
+
+--echo #
+--echo # MDEV-21649: Crash when using nested EXISTS
+--echo # (Just a testcase)
+--echo #
+CREATE TABLE t1 (id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id));
+CREATE TABLE t2 (id INT NOT NULL AUTO_INCREMENT, ip_id INT, PRIMARY KEY(id));
+CREATE TABLE t3 (id INT NOT NULL AUTO_INCREMENT, storage_method_id INT, storage_target_id INT, PRIMARY KEY(id));
+
+SELECT
+ W0.`id`
+FROM
+ `t1` W0
+WHERE (
+ EXISTS(
+ SELECT
+ V0.`id`
+ FROM
+ `t2` V0
+ WHERE (
+ EXISTS(
+ SELECT
+ U0.`id`
+ FROM
+ `t2` U0
+ INNER JOIN `t3` U4 ON (U0.`id` = U4.`storage_target_id`)
+ WHERE (
+ U0.`ip_id` = V0.`ip_id`
+ AND U4.`storage_method_id` = (
+ SELECT
+ U5.`storage_method_id`
+ FROM
+ `t3` U5
+ WHERE
+ U5.`storage_target_id` = V0.`id`
+ LIMIT
+ 1
+ )
+ )
+ )
+ )
+ )
+);
+
+drop table t1,t2,t3;
+
#restore defaults
set optimizer_switch=default;
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index 544bcd994ed..2c117fe00d6 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -611,3 +611,19 @@ FROM t1
DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # MDEV-23535: SIGSEGV, SIGABRT and SIGILL in typeinfo for Item_func_set_collation (on optimized builds)
+--echo #
+
+set @save_character_set_connection=@@character_set_connection;
+set character_set_connection='utf8';
+
+CREATE TABLE t1(a DATETIME, b VARCHAR(50)) ENGINE=INNODB;
+INSERT INTO t1 VALUES ('2019-03-10 02:55:05', '2019-03-10 02:55:05');
+CREATE TABLE t2(a VARCHAR(50)) ENGINE=INNODB;
+INSERT INTO t2 VALUES ('2019-03-10 02:55:05');
+SELECT * FROM t1 WHERE (SELECT 1,CONCAT(a) FROM t1) = (SELECT 1,CONCAT(a) FROM t2);
+DROP TABLE t1,t2;
+
+set character_set_connection=@save_character_set_connection;
diff --git a/mysql-test/t/temp_table_symlink.test b/mysql-test/t/temp_table_symlink.test
new file mode 100644
index 00000000000..9297b472805
--- /dev/null
+++ b/mysql-test/t/temp_table_symlink.test
@@ -0,0 +1,32 @@
+source include/not_windows.inc;
+
+#
+# MDEV-23569 temporary tables can overwrite existing files
+#
+
+let datadir=`select @@datadir`;
+create table d1 (a int);
+create temporary table t1 (a int);
+perl;
+chdir "$ENV{MYSQL_TMP_DIR}/mysqld.1/";
+for (<#sql*.MYI>) {
+ /^#sql(.*)_([0-9a-f]+_)([0-9a-f]+)\.MYI$/ or die;
+ symlink "$ENV{datadir}/test/d1.MYI", sprintf "#sql$1_$2%x.MYI", hex($3)+1;
+ symlink "$ENV{datadir}/test/d1.MYI", sprintf "#sql$1_$2%x.MAI", hex($3)+1;
+ symlink "$ENV{datadir}/test/d1.MYI", sprintf "#sql$1_$2%x.MAI", hex($3)+2;
+ symlink "$ENV{datadir}/test/d1.MYI", "#sql_$1_0.MAI";
+}
+EOF
+
+error 1,1030;
+create temporary table t2 (a int);
+error 1,1030;
+create temporary table t3 (a int) engine=Aria;
+error 1,1030;
+select * from information_schema.columns where table_schema='test';
+
+flush tables;
+select * from d1;
+drop temporary table t1;
+remove_files_wildcard $MYSQL_TMP_DIR/mysqld.1 *sql*;
+drop table d1;
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index c86bc730392..91f4a8250f6 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -369,12 +369,18 @@ select @a;
--echo #
--echo # BUG LP:1008487 virtual bool Item_cache::is_expensive(): Assertion `example' failed
--echo #
+
+# Set timestamp to make sure DATETIME->DATE truncation happens.
+# Otherwise, the warning would disappear at '00:00:00' sharp,
+# and a different execution plan would be chosen.
+SET TIMESTAMP=UNIX_TIMESTAMP('2012-01-01 00:00:01');
create table t1(a date,key(a));
insert into t1 values ('2012-01-01'),('2012-02-02');
explain
select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1;
select 1 from t1 as t1_0 inner join t1 as t2 on (t1_0.a <=> now()) join t1 on 1;
drop table t1;
+SET TIMESTAMP=DEFAULT;
--echo #
--echo # MDEV-9521 Least function returns 0000-00-00 for null date columns instead of null
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index 447a5d4b192..f2ef5030a6a 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -32,10 +32,12 @@ drop table t1;
# Test insert of now() and curtime()
#
+SET TIMESTAMP=UNIX_TIMESTAMP('2020-08-11 00:00:01');
CREATE TABLE t1 (a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b date, c time, d datetime);
insert into t1 (b,c,d) values(now(),curtime(),now());
select date_format(a,"%Y-%m-%d")=b,right(a+0,6)=c+0,a=d+0 from t1;
drop table t1;
+SET TIMESTAMP=DEFAULT;
#
# Test of datetime and not null
@@ -201,6 +203,7 @@ drop table t1;
#
# Bug#16377: Wrong DATE/DATETIME comparison in BETWEEN function.
#
+
create table t1 (f1 date, f2 datetime, f3 timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
insert into t1 values('2001-01-01','2001-01-01 01:01:01','2001-01-01 01:01:01');
insert into t1 values('2001-02-05','2001-02-05 00:00:00','2001-02-05 01:01:01');
@@ -214,7 +217,9 @@ select f1, f2, f3 from t1 where cast(f1 as datetime) between f2 and
select f2 from t1 where '2001-04-10 12:34:56' between f2 and '01-05-01';
select f2, f3 from t1 where '01-03-10' between f2 and f3;
select f2 from t1 where DATE(f2) between "2001-4-15" AND "01-4-15";
+SET timestamp=UNIX_TIMESTAMP('2001-01-01 00:00:01');
SELECT 1 from dual where NOW() BETWEEN CURRENT_DATE() - INTERVAL 1 DAY AND CURRENT_DATE();
+SET timestamp=DEFAULT;
drop table t1;
#
diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test
index 228812c2ae5..a8ec1ca01d9 100644
--- a/mysql-test/t/type_float.test
+++ b/mysql-test/t/type_float.test
@@ -486,5 +486,19 @@ DROP TABLE t1;
--echo #
+--echo # MDEV-23282 FLOAT(53,0) badly handles out-of-range values
+--echo #
+
+CREATE OR REPLACE TABLE t1 (c1 FLOAT NOT NULL, c2 FLOAT NOT NULL);
+INSERT IGNORE INTO t1 VALUES (1e+40, -1e+40);
+SELECT c1, c2 FROM t1;
+DROP TABLE t1;
+
+CREATE OR REPLACE TABLE t1 (c1 FLOAT(53,0) NOT NULL, c2 FLOAT(53,0) NOT NULL);
+INSERT IGNORE INTO t1 VALUES (1e+40, -1e+40);
+SELECT c1, c2 FROM t1;
+DROP TABLE t1;
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 9b1beeb3f51..7338780c616 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1822,6 +1822,28 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-23105 Cast number string with many leading zeros to decimal gives unexpected result
+--echo #
+
+SELECT CAST(0000000000000000000000000000000000000000000000000000000000000000000000000000000020.01 AS DECIMAL(15,2)) as val;
+
+SET sql_mode='';
+CREATE TABLE t1 (a TEXT);
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.0'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.9'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.99'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.994'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.995'));
+INSERT INTO t1 VALUES (CONCAT(REPEAT('0',100),1,'.999'));
+CREATE TABLE t2 (a TEXT, d DECIMAL(15,2));
+INSERT IGNORE INTO t2 (a,d) SELECT a, a FROM t1;
+INSERT IGNORE INTO t2 (a,d) SELECT CONCAT('-',a), CONCAT('-',a) FROM t1;
+SELECT d, a FROM t2 ORDER BY d,a;
+DROP TABLE t1, t2;
+SET sql_mode=DEFAULT;
+
+--echo #
--echo # End of 10.1 tests
--echo #
diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test
index 16e4f42301d..4bc5d8c4858 100644
--- a/mysql-test/t/type_set.test
+++ b/mysql-test/t/type_set.test
@@ -101,7 +101,7 @@ DROP TABLE t1;
--echo #
--echo #
---echo # MDEV-6950 Bad results with joins compating DATE and INT/ENUM/VARCHAR columns
+--echo # MDEV-6950 Bad results with joins comparing DATE and INT/ENUM/VARCHAR columns
--echo #
CREATE TABLE t1 (c1 DATE PRIMARY KEY);
diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test
index 4ee412f80d8..e9ba8e941e3 100644
--- a/mysql-test/t/udf.test
+++ b/mysql-test/t/udf.test
@@ -47,7 +47,7 @@ select lookup();
select lookup("127.0.0.1");
--error ER_CANT_INITIALIZE_UDF
select lookup(127,0,0,1);
-select lookup("localhost");
+select lookup("localhost") rlike '^127\.\\d+\.\\d+.\\d+$';
--error ER_CANT_INITIALIZE_UDF
select reverse_lookup();
diff --git a/mysql-test/t/uniques_crash-7912.test b/mysql-test/t/uniques_crash-7912.test
deleted file mode 100644
index 8dc82f8f540..00000000000
--- a/mysql-test/t/uniques_crash-7912.test
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# MDEV-7912
-#
-# multitable delete with wrongly set sort_buffer_size crashes in merge_buffers
-
---source include/have_innodb.inc
---source include/have_debug.inc
---source include/windows.inc
-
-call mtr.add_suppression("Out of memory");
-
-set sql_mode="";
---disable_warnings
-drop table if exists t1,t2;
-create table `t1` (`a` datetime not null) engine=InnoDB;
-create table `t2` (`a` int not null) engine=innodb;
-replace into t1 values (),();
-insert into t2 values(0);
-set session sort_buffer_size = 1024*1024*1024*1024;
-#Either fail with EE_OUTOFMEMORY, or succeed
---error 0 , 5
-delete d2 from t2 as d1, t1 as d2 where d1.a <=> d2.a;
---enable_warnings
-
-drop table t2;
-drop table t1;
diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests
index 6ed67cdba94..a7eb0986bfc 100644
--- a/mysql-test/unstable-tests
+++ b/mysql-test/unstable-tests
@@ -23,105 +23,93 @@
#
##############################################################################
#
-# Based on 10.1 05e72a33331bd9ad96ebbe4c844b94f0a5fb7390
+# Based on 10.1 09ec8e2e2246f9fb67fd41631c5669d9ae26b2e5
main.alter_table_trans : MDEV-12084 - timeout
main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result
main.auth_named_pipe : MDEV-14724 - System error 2
-main.bootstrap : Modified in 10.1.41
-main.connect_debug : Modified in 10.1.41
main.count_distinct2 : MDEV-11768 - timeout
main.create_delayed : MDEV-10605 - failed with timeout
main.create_drop_event : MDEV-16271 - Wrong result
-main.ctype_utf16 : MDEV-10675: timeout or extra warnings
-main.ctype_utf8_def_upgrade : Added in 10.1.41
+main.create_drop_function : Modified in 10.1.46
+main.ctype_binary : Modified in 10.1.46
+main.ctype_utf16 : MDEV-10675: timeout or extra warnings; modified in 10.1.46
+main.ctype_utf16le : Modified in 10.1.46
+main.ctype_utf32 : Modified in 10.1.46
+main.ctype_utf8 : Modified in 10.1.46
+main.ctype_utf8mb4 : Modified in 10.1.46
+main.ctype_utf8mb4_heap : Include file modified in 10.1.46
+main.ctype_utf8mb4_innodb : Include file modified in 10.1.46
+main.ctype_utf8mb4_myisam : Include file modified in 10.1.46
main.debug_sync : MDEV-10607 - internal error
-main.derived : Modified in 10.1.41
main.derived_opt : MDEV-11768 - timeout
-main.derived_view : Modified in 10.1.41
main.dirty_close : MDEV-19368 - mysqltest failed but provided no output
-main.drop_bad_db_type : Modified in 10.1.42
-main.drop_debug : Modified in 10.1.42
main.events_2 : MDEV-13277 - Server crash
main.events_bugs : MDEV-12892 - Crash in fill_schema_processlist
main.events_restart : MDEV-12236 - Server shutdown problem
main.events_slowlog : MDEV-12821 - Wrong result
main.flush : MDEV-19368 - mysqltest failed but provided no output
-main.func_math : Modified in 10.1.42
+main.func_gconcat : MDEV-21379 - Valgrind warnings
+main.func_math : Modified in 10.1.46
main.gis : MDEV-13411 - wrong result on P8
+main.gis_notembedded : MDEV-21264 - Wrong result with different default charset
+main.grant : Modified in 10.1.46
+main.grant5 : Modified in 10.1.46
main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown
main.index_intersect_innodb : MDEV-10643 - failed with timeout
-main.index_merge_innodb : MDEV-7142 - Wrong execution plan, timeout with valgrind; modified in 10.1.42
-main.index_merge_myisam : Modified in 10.1.42
-main.information_schema_parameters : Modified in 10.1.41
-main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure
-main.join : Modified in 10.1.42
-main.join_cache : Modified in 10.1.41
-main.join_nested : Modified in 10.1.41
-main.join_outer : Modified in 10.1.41
-main.join_outer_innodb : Modified in 10.1.41
+main.index_merge_innodb : MDEV-7142 - Wrong execution plan, timeout with valgrind; modified in 10.1.46
+main.index_merge_myisam : Modified in 10.1.45
+main.information_schema : Modified in 10.1.46
+main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure (Fixed in 10.3+, MDEV-22947)
main.kill_processlist-6619 : MDEV-10793 - wrong result in processlist
main.loaddata : MDEV-19368 - mysqltest failed but provided no output
main.locale : MDEV-20521 - Wrong result (missing warning)
main.log_slow : MDEV-13263 - Wrong result
-main.log_slow_debug : Modified in 10.1.42
main.log_tables-big : MDEV-13408 - wrong result
main.mdev-504 : MDEV-10607 - sporadic "can't connect"
main.mdev375 : MDEV-10607 - sporadic "can't connect"
main.merge : MDEV-10607 - sporadic "can't connect"
-main.multi_update : Modified in 10.1.41
-main.multi_update_debug : MDEV-20136 - Debug sync point wait timed out; added in 10.1.41
-main.multi_update_innodb : Modified in 10.1.41
-main.myisam : Modified in 10.1.42
+main.multi_update_debug : MDEV-20136 - Debug sync point wait timed out (Fixed in 10.2+)
main.mysql_client_test : MDEV-19369 - error: 5888, status: 23, errno: 2
main.mysql_client_test_comp : MDEV-19369 - error: 5888, status: 23, errno: 2
main.mysql_client_test_nonblock : MDEV-15096 - exec failed
main.mysql_upgrade_noengine : MDEV-14355 - Plugin is busy
-main.mysqld--help : Modified in 10.1.41
-main.mysqldump : Modified in 10.1.41
+main.mysqld--defaults-file : Modified in 10.1.45
+main.mysqldump : Modified in 10.1.45
main.mysqlhotcopy_myisam : MDEV-10995 - test hangs on debug build
main.mysqlslap : MDEV-11801 - timeout
main.mysqltest : MDEV-9269 - fails on Alpha
+main.nested_profiling : Added in 10.1.46
main.old-mode : MDEV-19373 - Wrong result
-main.order_by : Modified in 10.1.44
-main.order_by_innodb : Modified in 10.1.42
+main.order_by : Modified in 10.1.46
main.order_by_optimizer_innodb : MDEV-10683 - wrong execution plan
-main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock; modified in 10.1.42
+main.partition : Modified in 10.1.46
+main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock
main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings
-main.plugin : Modified in 10.1.41
-main.plugin_not_embedded : Modified in 10.1.41
-main.processlist : Modified in 10.1.42
-main.processlist_notembedded : Added in 10.1.42
-main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count; modified in 10.1.41
-main.ps_innodb : Added in 10.1.41
-main.query_cache : MDEV-12895 - Wrong result
+main.processlist_notembedded : Modified in 10.1.46
+main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count
+main.query_cache : MDEV-12895 - Wrong result; modified in 10.1.46
main.query_cache_debug : MDEV-15281 - Resize or similar command in progress
+main.range : Modified in 10.1.45
+main.range_innodb : Modified in 10.1.45
main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away
-main.repair_symlink-5543 : Modified in 10.1.41
-main.selectivity : Modified in 10.1.44
+main.selectivity : Modified in 10.1.46
main.set_statement : MDEV-13183 - Wrong result
main.show_explain : MDEV-10674 - sporadic failure
-main.sp : Modified in 10.1.42
-main.sp-code : Modified in 10.1.42
main.sp-security : MDEV-10607 - sporadic "can't connect"
main.sp_notembedded : MDEV-10607 - internal error
-main.stat_tables : Modified in 10.1.41
+main.stat_tables_innodb : Modified in 10.1.46
main.stat_tables_par_innodb : MDEV-14155 - wrong rounding
+main.stat_tables_partition : Modified in 10.1.46
main.status : MDEV-8510 - sporadic wrong result
-main.subselect : Modified in 10.1.41
+main.subselect4 : Modified in 10.1.46
+main.subselect_exists2in : Modified in 10.1.46
main.subselect_innodb : MDEV-10614 - sporadic wrong results
-main.subselect_sj : Modified in 10.1.42
-main.subselect_sj_mat : Modified in 10.1.41
-main.sum_distinct-big : Modified in 10.1.42
main.tc_heuristic_recover : MDEV-15200 - wrong error on mysqld_stub_cmd
-main.trigger_null-8605 : Modified in 10.1.41
main.type_blob : MDEV-15195 - Wrong result
-main.type_date : Modified in 10.1.42
-main.type_datetime : Modified in 10.1.42
main.type_datetime_hires : MDEV-10687 - timeout
-main.type_int : Modified in 10.1.42
-main.type_newdecimal : Modified in 10.1.42
-main.view : Modified in 10.1.41
+main.type_float : Modified in 10.1.46
+main.udf : Modified in 10.1.46
main.wait_timeout : Lost connection to MySQL server during query
main.xa : MDEV-11769 - lock wait timeout
@@ -138,37 +126,34 @@ archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed
#-----------------------------------------------------------------------
-binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed
-binlog.binlog_killed : MDEV-12925 - Wrong result
-binlog.binlog_mysqlbinlog_stop_never : Added in 10.1.41
-binlog.binlog_parallel_replication_marks_row : Include file modified in 10.1.41
-binlog.binlog_parallel_replication_marks_stm_mix : Include file modified in 10.1.41
-binlog.binlog_row_drop_tmp_tbl : Include file modified in 10.1.42
-binlog.binlog_stm_drop_tmp_tbl : Include file modified in 10.1.42
-binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
-binlog.load_data_stm_view : MDEV-16948 - Wrong result
+binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed
+binlog.binlog_invalid_read_in_rotate : MDEV-22455 - Server crash
+binlog.binlog_killed : MDEV-12925 - Wrong result
+binlog.binlog_mysqlbinlog_row_frag : Modified in 10.1.46
+binlog.binlog_no_uniqfile_crash : Added in 10.1.46
+binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint
+binlog.load_data_stm_view : MDEV-16948 - Wrong result
#-----------------------------------------------------------------------
-binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint
-binlog_encryption.encrypted_master : MDEV-12906 - Failed to sync
-binlog_encryption.rpl_corruption : Include file modified in 10.1.44
-binlog_encryption.rpl_parallel : MDEV-10653 - Timeout
-binlog_encryption.rpl_parallel_ignored_errors : Added in 10.1.42
-binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout
-binlog_encryption.rpl_semi_sync : MDEV-11220 - Wrong result, MDEV-11673 - Valgrind warning
-binlog_encryption.rpl_ssl : MDEV-14507 - Timeout on SLES 11.4
-binlog_encryption.rpl_stm_relay_ign_space : MDEV-19375 - Test assertion failed in assertion.inc
-binlog_encryption.rpl_typeconv : MDEV-14362 - Lost connection to MySQL server during query
+binlog_encryption.binlog_xa_recover : MDEV-12908 - Extra checkpoint
+binlog_encryption.encrypted_master : MDEV-12906 - Failed to sync
+binlog_encryption.multisource : MDEV-21289 - Wrong error code
+binlog_encryption.rpl_parallel : MDEV-10653 - Timeout
+binlog_encryption.rpl_relayrotate : MDEV-15194 - Timeout
+binlog_encryption.rpl_semi_sync : MDEV-11220 - Wrong result, MDEV-11673 - Valgrind warning
+binlog_encryption.rpl_ssl : MDEV-14507 - Timeout on SLES 11.4
+binlog_encryption.rpl_stm_relay_ign_space : MDEV-19375 - Test assertion failed in assertion.inc
+binlog_encryption.rpl_typeconv : MDEV-14362 - Lost connection to MySQL server during query
#-----------------------------------------------------------------------
-connect.pivot : MDEV-14803 - failed to discover table
+connect.pivot : MDEV-21378 - Valgrind warnings; MDEV-14803 - failed to discover table
connect.zip : MDEV-13884 - Wrong result
#-----------------------------------------------------------------------
-disks.disks_notembedded : Added in 10.1.41
+disks.disks_notembedded : MDEV-21587 - Wrong result
#-----------------------------------------------------------------------
@@ -178,15 +163,18 @@ encryption.encrypt_and_grep : MDEV-13765 - Wrong result
encryption.innodb-bad-key-change2 : MDEV-19118 - Can't connect through socket
encryption.innodb-compressed-blob : MDEV-14728 - Unable to get certificate
encryption.innodb-first-page-read : MDEV-14356 - Timeout on wait condition
+encryption.innodb-missing-key : MDEV-17286 - SSL error
encryption.innodb-page_encryption : MDEV-10641 - mutex problem
encryption.innodb-read-only : MDEV-14728 - Unable to get certificate; MDEV-16563 - Crash on startup
encryption.innodb-redo-badkey : MDEV-12898 - Server hang on startup
encryption.innodb-remove-encryption : MDEV-16493 - Timeout in wait condition
+encryption.innodb_encryption : MDEV-14728 - Unable to get certificate
encryption.innodb_encryption-page-compression : MDEV-12630 - crash or assertion failure
encryption.innodb_encryption_discard_import : MDEV-16116 - Wrong result
encryption.innodb_encryption_is : MDEV-12898 - Server hang on startup
encryption.innodb_encryption_row_compressed : MDEV-16113 - Crash
encryption.innodb_first_page : MDEV-10689 - Crash
+encryption.innodb_onlinealter_encryption : MDEV-14121 - Assertion failure
encryption.innodb_scrub : MDEV-8139 - scrubbing tests need fixing
encryption.innodb_scrub_background : MDEV-8139 - scrubbing tests need fixing
encryption.innodb_scrub_compressed : MDEV-8139 - scrubbing tests need fixing
@@ -238,23 +226,19 @@ galera_3nodes.* : The suite has not been stabilized yet
#-----------------------------------------------------------------------
innodb.binlog_consistent : MDEV-10618 - Server fails to start
-innodb.check_ibd_filesize : Added in 10.1.41
-innodb.create_select : Added in 10.1.41
-innodb.doublewrite : MDEV-12905 - Lost connection to MySQL server
-innodb.foreign-keys : Modified in 10.1.41
+innodb.doublewrite : MDEV-12905 - Lost connection to MySQL server; MDEV-21380 - Assertion failure
+innodb.foreign_key : Modified in 10.1.46
+innodb.foreign_key_debug : Added in 10.1.46
innodb.group_commit_crash : MDEV-11770 - Checksum mismatch
innodb.group_commit_crash_no_optimize_thread : MDEV-11770 - Checksum mismatch
innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on startup
innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS
innodb.innodb-alter-table : MDEV-10619 - Testcase timeout
-innodb.innodb-autoinc : Modified in 10.1.42
innodb.innodb-blob : MDEV-12053 - Client crash
innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown
innodb.innodb-page_compression_default : MDEV-14121 - Assertion failure
innodb.innodb-page_compression_lzma : MDEV-14353 - Wrong result on Fedora 25
innodb.innodb-page_compression_zip : MDEV-10641 - Mutex problem
-innodb.innodb-system-table-view : Added in 10.1.41
-innodb.innodb-wl5980-debug : Added in 10.1.41
innodb.innodb_bug14147491 : MDEV-11808 - Wrong error codes
innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan
innodb.innodb_bug48024 : MDEV-14352 - Assertion failure
@@ -263,26 +247,25 @@ innodb.innodb_monitor : MDEV-10939 - Testcase timeout
innodb.innodb_mysql : MDEV-19873 - Wrong result
innodb.innodb_stats : MDEV-10682 - Wrong result
innodb.innodb_sys_semaphore_waits : MDEV-10331 - Wrong result
+innodb.innodb_sys_var_valgrind : Added in 10.1.45
innodb.innodb_zip_innochecksum2 : MDEV-13882 - Warning: difficult to find free blocks
innodb.log_file_size : MDEV-15668 - Not found pattern
+innodb.read_only_recover_committed : Modified in 10.1.46
innodb.recovery_shutdown : MDEV-15671 - Warning: database page corruption
innodb.row_format_redundant : MDEV-15192 - Trying to access missing tablespace
-innodb.stat_tables : Added in 10.1.42
innodb.table_definition_cache_debug : MDEV-14206 - Extra warning
innodb.table_flags : MDEV-19374 - Server failed to restart
-innodb.trx_id_future : Modified in 10.1.42
innodb.xa_recovery : MDEV-15279 - mysqld got exception
#-----------------------------------------------------------------------
-innodb_fts.concurrent_insert : Modified in 10.1.42
-innodb_fts.crash_recovery : Modified in 10.1.42
-innodb_fts.innodb_ft_aux_table : Added in 10.1.41
-innodb_fts.innodb_fts_misc : Modified in 10.1.44
innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning
+innodb_fts.misc_debug2 : Added in 10.1.45
+innodb_fts.stopword : Added in 10.1.45
#-----------------------------------------------------------------------
+maria.encrypt-no-key : Added in 10.1.46
maria.insert_select : MDEV-12757 - Timeout
maria.insert_select-7314 : MDEV-16492 - Timeout
maria.maria : MDEV-14430 - Wrong result
@@ -290,7 +273,8 @@ maria.maria : MDEV-14430 - Wrong result
#-----------------------------------------------------------------------
mariabackup.apply-log-only : MDEV-20135 - Timeout
-mariabackup.huge_lsn : MDEV-17286 - SSL error
+mariabackup.huge_lsn : MDEV-17286 - SSL error; modified in 10.1.46
+mariabackup.incremental_backup : MDEV-15667 - Timeout
mariabackup.incremental_encrypted : MDEV-15667 - Timeout
mariabackup.mdev-14447 : MDEV-15201 - Timeout
mariabackup.xb_compressed_encrypted : MDEV-14812 - Segfault
@@ -314,9 +298,8 @@ mroonga/wrapper.repair_table_no_index_file : MDEV-14807 - Wrong error message
#-----------------------------------------------------------------------
multi_source.gtid : MDEV-10417 - Fails on Mips
-multi_source.info_logs : MDEV-10042 - Wrong result, MDEV-12629 - Valgrind warnings
-multi_source.mdev-8874 : Added in 10.1.41
-multi_source.multisource : MDEV-10417 - Fails on Mips
+multi_source.info_logs : MDEV-10042 - Wrong result, MDEV-12629 - Valgrind warnings, MDEV-21290 - Wrong result
+multi_source.multisource : MDEV-10417 - Fails on Mips, MDEV-21289 - Wrong error code
multi_source.reset_slave : MDEV-10690 - wrong result
multi_source.simple : MDEV-4633 - Wrong slave status output
multi_source.status_vars : MDEV-4632 - failed while waiting for Slave_received_heartbeats
@@ -326,12 +309,8 @@ multi_source.status_vars : MDEV-4632 - failed while waiting for Slave_received_h
parts.partition_alter2_2_maria : MDEV-14364 - Lost connection to MySQL server during query
parts.partition_auto_increment_archive : MDEV-16491 - Table marked as crashed
parts.partition_auto_increment_maria : MDEV-14430 - Wrong result
-parts.partition_debug : Modified in 10.1.42
-parts.partition_debug_innodb : Modified in 10.1.42
-parts.partition_debug_myisam : Modified in 10.1.42
parts.partition_exch_qa_10 : MDEV-11765 - wrong result
parts.partition_innodb_status_file : MDEV-12901 - Valgrind
-parts.reorganize_partition_innodb : Added in 10.1.42
#-----------------------------------------------------------------------
@@ -339,7 +318,6 @@ perfschema.connect_attrs : MDEV-17283 - Wrong result
perfschema.func_file_io : MDEV-5708 - fails for s390x
perfschema.func_mutex : MDEV-5708 - fails for s390x
perfschema.hostcache_ipv6_ssl : MDEV-10696 - crash on shutdown
-perfschema.misc : Modified in 10.1.44
perfschema.privilege_table_io : MDEV-13184 - Extra lines
perfschema.rpl_gtid_func : MDEV-16897 - Wrong result
perfschema.socket_summary_by_event_name_func : MDEV-10622 - Socket summary tables do not match
@@ -360,98 +338,86 @@ plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc
#-----------------------------------------------------------------------
-roles.create_and_grant_role : MDEV-11772 - wrong result
-
-#-----------------------------------------------------------------------
-
-rpl.circular_serverid0 : MDEV-19372 - ASAN heap-use-after-free
-rpl.create_or_replace_mix : MDEV-20523 - Wrong result; include file modified in 10.1.41
-rpl.create_or_replace_row : Include file modified in 10.1.41
-rpl.create_or_replace_statement : MDEV-20523 - Wrong result; include file modified in 10.1.41
-rpl.create_select : MDEV-14121 - Assertion failure
-rpl.kill_race_condition : Modified in 10.1.41
-rpl.last_insert_id : MDEV-10625 - warnings in error log
-rpl.mdev_17588 : Modified in 10.1.42
-rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips
-rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips
-rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log
-rpl.rpl_binlog_index : MDEV-9501 - Warning: failed registering on master
-rpl.rpl_blackhole : Modified in 10.1.41
-rpl.rpl_blackhole_row_annotate : Added in 10.1.41
-rpl.rpl_colSize : MDEV-16112 - Server crash
-rpl.rpl_corruption : Include file modified in 10.1.44
-rpl.rpl_create_or_replace_fail : Added in 10.1.42
-rpl.rpl_ddl : MDEV-10417 - Fails on Mips
-rpl.rpl_domain_id_filter_io_crash : MDEV-14357 - Wrong result
-rpl.rpl_domain_id_filter_master_crash : MDEV-19043 - Warnings/errors
-rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result; MDEV-19043 - Warnings/errors
-rpl.rpl_drop_db_fail : MDEV-16898 - Slave fails to start
-rpl.rpl_get_lock : MDEV-19368 - mysqltest failed but provided no output
-rpl.rpl_gtid_basic : MDEV-10681 - server startup problem
-rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master
-rpl.rpl_gtid_delete_domain : MDEV-14463 - Timeout in include
-rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings
-rpl.rpl_gtid_reconnect : MDEV-14497 - Timeout
-rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown, MDEV-12629 - Valgrind warnings
-rpl.rpl_gtid_until : MDEV-10625 - warnings in error log
-rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips
-rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x
-rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x
-rpl.rpl_insert_id : MDEV-15197 - Wrong result
-rpl.rpl_insert_id_pk : MDEV-16567 - Assertion failure
-rpl.rpl_insert_ignore : MDEV-14365 - Lost connection to MySQL server during query
-rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips
-rpl.rpl_known_bugs_detection : Modified in 10.1.42
-rpl.rpl_mariadb_slave_capability : MDEV-11018 - sporadic wrong events in binlog
-rpl.rpl_mdev12179 : MDEV-19043 - Warnings/errors
-rpl.rpl_mdev6020 : MDEV-10417 - Fails on Mips
-rpl.rpl_mdev_17614 : Added in 10.1.42
-rpl.rpl_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed
-rpl.rpl_non_direct_mixed_mixing_engines : MDEV-14489 - Sync slave with master failed
-rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master pos wait
-rpl.rpl_non_direct_stm_mixing_engines : MDEV-14489 - Sync slave with master failed
-rpl.rpl_parallel : MDEV-10653 - Timeouts
-rpl.rpl_parallel_ignored_errors : Added in 10.1.42
-rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure
-rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout
-rpl.rpl_parallel_optimistic : MDEV-10511 - Timeout
-rpl.rpl_parallel_retry : MDEV-11119 - Server crash
-rpl.rpl_parallel_temptable : MDEV-10356 - Crash in close_thread_tables
-rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips
-rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
-rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start
-rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed
-rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result
-rpl.rpl_row_drop_temp_table : Added in 10.1.41
-rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed
-rpl.rpl_row_img_eng_min : MDEV-13875 - command "diff_files" failed
-rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed
-rpl.rpl_row_index_choice : MDEV-15196 - Slave crash
-rpl.rpl_row_mysqlbinlog : Modified in 10.1.41
-rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x
-rpl.rpl_semi_sync : MDEV-11220 - Wrong result
-rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result
-rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result
-rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings
-rpl.rpl_semi_sync_gtid_reconnect : Added in 10.1.44
-rpl.rpl_semi_sync_skip_repl : Modified in 10.1.41
-rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status; modified in 10.1.41
-rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
-rpl.rpl_show_slave_hosts : MDEV-10681 - server startup problem
-rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha
-rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock
-rpl.rpl_start_stop_slave : MDEV-13567 - Replication failure
-rpl.rpl_stm_mixing_engines : MDEV-14489 - Sync slave with master failed
-rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion
-rpl.rpl_sync : MDEV-10633 - Database page corruption
-rpl.rpl_sync_with_innodb_thd_conc : Added in 10.1.42
-rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries
-rpl.rpl_test_framework : MDEV-19368 - mysqltest failed but provided no output
-rpl.rpl_trigger : MDEV-18055 - Wrong result
-rpl.rpl_truncate_3innodb : MDEV-19454 - Syntax error in test
-rpl.rpl_unsafe_statements : Modified in 10.1.42
-rpl.rpl_user_variables : MDEV-20522 - Wrong result
-rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result
+roles.create_and_grant_role : MDEV-11772 - wrong result
+roles.drop_current_role : Added in 10.1.46
+roles.set_default_role_invalid : Modified in 10.1.46
+
+#-----------------------------------------------------------------------
+
+rpl.circular_serverid0 : MDEV-19372 - ASAN heap-use-after-free
+rpl.create_or_replace_mix : MDEV-20523 - Wrong result
+rpl.create_or_replace_statement : MDEV-20523 - Wrong result
+rpl.create_select : MDEV-14121 - Assertion failure
+rpl.last_insert_id : MDEV-10625 - warnings in error log
+rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips
+rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips
+rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log
+rpl.rpl_binlog_dump_slave_gtid_state_info : Added in 10.1.46
+rpl.rpl_binlog_index : MDEV-9501 - Warning: failed registering on master
+rpl.rpl_checksum_cache : MDEV-22510 - Server crash
+rpl.rpl_colSize : MDEV-16112 - Server crash
+rpl.rpl_conditional_comments : Modified in 10.1.45
+rpl.rpl_ddl : MDEV-10417 - Fails on Mips
+rpl.rpl_domain_id_filter_io_crash : MDEV-14357 - Wrong result
+rpl.rpl_domain_id_filter_master_crash : MDEV-19043 - Warnings/errors
+rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result; MDEV-19043 - Warnings/errors
+rpl.rpl_drop_db_fail : MDEV-16898 - Slave fails to start
+rpl.rpl_fail_register : Modified in 10.1.46
+rpl.rpl_get_lock : MDEV-19368 - mysqltest failed but provided no output
+rpl.rpl_gtid_basic : MDEV-10681 - server startup problem
+rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master
+rpl.rpl_gtid_delete_domain : MDEV-14463 - Timeout in include
+rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings
+rpl.rpl_gtid_reconnect : MDEV-14497 - Timeout
+rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown, MDEV-12629 - Valgrind warnings
+rpl.rpl_gtid_until : MDEV-10625 - warnings in error log
+rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips
+rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x
+rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x
+rpl.rpl_insert_id : MDEV-15197 - Wrong result
+rpl.rpl_insert_id_pk : MDEV-16567 - Assertion failure
+rpl.rpl_insert_ignore : MDEV-14365 - Lost connection to MySQL server during query
+rpl.rpl_invoked_features : MDEV-10417 - Fails on Mips
+rpl.rpl_mariadb_slave_capability : MDEV-11018 - sporadic wrong events in binlog
+rpl.rpl_mdev12179 : MDEV-19043 - Warnings/errors
+rpl.rpl_mdev6020 : MDEV-10417 - Fails on Mips
+rpl.rpl_non_direct_row_mixing_engines : MDEV-16561 - Timeout in master pos wait
+rpl.rpl_parallel : MDEV-10653 - Timeouts
+rpl.rpl_parallel2 : MDEV-23089 - Server hang
+rpl.rpl_parallel_mdev6589 : MDEV-12979 - Assertion failure
+rpl.rpl_parallel_multilevel2 : MDEV-14723 - Timeout
+rpl.rpl_parallel_optimistic : MDEV-10511 - Timeout
+rpl.rpl_parallel_optimistic_until : Added in 10.1.46
+rpl.rpl_parallel_retry : MDEV-11119 - Server crash
+rpl.rpl_parallel_temptable : MDEV-10356 - Crash in close_thread_tables
+rpl.rpl_partition_innodb : MDEV-10417 - Fails on Mips
+rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings
+rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start
+rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result
+rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_img_eng_min : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed
+rpl.rpl_row_index_choice : MDEV-15196 - Slave crash
+rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x
+rpl.rpl_semi_sync : MDEV-11220 - Wrong result
+rpl.rpl_semi_sync_after_sync : MDEV-14366 - Wrong result
+rpl.rpl_semi_sync_after_sync_row : MDEV-14366 - Wrong result
+rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings
+rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status
+rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition
+rpl.rpl_show_slave_hosts : MDEV-10681 - server startup problem
+rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha
+rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock
+rpl.rpl_start_stop_slave : MDEV-13567 - Replication failure
+rpl.rpl_stm_relay_ign_space : MDEV-14360 - Test assertion
+rpl.rpl_sync : MDEV-10633 - Database page corruption
+rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries
+rpl.rpl_test_framework : MDEV-19368 - mysqltest failed but provided no output
+rpl.rpl_trigger : MDEV-18055 - Wrong result
+rpl.rpl_truncate_3innodb : MDEV-19454 - Syntax error in test
+rpl.rpl_user_variables : MDEV-20522 - Wrong result
+rpl.sec_behind_master-5114 : MDEV-13878 - Wrong result
#-----------------------------------------------------------------------
@@ -494,14 +460,13 @@ stress.ddl_innodb : MDEV-10635 - Testcase timeout
#-----------------------------------------------------------------------
-sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x
-sys_vars.delayed_insert_limit_func : Modified in 10.1.42
-sys_vars.innodb_ft_result_cache_limit_32 : Modified in 10.1.41
-sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout
-sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash
-sys_vars.rpl_init_slave_func : MDEV-10149 - wrong results
-sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result
-sys_vars.wait_timeout_func : MDEV-12896 - Wrong result
+sys_vars.autocommit_func2 : MDEV-9329 - Fails on Ubuntu/s390x
+sys_vars.keep_files_on_create_basic : MDEV-10676 - timeout
+sys_vars.log_slow_admin_statements_func : MDEV-12235 - Server crash
+sys_vars.max_sort_length_basic : Modified in 10.1.46
+sys_vars.rpl_init_slave_func : MDEV-10149 - wrong results
+sys_vars.thread_cache_size_func : MDEV-11775 - Wrong result
+sys_vars.wait_timeout_func : MDEV-12896 - Wrong result
#-----------------------------------------------------------------------
@@ -539,10 +504,6 @@ tokudb_bugs.xa : MDEV-11804 - Lock wait timeout
#-----------------------------------------------------------------------
-tokudb_parts.partition_debug_tokudb : Include file modified in 10.1.42
-
-#-----------------------------------------------------------------------
-
tokudb_rpl.* : MDEV-11001 - tests don't work
#-----------------------------------------------------------------------
@@ -559,17 +520,15 @@ unit.ma_test_loghandler : MDEV-10638 - record read not ok
vcol.not_supported : MDEV-10639 - Testcase timeout
vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout
-vcol.vcol_misc : MDEV-16651 - Wrong error message
+vcol.vcol_misc : MDEV-16651 - Wrong error message; modified in 10.1.46
#-----------------------------------------------------------------------
-wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node
-wsrep.mdev_6832 : MDEV-14195 - Failure upon check-testcase
-wsrep.mysql_tzinfo_to_sql_symlink_skip : Added in 10.1.42
-wsrep.pool_of_threads : MDEV-17345 - WSREP has not yet prepared node for application use
-wsrep.variables : MDEV-17585 - Deadlock
+wsrep.foreign_key : MDEV-14725 - WSREP has not yet prepared node
+wsrep.mdev_6832 : MDEV-14195 - Failure upon check-testcase
+wsrep.pool_of_threads : MDEV-17345 - WSREP has not yet prepared node for application use
+wsrep.variables : MDEV-17585 - Deadlock
#-----------------------------------------------------------------------
-wsrep_info.* : Cnf file modified in 10.1.41
wsrep_info.plugin : MDEV-12909 - Wrong result
diff --git a/mysys/list.c b/mysys/list.c
index 8f4c934f64e..380de83c031 100644
--- a/mysys/list.c
+++ b/mysys/list.c
@@ -14,7 +14,7 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
/*
- Code for handling dubble-linked lists in C
+ Code for handling doubly linked lists in C
*/
#include "mysys_priv.h"
@@ -22,7 +22,7 @@
- /* Add a element to start of list */
+ /* Add an element to start of list */
LIST *list_add(LIST *root, LIST *element)
{
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 1245a622262..11f7bbd81b4 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates
- Copyright (c) 2010, 2015, MariaDB
+ Copyright (c) 2010, 2020, MariaDB
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
@@ -703,7 +703,8 @@ int _my_b_cache_read(IO_CACHE *info, uchar *Buffer, size_t Count)
info->read_pos=info->buffer+Count;
info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
- memcpy(Buffer, info->buffer, Count);
+ if (Count)
+ memcpy(Buffer, info->buffer, Count);
DBUG_RETURN(0);
}
@@ -1206,7 +1207,8 @@ static int _my_b_cache_read_r(IO_CACHE *cache, uchar *Buffer, size_t Count)
DBUG_RETURN(1);
}
cnt= (len > Count) ? Count : len;
- memcpy(Buffer, cache->read_pos, cnt);
+ if (cnt)
+ memcpy(Buffer, cache->read_pos, cnt);
Count -= cnt;
Buffer+= cnt;
left_length+= cnt;
diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
index d16f33036ab..ecb512572b1 100644
--- a/mysys/my_addr_resolve.c
+++ b/mysys/my_addr_resolve.c
@@ -49,6 +49,18 @@ static const char *strip_path(const char *s)
static bfd *bfdh= 0;
static asymbol **symtable= 0;
+#ifndef bfd_get_section_flags
+#define bfd_get_section_flags(H, S) bfd_section_flags(S)
+#endif /* bfd_get_section_flags */
+
+#ifndef bfd_get_section_size
+#define bfd_get_section_size(S) bfd_section_size(S)
+#endif /* bfd_get_section_size */
+
+#ifndef bfd_get_section_vma
+#define bfd_get_section_vma(H, S) bfd_section_vma(S)
+#endif /* bfd_get_section_vma */
+
/**
finds a file name, a line number, and a function name corresponding to addr.
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index 3b614cb4c15..5bfcb455b8a 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -1,5 +1,6 @@
/*
Copyright (c) 2000, 2010, Oracle and/or its affiliates
+ Copyright (c) 2010, 2020, MariaDB
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
@@ -449,7 +450,8 @@ char *strmake_root(MEM_ROOT *root, const char *str, size_t len)
char *pos;
if ((pos=alloc_root(root,len+1)))
{
- memcpy(pos,str,len);
+ if (len)
+ memcpy(pos,str,len);
pos[len]=0;
}
return pos;
diff --git a/mysys/my_default.c b/mysys/my_default.c
index 32faf2045f9..6f080bb35fe 100644
--- a/mysys/my_default.c
+++ b/mysys/my_default.c
@@ -1035,6 +1035,11 @@ void my_print_default_files(const char *conf_file)
char name[FN_REFLEN], **ext;
puts("\nDefault options are read from the following files in the given order:");
+ if (my_defaults_file)
+ {
+ puts(my_defaults_file);
+ return;
+ }
if (dirname_length(conf_file))
fputs(conf_file,stdout);
@@ -1059,7 +1064,12 @@ void my_print_default_files(const char *conf_file)
if (**dirs)
pos= *dirs;
else if (my_defaults_extra_file)
+ {
pos= my_defaults_extra_file;
+ fputs(pos, stdout);
+ fputs(" ", stdout);
+ continue;
+ }
else
continue;
end= convert_dirname(name, pos, NullS);
diff --git a/mysys/queues.c b/mysys/queues.c
index 5d09ce2063f..7a0ef2017c2 100644
--- a/mysys/queues.c
+++ b/mysys/queues.c
@@ -70,10 +70,9 @@
*/
int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
- pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
+ my_bool max_at_top, int (*compare) (void *, uchar *, uchar *),
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent)
-
{
DBUG_ENTER("init_queue");
if ((queue->root= (uchar **) my_malloc((max_elements + 1) * sizeof(void*),
@@ -109,7 +108,7 @@ int init_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
*/
int reinit_queue(QUEUE *queue, uint max_elements, uint offset_to_key,
- pbool max_at_top, int (*compare) (void *, uchar *, uchar *),
+ my_bool max_at_top, int (*compare) (void *, uchar *, uchar *),
void *first_cmp_arg, uint offset_to_queue_pos,
uint auto_extent)
{
@@ -182,6 +181,28 @@ void delete_queue(QUEUE *queue)
}
+static void insert_at(QUEUE *queue, uchar *element, uint idx)
+{
+ uint next_index, offset_to_key= queue->offset_to_key;
+ uint offset_to_queue_pos= queue->offset_to_queue_pos;
+ /* max_at_top swaps the comparison if we want to order by desc */
+ while ((next_index= idx >> 1) > 0 &&
+ queue->compare(queue->first_cmp_arg,
+ element + offset_to_key,
+ queue->root[next_index] + offset_to_key) *
+ queue->max_at_top < 0)
+ {
+ queue->root[idx]= queue->root[next_index];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
+ idx= next_index;
+ }
+ queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element + offset_to_queue_pos-1))= idx;
+}
+
+
/*
Insert element in queue
@@ -191,28 +212,10 @@ void delete_queue(QUEUE *queue)
element Element to insert
*/
-void queue_insert(register QUEUE *queue, uchar *element)
+void queue_insert(QUEUE *queue, uchar *element)
{
- reg2 uint idx, next;
- uint offset_to_queue_pos= queue->offset_to_queue_pos;
DBUG_ASSERT(queue->elements < queue->max_elements);
-
- idx= ++queue->elements;
- /* max_at_top swaps the comparison if we want to order by desc */
- while (idx > 1 &&
- (queue->compare(queue->first_cmp_arg,
- element + queue->offset_to_key,
- queue->root[(next= idx >> 1)] +
- queue->offset_to_key) * queue->max_at_top) < 0)
- {
- queue->root[idx]= queue->root[next];
- if (offset_to_queue_pos)
- (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
- idx= next;
- }
- queue->root[idx]= element;
- if (offset_to_queue_pos)
- (*(uint*) (element+ offset_to_queue_pos-1))= idx;
+ insert_at(queue, element, ++queue->elements);
}
@@ -230,7 +233,7 @@ void queue_insert(register QUEUE *queue, uchar *element)
2 auto_extend is 0; No insertion done
*/
-int queue_insert_safe(register QUEUE *queue, uchar *element)
+int queue_insert_safe(QUEUE *queue, uchar *element)
{
if (queue->elements == queue->max_elements)
@@ -240,7 +243,7 @@ int queue_insert_safe(register QUEUE *queue, uchar *element)
if (resize_queue(queue, queue->max_elements + queue->auto_extent))
return 1;
}
-
+
queue_insert(queue, element);
return 0;
}
@@ -259,81 +262,55 @@ int queue_insert_safe(register QUEUE *queue, uchar *element)
pointer to removed element
*/
-uchar *queue_remove(register QUEUE *queue, uint idx)
+uchar *queue_remove(QUEUE *queue, uint idx)
{
uchar *element;
- DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
+ DBUG_ASSERT(idx >= 1);
+ DBUG_ASSERT(idx <= queue->elements);
element= queue->root[idx];
- _downheap(queue, idx, queue->root[queue->elements--]);
+ queue->root[idx]= queue->root[queue->elements--];
+ queue_replace(queue, idx);
return element;
}
/*
- Add element to fixed position and update heap
+ Restores the heap property from idx down the heap
SYNOPSIS
_downheap()
queue Queue to use
idx Index of element to change
- element Element to store at 'idx'
-
- NOTE
- This only works if element is >= all elements <= start_idx
*/
-void _downheap(register QUEUE *queue, uint start_idx, uchar *element)
+void _downheap(QUEUE *queue, uint idx)
{
- uint elements,half_queue,offset_to_key, next_index, offset_to_queue_pos;
- register uint idx= start_idx;
- my_bool first= TRUE;
-
- offset_to_key=queue->offset_to_key;
- offset_to_queue_pos= queue->offset_to_queue_pos;
- half_queue= (elements= queue->elements) >> 1;
+ uchar *element= queue->root[idx];
+ uint next_index,
+ elements= queue->elements,
+ half_queue= elements >> 1,
+ offset_to_key= queue->offset_to_key,
+ offset_to_queue_pos= queue->offset_to_queue_pos;
while (idx <= half_queue)
{
- next_index=idx+idx;
+ next_index= idx+idx;
if (next_index < elements &&
- (queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- queue->root[next_index+1]+offset_to_key) *
- queue->max_at_top) > 0)
+ (queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ queue->root[next_index+1]+offset_to_key) *
+ queue->max_at_top) > 0)
next_index++;
- if (first &&
- (((queue->compare(queue->first_cmp_arg,
- queue->root[next_index]+offset_to_key,
- element+offset_to_key) * queue->max_at_top) >= 0)))
- {
- queue->root[idx]= element;
- if (offset_to_queue_pos)
- (*(uint*) (element + offset_to_queue_pos-1))= idx;
- return;
- }
- first= FALSE;
- queue->root[idx]= queue->root[next_index];
- if (offset_to_queue_pos)
- (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
- idx=next_index;
- }
-
- /*
- Insert the element into the right position. This is the same code
- as we have in queue_insert()
- */
- while ((next_index= (idx >> 1)) > start_idx &&
- queue->compare(queue->first_cmp_arg,
- element+offset_to_key,
- queue->root[next_index]+offset_to_key)*
- queue->max_at_top < 0)
- {
+ if ((queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key) * queue->max_at_top) >= 0)
+ break;
queue->root[idx]= queue->root[next_index];
if (offset_to_queue_pos)
(*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
idx= next_index;
}
- queue->root[idx]= element;
+ queue->root[idx]=element;
if (offset_to_queue_pos)
(*(uint*) (element + offset_to_queue_pos-1))= idx;
}
@@ -351,7 +328,7 @@ void queue_fix(QUEUE *queue)
{
uint i;
for (i= queue->elements >> 1; i > 0; i--)
- _downheap(queue, i, queue_element(queue, i));
+ _downheap(queue, i);
}
@@ -362,13 +339,47 @@ void queue_fix(QUEUE *queue)
queue_replace()
queue Queue to use
idx Index of element to change
- element Element to store at 'idx'
+
+ NOTE
+ optimized for the case when the new position is close to the end of the
+ heap (typical for queue_remove() replacements).
*/
void queue_replace(QUEUE *queue, uint idx)
{
uchar *element= queue->root[idx];
- DBUG_ASSERT(idx >= 1 && idx <= queue->elements);
- queue_remove(queue, idx);
- queue_insert(queue, element);
+ uint next_index,
+ elements= queue->elements,
+ half_queue= elements>>1,
+ offset_to_key= queue->offset_to_key,
+ offset_to_queue_pos= queue->offset_to_queue_pos;
+ my_bool first= TRUE;
+
+ while (idx <= half_queue)
+ {
+ next_index= idx + idx;
+ if (next_index < elements &&
+ queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ queue->root[next_index+1]+offset_to_key) *
+ queue->max_at_top > 0)
+ next_index++;
+ if (first &&
+ queue->compare(queue->first_cmp_arg,
+ queue->root[next_index]+offset_to_key,
+ element+offset_to_key) * queue->max_at_top >= 0)
+ {
+ queue->root[idx]= element;
+ if (offset_to_queue_pos)
+ (*(uint*) (element + offset_to_queue_pos-1))= idx;
+ break;
+ }
+ first= FALSE;
+ queue->root[idx]= queue->root[next_index];
+ if (offset_to_queue_pos)
+ (*(uint*) (queue->root[idx] + offset_to_queue_pos-1))= idx;
+ idx=next_index;
+ }
+
+ insert_at(queue, element, idx);
}
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 7daed0df673..339111f6fee 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -34,107 +34,16 @@
#include <execinfo.h>
#endif
-#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
-
-static char *heap_start;
-
-#ifdef HAVE_BSS_START
-extern char *__bss_start;
-#endif
-
void my_init_stacktrace()
{
-#ifdef HAVE_BSS_START
- heap_start = (char*) &__bss_start;
-#endif
-}
-
-#ifdef __linux__
-
-static void print_buffer(char *buffer, size_t count)
-{
- const char s[]= " ";
- for (; count && *buffer; --count)
- {
- my_write_stderr(isprint(*buffer) ? buffer : s, 1);
- ++buffer;
- }
-}
-
-/**
- Access the pages of this process through /proc/self/task/<tid>/mem
- in order to safely print the contents of a memory address range.
-
- @param addr The address at the start of the memory region.
- @param max_len The length of the memory region.
-
- @return Zero on success.
-*/
-static int safe_print_str(const char *addr, int max_len)
-{
- int fd;
- pid_t tid;
- off_t offset;
- ssize_t nbytes= 0;
- size_t total, count;
- char buf[256];
-
- tid= (pid_t) syscall(SYS_gettid);
-
- sprintf(buf, "/proc/self/task/%d/mem", tid);
-
- if ((fd= open(buf, O_RDONLY)) < 0)
- return -1;
-
- /* Ensure that off_t can hold a pointer. */
- compile_time_assert(sizeof(off_t) >= sizeof(intptr));
-
- total= max_len;
- offset= (intptr) addr;
-
- /* Read up to the maximum number of bytes. */
- while (total)
- {
- count= MY_MIN(sizeof(buf), total);
-
- if ((nbytes= pread(fd, buf, count, offset)) < 0)
- {
- /* Just in case... */
- if (errno == EINTR)
- continue;
- else
- break;
- }
-
- /* Advance offset into memory. */
- total-= nbytes;
- offset+= nbytes;
- addr+= nbytes;
-
- /* Output the printable characters. */
- print_buffer(buf, nbytes);
-
- /* Break if less than requested... */
- if ((count - nbytes))
- break;
- }
-
- if (nbytes == -1)
- my_safe_printf_stderr("Can't read from address %p", addr);
-
- close(fd);
-
- return 0;
}
-#endif
/*
Attempt to print a char * pointer as a string.
SYNOPSIS
- Prints either until the end of string ('\0'), or max_len characters have
- been printed.
+ Prints until max_len characters have been printed.
RETURN VALUE
0 Pointer was within the heap address space.
@@ -149,24 +58,25 @@ static int safe_print_str(const char *addr, int max_len)
int my_safe_print_str(const char* val, int max_len)
{
- char *heap_end;
-
-#ifdef __linux__
- // Try and make use of /proc filesystem to safely print memory contents.
- if (!safe_print_str(val, max_len))
- return 0;
-#endif
-
- heap_end= (char*) sbrk(0);
-
- if (!PTR_SANE(val))
+ const char *orig_val= val;
+ if (!val)
{
- my_safe_printf_stderr("%s", "is an invalid pointer");
+ my_safe_printf_stderr("%s", "(null)");
return 1;
}
- for (; max_len && PTR_SANE(val) && *val; --max_len)
- my_write_stderr((val++), 1);
+ for (; max_len; --max_len)
+ {
+ if (my_write_stderr((val++), 1) != 1)
+ {
+ if ((errno == EFAULT) &&(val == orig_val + 1))
+ {
+ // We can not read the address from very beginning
+ my_safe_printf_stderr("Can't access address %p", orig_val);
+ }
+ break;
+ }
+ }
my_safe_printf_stderr("%s", "\n");
return 0;
diff --git a/pcre/AUTHORS b/pcre/AUTHORS
index 23c005a33d6..bb8b32835bd 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-2019 University of Cambridge
+Copyright (c) 1997-2020 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-2019 Zoltan Herczeg
+Copyright(c) 2010-2020 Zoltan Herczeg
All rights reserved.
@@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Emain domain: freemail.hu
-Copyright(c) 2009-2019 Zoltan Herczeg
+Copyright(c) 2009-2020 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/ChangeLog b/pcre/ChangeLog
index e4d2d9fa24c..04d1ef5b2c4 100644
--- a/pcre/ChangeLog
+++ b/pcre/ChangeLog
@@ -5,6 +5,35 @@ 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.44 12 February-2020
+-----------------------------
+
+1. Setting --enable-jit=auto for an out-of-tree build failed because the
+source directory wasn't in the search path for AC_TRY_COMPILE always. Patch
+from Ross Burton.
+
+2. Applied a patch from Michael Shigorin to fix 8.43 build on e2k arch
+with lcc compiler (EDG frontend based); the problem it fixes is:
+
+ lcc: "pcrecpp.cc", line 74: error: declaration aliased to undefined entity
+ "_ZN7pcrecpp2RE6no_argE" [-Werror]
+
+3. Change 2 for 8.43 omitted (*LF) from the list of start-of-pattern items. Now
+added.
+
+4. Fix ARMv5 JIT improper handling of labels right after a constant pool.
+
+5. Small patch to pcreposix.c to set the erroroffset field to -1 immediately
+after a successful compile, instead of at the start of matching to avoid a
+sanitizer complaint (regexec is supposed to be thread safe).
+
+6. Check the size of the number after (?C as it is read, in order to avoid
+integer overflow.
+
+7. Tidy up left shifts to avoid sanitize warnings; also fix one NULL deference
+in pcretest.
+
+
Version 8.43 23-February-2019
-----------------------------
diff --git a/pcre/LICENCE b/pcre/LICENCE
index 760a6666b60..57a544814c8 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-2019 University of Cambridge
+Copyright (c) 1997-2020 University of Cambridge
All rights reserved.
@@ -36,7 +36,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
-Copyright(c) 2010-2019 Zoltan Herczeg
+Copyright(c) 2010-2020 Zoltan Herczeg
All rights reserved.
@@ -47,7 +47,7 @@ Written by: Zoltan Herczeg
Email local part: hzmester
Email domain: freemail.hu
-Copyright(c) 2009-2019 Zoltan Herczeg
+Copyright(c) 2009-2020 Zoltan Herczeg
All rights reserved.
diff --git a/pcre/NEWS b/pcre/NEWS
index 0f184081740..3d91b67dfa9 100644
--- a/pcre/NEWS
+++ b/pcre/NEWS
@@ -5,6 +5,12 @@ 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.44 12-February-2020
+-----------------------------
+
+This is a bug-fix release.
+
+
Release 8.43 23-February-2019
-----------------------------
diff --git a/pcre/README b/pcre/README
index 4887ebf350e..334362b3e53 100644
--- a/pcre/README
+++ b/pcre/README
@@ -13,9 +13,10 @@ libraries.
The latest release of PCRE1 is always available in three alternative formats
from:
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip
+ https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.gz
+ https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.bz2
+ https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.zip
+
There is a mailing list for discussion about the development of PCRE at
pcre-dev@exim.org. You can access the archives and subscribe or manage your
@@ -999,4 +1000,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
-Last updated: 10 February 2015
+Last updated: 12 February 2020
diff --git a/pcre/configure.ac b/pcre/configure.ac
index d2e5236cbd6..6a3e5f35d8e 100644
--- a/pcre/configure.ac
+++ b/pcre/configure.ac
@@ -9,19 +9,19 @@ 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, [43])
+m4_define(pcre_minor, [44])
m4_define(pcre_prerelease, [])
-m4_define(pcre_date, [2019-02-23])
+m4_define(pcre_date, [2020-02-12])
# 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:11:2])
-m4_define(libpcre16_version, [2:11:2])
-m4_define(libpcre32_version, [0:11:0])
-m4_define(libpcreposix_version, [0:6:0])
-m4_define(libpcrecpp_version, [0:1:0])
+m4_define(libpcre_version, [3:12:2])
+m4_define(libpcre16_version, [2:12:2])
+m4_define(libpcre32_version, [0:12:0])
+m4_define(libpcreposix_version, [0:7:0])
+m4_define(libpcrecpp_version, [0:2:0])
AC_PREREQ(2.57)
AC_INIT(PCRE, pcre_major.pcre_minor[]pcre_prerelease, , pcre)
@@ -159,12 +159,15 @@ AC_ARG_ENABLE(jit,
if test "$enable_jit" = "auto"; then
AC_LANG(C)
+ SAVE_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS=-I$srcdir
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#define SLJIT_CONFIG_AUTO 1
#include "sljit/sljitConfigInternal.h"
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
#error unsupported
#endif]])], enable_jit=yes, enable_jit=no)
+ CPPFLAGS=$SAVE_CPPFLAGS
fi
# Handle --disable-pcregrep-jit (enabled by default)
diff --git a/pcre/doc/html/README.txt b/pcre/doc/html/README.txt
index 4887ebf350e..334362b3e53 100644
--- a/pcre/doc/html/README.txt
+++ b/pcre/doc/html/README.txt
@@ -13,9 +13,10 @@ libraries.
The latest release of PCRE1 is always available in three alternative formats
from:
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2
- ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip
+ https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.gz
+ https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.bz2
+ https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.zip
+
There is a mailing list for discussion about the development of PCRE at
pcre-dev@exim.org. You can access the archives and subscribe or manage your
@@ -999,4 +1000,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
Philip Hazel
Email local part: ph10
Email domain: cam.ac.uk
-Last updated: 10 February 2015
+Last updated: 12 February 2020
diff --git a/pcre/doc/html/pcre.html b/pcre/doc/html/pcre.html
index c87b1066427..0db75e44892 100644
--- a/pcre/doc/html/pcre.html
+++ b/pcre/doc/html/pcre.html
@@ -143,7 +143,7 @@ performance.
One way of guarding against this possibility is to use the
<b>pcre_fullinfo()</b> function to check the compiled pattern's options for UTF.
Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF option at
-compile time. This causes an compile time error if a pattern contains a
+compile time. This causes a compile time error if a pattern contains a
UTF-setting sequence.
</P>
<P>
diff --git a/pcre/doc/html/pcreapi.html b/pcre/doc/html/pcreapi.html
index 2d7adf185a6..2fdfbff5ccf 100644
--- a/pcre/doc/html/pcreapi.html
+++ b/pcre/doc/html/pcreapi.html
@@ -1246,7 +1246,7 @@ the following negative numbers:
PCRE_ERROR_BADOPTION the value of <i>what</i> was invalid
PCRE_ERROR_UNSET the requested field is not set
</pre>
-The "magic number" is placed at the start of each compiled pattern as an simple
+The "magic number" is placed at the start of each compiled pattern as a simple
check against passing an arbitrary memory pointer. The endianness error can
occur if a compiled pattern is saved and reloaded on a different host. Here is
a typical call of <b>pcre_fullinfo()</b>, to obtain the length of the compiled
@@ -1318,7 +1318,7 @@ returned. For anchored patterns, -2 is returned.
</pre>
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 <b>uint_t</b>
+otherwise return 0. The fourth argument should point to a <b>uint_t</b>
variable.
</P>
<P>
@@ -1577,7 +1577,7 @@ returned value 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for
</pre>
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 <b>uint32_t</b> variable. If there is no such
+fourth argument should point to a <b>uint32_t</b> variable. If there is no such
value, 0 is returned.
</P>
<br><a name="SEC16" href="#TOC1">REFERENCE COUNTS</a><br>
diff --git a/pcre/doc/html/pcretest.html b/pcre/doc/html/pcretest.html
index ba540d3c385..842ff3cbe53 100644
--- a/pcre/doc/html/pcretest.html
+++ b/pcre/doc/html/pcretest.html
@@ -99,23 +99,21 @@ the 16-bit library, or <b>pcre32_xx</b> when using the 32-bit library".
<br><a name="SEC4" href="#TOC1">COMMAND LINE OPTIONS</a><br>
<P>
<b>-8</b>
-If both the 8-bit library has been built, this option causes the 8-bit library
-to be used (which is the default); if the 8-bit library has not been built,
-this option causes an error.
+If the 8-bit library has been built, this option causes it to be used (this is
+the default). If the 8-bit library has not been built, this option causes an
+error.
</P>
<P>
<b>-16</b>
-If both the 8-bit or the 32-bit, and the 16-bit libraries have been built, this
-option causes the 16-bit library to be used. If only the 16-bit library has been
-built, this is the default (so has no effect). If only the 8-bit or the 32-bit
-library has been built, this option causes an error.
+If the 16-bit library has been built, this option causes it to be used. If only
+the 16-bit library has been built, this is the default. If the 16-bit library
+has not been built, this option causes an error.
</P>
<P>
<b>-32</b>
-If both the 8-bit or the 16-bit, and the 32-bit libraries have been built, this
-option causes the 32-bit library to be used. If only the 32-bit library has been
-built, this is the default (so has no effect). If only the 8-bit or the 16-bit
-library has been built, this option causes an error.
+If the 32-bit library has been built, this option causes it to be used. If only
+the 32-bit library has been built, this is the default. If the 32-bit library
+has not been built, this option causes an error.
</P>
<P>
<b>-b</b>
@@ -1154,9 +1152,9 @@ Cambridge CB2 3QH, England.
</P>
<br><a name="SEC17" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 23 February 2017
+Last updated: 10 February 2020
<br>
-Copyright &copy; 1997-2017 University of Cambridge.
+Copyright &copy; 1997-2020 University of Cambridge.
<br>
<p>
Return to the <a href="index.html">PCRE index page</a>.
diff --git a/pcre/doc/pcre-config.txt b/pcre/doc/pcre-config.txt
index 8503ab0ef0c..977e46868a8 100644
--- a/pcre/doc/pcre-config.txt
+++ b/pcre/doc/pcre-config.txt
@@ -16,8 +16,8 @@ DESCRIPTION
pcre-config returns the configuration of the installed PCRE libraries
and the options required to compile a program to use them. Some of the
- options apply only to the 8-bit, or 16-bit, or 32-bit libraries,
- respectively, and are not available if only one of those libraries has
+ options apply only to the 8-bit, or 16-bit, or 32-bit libraries, re-
+ spectively, and are not available if only one of those libraries has
been built. If an unavailable option is encountered, the "usage" infor-
mation is output.
@@ -36,37 +36,37 @@ OPTIONS
--version Writes the version number of the installed PCRE libraries to
the standard output.
- --libs Writes to the standard output the command line options
- required to link with the 8-bit PCRE library (-lpcre on many
+ --libs Writes to the standard output the command line options re-
+ quired to link with the 8-bit PCRE library (-lpcre on many
systems).
- --libs16 Writes to the standard output the command line options
- required to link with the 16-bit PCRE library (-lpcre16 on
- many systems).
+ --libs16 Writes to the standard output the command line options re-
+ quired to link with the 16-bit PCRE library (-lpcre16 on many
+ systems).
- --libs32 Writes to the standard output the command line options
- required to link with the 32-bit PCRE library (-lpcre32 on
- many systems).
+ --libs32 Writes to the standard output the command line options re-
+ quired to link with the 32-bit PCRE library (-lpcre32 on many
+ systems).
--libs-cpp
- Writes to the standard output the command line options
- required to link with PCRE's C++ wrapper library (-lpcrecpp
+ Writes to the standard output the command line options re-
+ quired to link with PCRE's C++ wrapper library (-lpcrecpp
-lpcre on many systems).
--libs-posix
- Writes to the standard output the command line options
- required to link with PCRE's POSIX API wrapper library
+ Writes to the standard output the command line options re-
+ quired to link with PCRE's POSIX API wrapper library
(-lpcreposix -lpcre on many systems).
- --cflags Writes to the standard output the command line options
- required to compile files that use PCRE (this may include
- some -I options, but is blank on many systems).
+ --cflags Writes to the standard output the command line options re-
+ quired to compile files that use PCRE (this may include some
+ -I options, but is blank on many systems).
--cflags-posix
- Writes to the standard output the command line options
- required to compile files that use PCRE's POSIX API wrapper
- library (this may include some -I options, but is blank on
- many systems).
+ Writes to the standard output the command line options re-
+ quired to compile files that use PCRE's POSIX API wrapper li-
+ brary (this may include some -I options, but is blank on many
+ systems).
SEE ALSO
diff --git a/pcre/doc/pcre.3 b/pcre/doc/pcre.3
index 0f2837e7c06..716d58044c7 100644
--- a/pcre/doc/pcre.3
+++ b/pcre/doc/pcre.3
@@ -146,7 +146,7 @@ performance.
One way of guarding against this possibility is to use the
\fBpcre_fullinfo()\fP function to check the compiled pattern's options for UTF.
Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF option at
-compile time. This causes an compile time error if a pattern contains a
+compile time. This causes a compile time error if a pattern contains a
UTF-setting sequence.
.P
If your application is one that supports UTF, be aware that validity checking
diff --git a/pcre/doc/pcre.txt b/pcre/doc/pcre.txt
index c027538f500..8ffc90234ac 100644
--- a/pcre/doc/pcre.txt
+++ b/pcre/doc/pcre.txt
@@ -37,10 +37,10 @@ INTRODUCTION
give better JavaScript compatibility.
Starting with release 8.30, it is possible to compile two separate PCRE
- libraries: the original, which supports 8-bit character strings
- (including UTF-8 strings), and a second library that supports 16-bit
- character strings (including UTF-16 strings). The build process allows
- either one or both to be built. The majority of the work to make this
+ libraries: the original, which supports 8-bit character strings (in-
+ cluding UTF-8 strings), and a second library that supports 16-bit char-
+ acter strings (including UTF-16 strings). The build process allows ei-
+ ther one or both to be built. The majority of the work to make this
possible was done by Zoltan Herczeg.
Starting with release 8.32 it is possible to compile a third separate
@@ -121,7 +121,7 @@ SECURITY CONSIDERATIONS
One way of guarding against this possibility is to use the
pcre_fullinfo() function to check the compiled pattern's options for
UTF. Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF
- option at compile time. This causes an compile time error if a pattern
+ option at compile time. This causes a compile time error if a pattern
contains a UTF-setting sequence.
If your application is one that supports UTF, be aware that validity
@@ -314,12 +314,12 @@ THE PCRE 16-BIT LIBRARY
Starting with release 8.30, it is possible to compile a PCRE library
that supports 16-bit character strings, including UTF-16 strings, as
well as or instead of the original 8-bit library. The majority of the
- work to make this possible was done by Zoltan Herczeg. The two
- libraries contain identical sets of functions, used in exactly the same
+ work to make this possible was done by Zoltan Herczeg. The two li-
+ braries contain identical sets of functions, used in exactly the same
way. Only the names of the functions and the data types of their argu-
ments and results are different. To avoid over-complication and reduce
- the documentation maintenance load, most of the PCRE documentation
- describes the 8-bit library, with only occasional references to the
+ the documentation maintenance load, most of the PCRE documentation de-
+ scribes the 8-bit library, with only occasional references to the
16-bit library. This page describes what is different when you use the
16-bit library.
@@ -350,12 +350,12 @@ STRING TYPES
In the 8-bit library, strings are passed to PCRE library functions as
vectors of bytes with the C type "char *". In the 16-bit library,
strings are passed as vectors of unsigned 16-bit quantities. The macro
- PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is
- defined as "const PCRE_UCHAR16 *". In very many environments, "short
- int" is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16
- as "unsigned short int", but checks that it really is a 16-bit data
- type. If it is not, the build fails with an error message telling the
- maintainer to modify the definition appropriately.
+ PCRE_UCHAR16 specifies an appropriate data type, and PCRE_SPTR16 is de-
+ fined as "const PCRE_UCHAR16 *". In very many environments, "short int"
+ is a 16-bit data type. When PCRE is built, it defines PCRE_UCHAR16 as
+ "unsigned short int", but checks that it really is a 16-bit data type.
+ If it is not, the build fails with an error message telling the main-
+ tainer to modify the definition appropriately.
STRUCTURE TYPES
@@ -424,9 +424,9 @@ OPTION NAMES
There are two new general option names, PCRE_UTF16 and
PCRE_NO_UTF16_CHECK, which correspond to PCRE_UTF8 and
- PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options
- define the same bits in the options word. There is a discussion about
- the validity of UTF-16 strings in the pcreunicode page.
+ PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options de-
+ fine the same bits in the options word. There is a discussion about the
+ validity of UTF-16 strings in the pcreunicode page.
For the pcre16_config() function there is an option PCRE_CONFIG_UTF16
that returns 1 if UTF-16 support is configured, otherwise 0. If this
@@ -464,8 +464,8 @@ ERROR NAMES
patterns in the other mode, for example, if a pattern compiled with
pcre_compile() is passed to pcre16_exec().
- There are new error codes whose names begin with PCRE_UTF16_ERR for
- invalid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for
+ There are new error codes whose names begin with PCRE_UTF16_ERR for in-
+ valid UTF-16 strings, corresponding to the PCRE_UTF8_ERR codes for
UTF-8 strings that are described in the section entitled "Reason codes
for invalid UTF-8 strings" in the main pcreapi page. The UTF-16 errors
are:
@@ -509,8 +509,8 @@ TESTING
NOT SUPPORTED IN 16-BIT MODE
Not all the features of the 8-bit library are available with the 16-bit
- library. The C++ and POSIX wrapper functions support only the 8-bit
- library, and the pcregrep program is at present 8-bit only.
+ library. The C++ and POSIX wrapper functions support only the 8-bit li-
+ brary, and the pcregrep program is at present 8-bit only.
AUTHOR
@@ -651,8 +651,8 @@ THE PCRE 32-BIT LIBRARY
and the data types of their arguments and results are different. To
avoid over-complication and reduce the documentation maintenance load,
most of the PCRE documentation describes the 8-bit library, with only
- occasional references to the 16-bit and 32-bit libraries. This page
- describes what is different when you use the 32-bit library.
+ occasional references to the 16-bit and 32-bit libraries. This page de-
+ scribes what is different when you use the 32-bit library.
WARNING: A single application can be linked with all or any of the
three libraries, but you must take care when processing any particular
@@ -681,8 +681,8 @@ STRING TYPES
In the 8-bit library, strings are passed to PCRE library functions as
vectors of bytes with the C type "char *". In the 32-bit library,
strings are passed as vectors of unsigned 32-bit quantities. The macro
- PCRE_UCHAR32 specifies an appropriate data type, and PCRE_SPTR32 is
- defined as "const PCRE_UCHAR32 *". In very many environments, "unsigned
+ PCRE_UCHAR32 specifies an appropriate data type, and PCRE_SPTR32 is de-
+ fined as "const PCRE_UCHAR32 *". In very many environments, "unsigned
int" is a 32-bit data type. When PCRE is built, it defines PCRE_UCHAR32
as "unsigned int", but checks that it really is a 32-bit data type. If
it is not, the build fails with an error message telling the maintainer
@@ -755,9 +755,9 @@ OPTION NAMES
There are two new general option names, PCRE_UTF32 and
PCRE_NO_UTF32_CHECK, which correspond to PCRE_UTF8 and
- PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options
- define the same bits in the options word. There is a discussion about
- the validity of UTF-32 strings in the pcreunicode page.
+ PCRE_NO_UTF8_CHECK in the 8-bit library. In fact, these new options de-
+ fine the same bits in the options word. There is a discussion about the
+ validity of UTF-32 strings in the pcreunicode page.
For the pcre32_config() function there is an option PCRE_CONFIG_UTF32
that returns 1 if UTF-32 support is configured, otherwise 0. If this
@@ -793,8 +793,8 @@ ERROR NAMES
to a function that processes patterns in the other mode, for example,
if a pattern compiled with pcre_compile() is passed to pcre32_exec().
- There are new error codes whose names begin with PCRE_UTF32_ERR for
- invalid UTF-32 strings, corresponding to the PCRE_UTF8_ERR codes for
+ There are new error codes whose names begin with PCRE_UTF32_ERR for in-
+ valid UTF-32 strings, corresponding to the PCRE_UTF8_ERR codes for
UTF-8 strings that are described in the section entitled "Reason codes
for invalid UTF-8 strings" in the main pcreapi page. The UTF-32 errors
are:
@@ -837,8 +837,8 @@ TESTING
NOT SUPPORTED IN 32-BIT MODE
Not all the features of the 8-bit library are available with the 32-bit
- library. The C++ and POSIX wrapper functions support only the 8-bit
- library, and the pcregrep program is at present 8-bit only.
+ library. The C++ and POSIX wrapper functions support only the 8-bit li-
+ brary, and the pcregrep program is at present 8-bit only.
AUTHOR
@@ -866,8 +866,8 @@ BUILDING PCRE
PCRE is distributed with a configure script that can be used to build
the library in Unix-like environments using the applications known as
- Autotools. Also in the distribution are files to support building
- using CMake instead of configure. The text file README contains general
+ Autotools. Also in the distribution are files to support building us-
+ ing CMake instead of configure. The text file README contains general
information about building with Autotools (some of which is repeated
below), and also has some comments about building on various operating
systems. There is a lot more information about building PCRE without
@@ -892,13 +892,13 @@ PCRE BUILD-TIME OPTIONS
compiler, as described in NON-AUTOTOOLS-BUILD.
The complete list of options for configure (which includes the standard
- ones such as the selection of the installation directory) can be
- obtained by running
+ ones such as the selection of the installation directory) can be ob-
+ tained by running
./configure --help
- The following sections include descriptions of options whose names
- begin with --enable or --disable. These settings specify changes to the
+ The following sections include descriptions of options whose names be-
+ gin with --enable or --disable. These settings specify changes to the
defaults for the configure command. Because of the way that configure
works, --enable and --disable always come in pairs, so the complemen-
tary option always exists as well, but as it specifies the default, it
@@ -916,8 +916,8 @@ BUILDING 8-BIT, 16-BIT AND 32-BIT LIBRARIES
--enable-pcre16
- to the configure command. You can also build yet another separate
- library, called libpcre32, in which strings are contained in vectors of
+ to the configure command. You can also build yet another separate li-
+ brary, called libpcre32, in which strings are contained in vectors of
32-bit data units and interpreted either as single-unit characters or
UTF-32 strings, by adding
@@ -965,8 +965,8 @@ UTF-8, UTF-16 AND UTF-32 SUPPORT
to the configure command. This setting applies to all three libraries,
adding support for UTF-8 to the 8-bit library, support for UTF-16 to
- the 16-bit library, and support for UTF-32 to the to the 32-bit
- library. There are no separate options for enabling UTF-8, UTF-16 and
+ the 16-bit library, and support for UTF-32 to the to the 32-bit li-
+ brary. There are no separate options for enabling UTF-8, UTF-16 and
UTF-32 independently because that would allow ridiculous settings such
as requesting UTF-16 support while building only the 8-bit library. It
is not possible to build one library with UTF support and another with-
@@ -975,8 +975,8 @@ UTF-8, UTF-16 AND UTF-32 SUPPORT
Of itself, this setting does not make PCRE treat strings as UTF-8,
UTF-16 or UTF-32. As well as compiling PCRE with this option, you also
- have have to set the PCRE_UTF8, PCRE_UTF16 or PCRE_UTF32 option (as
- appropriate) when you call one of the pattern compiling functions.
+ have have to set the PCRE_UTF8, PCRE_UTF16 or PCRE_UTF32 option (as ap-
+ propriate) when you call one of the pattern compiling functions.
If you set --enable-utf when compiling in an EBCDIC environment, PCRE
expects its input to be either ASCII or UTF-8 (depending on the run-
@@ -1010,9 +1010,9 @@ JUST-IN-TIME COMPILER SUPPORT
--enable-jit
This support is available only for certain hardware architectures. If
- this option is set for an unsupported architecture, a compile time
- error occurs. See the pcrejit documentation for a discussion of JIT
- usage. When JIT support is enabled, pcregrep automatically makes use of
+ this option is set for an unsupported architecture, a compile time er-
+ ror occurs. See the pcrejit documentation for a discussion of JIT us-
+ age. When JIT support is enabled, pcregrep automatically makes use of
it, unless you add
--disable-pcregrep-jit
@@ -1029,8 +1029,8 @@ CODE VALUE OF NEWLINE
--enable-newline-is-cr
- to the configure command. There is also a --enable-newline-is-lf
- option, which explicitly specifies linefeed as the newline character.
+ to the configure command. There is also a --enable-newline-is-lf op-
+ tion, which explicitly specifies linefeed as the newline character.
Alternatively, you can specify that line endings are to be indicated by
the two character sequence CRLF. If you want this, add
@@ -1124,12 +1124,12 @@ AVOIDING EXCESSIVE STACK USAGE
can replace the pointers so that your own functions are used instead.
Separate functions are provided rather than using pcre_malloc and
- pcre_free because the usage is very predictable: the block sizes
- requested are always the same, and the blocks are always freed in
- reverse order. A calling program might be able to implement optimized
- functions that perform better than malloc() and free(). PCRE runs
- noticeably more slowly when built in this way. This option affects only
- the pcre_exec() function; it is not relevant for pcre_dfa_exec().
+ pcre_free because the usage is very predictable: the block sizes re-
+ quested are always the same, and the blocks are always freed in reverse
+ order. A calling program might be able to implement optimized functions
+ that perform better than malloc() and free(). PCRE runs noticeably more
+ slowly when built in this way. This option affects only the pcre_exec()
+ function; it is not relevant for pcre_dfa_exec().
LIMITING PCRE RESOURCE USAGE
@@ -1152,9 +1152,9 @@ LIMITING PCRE RESOURCE USAGE
calls of match() more strictly than the total number of calls, in order
to restrict the maximum amount of stack (or heap, if --disable-stack-
for-recursion is specified) that is used. A second limit controls this;
- it defaults to the value that is set for --with-match-limit, which
- imposes no additional constraints. However, you can set a lower limit
- by adding, for example,
+ it defaults to the value that is set for --with-match-limit, which im-
+ poses no additional constraints. However, you can set a lower limit by
+ adding, for example,
--with-match-limit-recursion=10000
@@ -1190,9 +1190,9 @@ USING EBCDIC CODE
--enable-ebcdic
to the configure command. This setting implies --enable-rebuild-charta-
- bles. You should only use it if you know that you are in an EBCDIC
- environment (for example, an IBM mainframe operating system). The
- --enable-ebcdic option is incompatible with --enable-utf.
+ bles. You should only use it if you know that you are in an EBCDIC en-
+ vironment (for example, an IBM mainframe operating system). The --en-
+ able-ebcdic option is incompatible with --enable-utf.
The EBCDIC character that corresponds to an ASCII LF is assumed to have
the value 0x15 by default. However, in some EBCDIC environments, 0x25
@@ -1246,8 +1246,8 @@ PCRETEST OPTION FOR LIBREADLINE SUPPORT
--enable-pcretest-libreadline
- to the configure command, pcretest is linked with the libreadline
- library, and when its input is from a terminal, it reads it using the
+ to the configure command, pcretest is linked with the libreadline li-
+ brary, and when its input is from a terminal, it reads it using the
readline() function. This provides line-editing and history facilities.
Note that libreadline is GPL-licensed, so if you distribute a binary of
pcretest linked in this way, there may be licensing issues.
@@ -1278,8 +1278,8 @@ DEBUGGING WITH VALGRIND SUPPORT
--enable-valgrind
option to to the configure command, PCRE will use valgrind annotations
- to mark certain memory regions as unaddressable. This allows it to
- detect invalid memory accesses, and is mostly useful for debugging PCRE
+ to mark certain memory regions as unaddressable. This allows it to de-
+ tect invalid memory accesses, and is mostly useful for debugging PCRE
itself.
@@ -1372,8 +1372,8 @@ PCRE MATCHING ALGORITHMS
ject string. The "standard" algorithm is the one provided by the
pcre_exec(), pcre16_exec() and pcre32_exec() functions. These work in
the same as as Perl's matching function, and provide a Perl-compatible
- matching operation. The just-in-time (JIT) optimization that is
- described in the pcrejit documentation is compatible with these func-
+ matching operation. The just-in-time (JIT) optimization that is de-
+ scribed in the pcrejit documentation is compatible with these func-
tions.
An alternative algorithm is provided by the pcre_dfa_exec(),
@@ -1448,8 +1448,8 @@ THE ALTERNATIVE MATCHING ALGORITHM
Although the general principle of this matching algorithm is that it
scans the subject string only once, without backtracking, there is one
exception: when a lookaround assertion is encountered, the characters
- following or preceding the current point have to be independently
- inspected.
+ following or preceding the current point have to be independently in-
+ spected.
The scan continues until either the end of the subject is reached, or
there are no more unterminated paths. At this point, terminated paths
@@ -1482,9 +1482,9 @@ THE ALTERNATIVE MATCHING ALGORITHM
There are a number of features of PCRE regular expressions that are not
supported by the alternative matching algorithm. They are as follows:
- 1. Because the algorithm finds all possible matches, the greedy or
- ungreedy nature of repetition quantifiers is not relevant. Greedy and
- ungreedy quantifiers are treated in exactly the same way. However, pos-
+ 1. Because the algorithm finds all possible matches, the greedy or un-
+ greedy nature of repetition quantifiers is not relevant. Greedy and un-
+ greedy quantifiers are treated in exactly the same way. However, pos-
sessive quantifiers can make a difference when what follows could also
match what is quantified, for example in a pattern like this:
@@ -1498,8 +1498,8 @@ THE ALTERNATIVE MATCHING ALGORITHM
2. When dealing with multiple paths through the tree simultaneously, it
is not straightforward to keep track of captured substrings for the
- different matching possibilities, and PCRE's implementation of this
- algorithm does not attempt to do this. This means that no captured sub-
+ different matching possibilities, and PCRE's implementation of this al-
+ gorithm does not attempt to do this. This means that no captured sub-
strings are available.
3. Because no substrings are captured, back references within the pat-
@@ -1509,10 +1509,10 @@ THE ALTERNATIVE MATCHING ALGORITHM
ence as the condition or test for a specific group recursion are not
supported.
- 5. Because many paths through the tree may be active, the \K escape
- sequence, which resets the start of the match when encountered (but may
- be on some paths and not on others), is not supported. It causes an
- error if encountered.
+ 5. Because many paths through the tree may be active, the \K escape se-
+ quence, which resets the start of the match when encountered (but may
+ be on some paths and not on others), is not supported. It causes an er-
+ ror if encountered.
6. Callouts are supported, but the value of the capture_top field is
always 1, and the value of the capture_last field is always -1.
@@ -1719,10 +1719,10 @@ PCRE API OVERVIEW
PCRE has its own native API, which is described in this document. There
are also some wrapper functions (for the 8-bit library only) that cor-
- respond to the POSIX regular expression API, but they do not give
- access to all the functionality. They are described in the pcreposix
- documentation. Both of these APIs define a set of C function calls. A
- C++ wrapper (again for the 8-bit library only) is also distributed with
+ respond to the POSIX regular expression API, but they do not give ac-
+ cess to all the functionality. They are described in the pcreposix doc-
+ umentation. Both of these APIs define a set of C function calls. A C++
+ wrapper (again for the 8-bit library only) is also distributed with
PCRE. It is documented in the pcrecpp page.
The native API C function prototypes are defined in the header file
@@ -1734,10 +1734,10 @@ PCRE API OVERVIEW
for different releases of PCRE.
In a Windows environment, if you want to statically link an application
- program against a non-dll pcre.a file, you must define PCRE_STATIC
- before including pcre.h or pcrecpp.h, because otherwise the pcre_mal-
- loc() and pcre_free() exported functions will be declared
- __declspec(dllimport), with unwanted results.
+ program against a non-dll pcre.a file, you must define PCRE_STATIC be-
+ fore including pcre.h or pcrecpp.h, because otherwise the pcre_malloc()
+ and pcre_free() exported functions will be declared __declspec(dl-
+ limport), with unwanted results.
The functions pcre_compile(), pcre_compile2(), pcre_study(), and
pcre_exec() are used for compiling and matching regular expressions in
@@ -1749,10 +1749,10 @@ PCRE API OVERVIEW
Just-in-time compiler support is an optional feature of PCRE that can
be built in appropriate hardware environments. It greatly speeds up the
- matching performance of many patterns. Simple programs can easily
- request that it be used if available, by setting an option that is
- ignored when it is not relevant. More complicated programs might need
- to make use of the functions pcre_jit_stack_alloc(),
+ matching performance of many patterns. Simple programs can easily re-
+ quest that it be used if available, by setting an option that is ig-
+ nored when it is not relevant. More complicated programs might need to
+ make use of the functions pcre_jit_stack_alloc(),
pcre_jit_stack_free(), and pcre_assign_jit_stack() in order to control
the JIT code's memory usage.
@@ -1784,39 +1784,37 @@ PCRE API OVERVIEW
pcre_free_substring() and pcre_free_substring_list() are also provided,
to free the memory used for extracted strings.
- The function pcre_maketables() is used to build a set of character
- tables in the current locale for passing to pcre_compile(),
- pcre_exec(), or pcre_dfa_exec(). This is an optional facility that is
- provided for specialist use. Most commonly, no special tables are
- passed, in which case internal tables that are generated when PCRE is
- built are used.
+ The function pcre_maketables() is used to build a set of character ta-
+ bles in the current locale for passing to pcre_compile(), pcre_exec(),
+ or pcre_dfa_exec(). This is an optional facility that is provided for
+ specialist use. Most commonly, no special tables are passed, in which
+ case internal tables that are generated when PCRE is built are used.
- The function pcre_fullinfo() is used to find out information about a
- compiled pattern. The function pcre_version() returns a pointer to a
+ The function pcre_fullinfo() is used to find out information about a
+ compiled pattern. The function pcre_version() returns a pointer to a
string containing the version of PCRE and its date of release.
- The function pcre_refcount() maintains a reference count in a data
- block containing a compiled pattern. This is provided for the benefit
+ The function pcre_refcount() maintains a reference count in a data
+ block containing a compiled pattern. This is provided for the benefit
of object-oriented applications.
- The global variables pcre_malloc and pcre_free initially contain the
- entry points of the standard malloc() and free() functions, respec-
+ The global variables pcre_malloc and pcre_free initially contain the
+ entry points of the standard malloc() and free() functions, respec-
tively. PCRE calls the memory management functions via these variables,
- so a calling program can replace them if it wishes to intercept the
+ so a calling program can replace them if it wishes to intercept the
calls. This should be done before calling any PCRE functions.
- The global variables pcre_stack_malloc and pcre_stack_free are also
- indirections to memory management functions. These special functions
- are used only when PCRE is compiled to use the heap for remembering
- data, instead of recursive function calls, when running the pcre_exec()
- function. See the pcrebuild documentation for details of how to do
- this. It is a non-standard way of building PCRE, for use in environ-
- 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 always allocate memory blocks of the same size.
- There is a discussion about PCRE's stack usage in the pcrestack docu-
- mentation.
+ The global variables pcre_stack_malloc and pcre_stack_free are also in-
+ directions to memory management functions. These special functions are
+ used only when PCRE is compiled to use the heap for remembering data,
+ instead of recursive function calls, when running the pcre_exec() func-
+ tion. See the pcrebuild 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 func-
+ tions always allocate memory blocks of the same size. There is a dis-
+ cussion about PCRE's stack usage in the pcrestack documentation.
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
@@ -1915,24 +1913,24 @@ CHECKING BUILD-TIME OPTIONS
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
- PCRE_ERROR_BADOPTION.
+ the 16-bit or 32-bit version of this function, the result is PCRE_ER-
+ ROR_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
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
- PCRE_ERROR_BADOPTION.
+ to the 8-bit or 32-bit version of this function, the result is PCRE_ER-
+ ROR_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
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
- PCRE_ERROR_BADOPTION.
+ to the 8-bit or 16-bit version of this function, the result is PCRE_ER-
+ ROR_BADOPTION.
PCRE_CONFIG_UNICODE_PROPERTIES
@@ -1949,8 +1947,8 @@ CHECKING BUILD-TIME OPTIONS
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
- result is NULL.
+ (little endian + unaligned)". If JIT support is not available, the re-
+ sult is NULL.
PCRE_CONFIG_NEWLINE
@@ -1973,15 +1971,15 @@ CHECKING BUILD-TIME OPTIONS
PCRE_CONFIG_LINK_SIZE
- 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
- 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
- of slower matching.
+ The output is an integer that contains the number of bytes used for in-
+ ternal 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 ei-
+ ther 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 of
+ slower matching.
PCRE_CONFIG_POSIX_MALLOC_THRESHOLD
@@ -2009,8 +2007,8 @@ CHECKING BUILD-TIME OPTIONS
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()
- below.
+ pcre_exec() execution. Further details are given with pcre_exec() be-
+ low.
PCRE_CONFIG_STACKRECURSE
@@ -2042,11 +2040,11 @@ COMPILING A PATTERN
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
- 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
+ the pattern argument. A pointer to a single block of memory that is ob-
+ tained 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
@@ -2089,12 +2087,12 @@ COMPILING A PATTERN
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
- locale support below.
+ character tables that are built when PCRE is compiled, using the de-
+ fault C locale. Otherwise, tableptr must be an address that is the re-
+ sult of a call to pcre_maketables(). This value is stored with the com-
+ piled 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-
pile():
@@ -2178,13 +2176,13 @@ COMPILING A PATTERN
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
- between an item and a following quantifier and between a quantifier and
- a following + that indicates possessiveness.
+ If this bit is set, most white space characters in the pattern are to-
+ tally ignored except when escaped or inside a character class. However,
+ 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 follow-
+ ing + 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
@@ -2196,17 +2194,17 @@ COMPILING A PATTERN
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-
- tions" in the pcrepattern documentation. Note that the end of this type
- of comment is a literal newline sequence in the pattern; escape
- sequences that happen to represent a newline do not count.
+ Which characters are interpreted as newlines is controlled by the op-
+ tions passed to pcre_compile() or by a special sequence at the start of
+ the pattern, as described in the section entitled "Newline conventions"
+ in the pcrepattern documentation. Note that the end of this type 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
- sequences in a pattern, for example within the sequence (?( that intro-
+ White space characters may never appear within special character se-
+ quences in a pattern, for example within the sequence (?( that intro-
duces a conditional subpattern.
PCRE_EXTRA
@@ -2224,9 +2222,9 @@ COMPILING 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
- matched text may continue over the newline.
+ If this option is set, an unanchored pattern is required to match be-
+ fore or at the first newline in the subject string, though the matched
+ text may continue over the newline.
PCRE_JAVASCRIPT_COMPAT
@@ -2529,8 +2527,8 @@ STUDYING A PATTERN
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
- returns a pcre_extra block even if studying did not find any additional
+ pcre_study() is called with the PCRE_STUDY_EXTRA_NEEDED option, it re-
+ turns a pcre_extra block even if studying did not find any additional
information. It may still return NULL, however, if an error occurs in
pcre_study().
@@ -2557,10 +2555,10 @@ STUDYING A PATTERN
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
- after calling pcre_study(), to be sure that it has run successfully.
+ points to is set to NULL. Otherwise it is set to point to a textual er-
+ ror 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 af-
+ ter 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
the study data by calling pcre_free_study(). This function was added to
@@ -2635,10 +2633,10 @@ LOCALE SUPPORT
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
- 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,
+ argument of pcre_compile() is NULL. These are sufficient for many ap-
+ plications. Normally, the internal tables recognize only ASCII charac-
+ ters. However, when PCRE is built, it is possible to cause the internal
+ 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
@@ -2649,9 +2647,9 @@ LOCALE SUPPORT
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:
+ and use tables that are appropriate for the French locale (where ac-
+ cented characters with values greater than 128 are treated as letters),
+ the following code could be used:
setlocale(LC_CTYPE, "fr_FR");
tables = pcre_maketables();
@@ -2660,8 +2658,8 @@ LOCALE SUPPORT
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
+ When pcre_maketables() runs, the tables are built in memory that is ob-
+ tained 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.
@@ -2706,9 +2704,9 @@ 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-
- anness error can occur if a compiled pattern is saved and reloaded on a
+ The "magic number" is placed at the start of each compiled pattern as a
+ simple check against passing an arbitrary memory pointer. The endian-
+ ness 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
the length of the compiled pattern:
@@ -2745,12 +2743,12 @@ INFORMATION ABOUT A PATTERN
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 li-
+ brary, where data units are bytes. The fourth argument should point to
+ an int variable. Negative values are used for special cases. However,
+ 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 reason, 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
@@ -2774,14 +2772,14 @@ INFORMATION ABOUT A PATTERN
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
+ matched string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS re-
+ turns 1; otherwise return 0. The fourth argument should point to a
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
- using UTF-32 mode.
+ mode the value can be up to 0x10ffff, and up to 0xffffffff when not us-
+ ing UTF-32 mode.
PCRE_INFO_FIRSTCHARACTERFLAGS
@@ -2853,8 +2851,8 @@ INFORMATION ABOUT A PATTERN
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.
+ deprecated; instead the PCRE_INFO_REQUIREDCHARFLAGS and PCRE_INFO_RE-
+ QUIREDCHAR values should be used.
PCRE_INFO_MATCH_EMPTY
@@ -2864,10 +2862,10 @@ INFORMATION ABOUT A PATTERN
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
- PCRE_ERROR_UNSET.
+ (*LIMIT_MATCH=nnnn) at the start, the value is returned. The fourth ar-
+ gument 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_UN-
+ SET.
PCRE_INFO_MAXLOOKBEHIND
@@ -2903,14 +2901,14 @@ INFORMATION ABOUT A PATTERN
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
- described by these three values.
+ the conversion, you need to use the name-to-number map, which is de-
+ scribed 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
- a pointer to the first entry of the table. This is a pointer to char in
+ of each entry; both of these return an int value. The entry size de-
+ pends 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
@@ -2926,9 +2924,9 @@ INFORMATION ABOUT A PATTERN
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
- because later subpatterns may have lower numbers.
+ found in the pattern. In the absence of (?| this is the order of in-
+ creasing number; when (?| is used this is not necessarily the case be-
+ cause later subpatterns may have lower numbers.
As a simple example of the name/number table, consider the following
pattern after compilation by the 8-bit library (assume PCRE_EXTENDED is
@@ -2955,8 +2953,8 @@ INFORMATION ABOUT A PATTERN
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
+ variable. From release 8.00, this always returns 1, because the re-
+ strictions that previously applied to partial matching have been
lifted. The pcrepartial documentation gives details of partial match-
ing.
@@ -2971,8 +2969,8 @@ INFORMATION ABOUT A PATTERN
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
- alternatives begin with one of the following:
+ A pattern is automatically anchored by PCRE if all of its top-level al-
+ ternatives begin with one of the following:
^ unless PCRE_MULTILINE is set
\A always
@@ -2988,13 +2986,13 @@ INFORMATION ABOUT A PATTERN
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
- PCRE_ERROR_UNSET.
+ has been set, the call to pcre_fullinfo() returns the error PCRE_ER-
+ ROR_UNSET.
PCRE_INFO_SIZE
- Return the size of the compiled pattern in bytes (for all three
- libraries). The fourth argument should point to a size_t variable. This
+ Return the size of the compiled pattern in bytes (for all three li-
+ braries). 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
@@ -3024,14 +3022,14 @@ INFORMATION ABOUT A PATTERN
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
- PCRE_INFO_REQUIREDCHAR), but for /^a\dz\d/ the returned value is 0.
+ /^a\d+z\d+/ the returned value 1 (with "z" returned from PCRE_INFO_RE-
+ QUIREDCHAR), 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
+ recorded. The fourth argument should point to a uint32_t variable. If
there is no such value, 0 is returned.
@@ -3065,14 +3063,14 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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
+ was studied, the result of the study should be passed in the extra ar-
+ gument. You can call pcre_exec() with the same code and extra arguments
+ 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 op-
+ erates in a Perl-like manner. For specialist use there is also an al-
+ ternative 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-
@@ -3142,8 +3140,8 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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,
+ repeatedly (sometimes recursively). The limit set by match_limit is im-
+ posed 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.
@@ -3155,12 +3153,12 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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
+ The default value for the limit can be set when PCRE is built; the de-
+ fault 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.
+ pcre_extra block in which match_limit is set, and PCRE_EX-
+ TRA_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
start of a pattern of the form
@@ -3186,9 +3184,9 @@ MATCHING A PATTERN: THE TRADITIONAL FUNCTION
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 pcre_extra block in which match_limit_recursion is set, and PCRE_EX-
+ TRA_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
start of a pattern of the form
@@ -3265,345 +3263,344 @@ 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
- match failure for an unanchored pattern.
+ These options override the newline definition that was chosen or de-
+ faulted when the pattern was compiled. For details, see the description
+ of pcre_compile() above. During matching, the newline choice affects
+ the behaviour of the dot, circumflex, and dollar metacharacters. 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
- advanced by two characters instead of one, in other words, to after the
- CRLF.
+ rent position is at a CRLF sequence, and the pattern contains no ex-
+ plicit 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
- 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-
+ expected. For example, if the pattern is .+A (and the PCRE_DOTALL op-
+ tion 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-
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
- 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
- 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
- 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
- starting offset by two characters instead of one.
+ 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 an-
+ chored, such a match can occur only if the pattern contains \K.
+
+ Perl has no direct equivalent of PCRE_NOTEMPTY or PCRE_NOTEMPTY_AT-
+ START, 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 offset with PCRE_NOTEMPTY_AT-
+ START and PCRE_ANCHORED, and then if that fails, by advancing the
+ starting offset (see below) and trying an ordinary 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 new-
+ line convention recognizes CRLF as a newline, and if so, and the cur-
+ rent 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
- always done using interpretively.
+ pcre_exec()) disables JIT execution; in this situation, matching is al-
+ ways done using interpretively.
- Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching
- operation. Consider the pattern
+ Setting PCRE_NO_START_OPTIMIZE can change the outcome of a matching op-
+ eration. 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
- may be recorded. Consider the pattern
+ 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 re-
+ sult is "no match". If the pattern is studied, more start-up optimiza-
+ tions 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 fi-
+ nally 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
- 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-
+ 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_ER-
+ ROR_BADUTF8 or, if PCRE_PARTIAL_HARD is set and the problem is a trun-
+ cated 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-
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
- 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
- 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
+ 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 li-
+ brary.
+
+ 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 bi-
+ nary 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
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,
- 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
+ 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, be-
+ cause \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
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 re-
+ member 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
- 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
- than the maximum, a non-zero value is returned.
+ match "c" and backing up to try the second alternative. The zero re-
+ turn, however, does correctly indicate that the maximum number of slots
+ (namely 2) have been filled. In similar cases where there is temporary
+ 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
- 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-
- 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,
+ if the string "abc" is matched against the pattern (a|(z))(bc) the re-
+ turn 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 correspond-
+ ing 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,
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)
@@ -3612,7 +3609,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)
@@ -3621,82 +3618,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(),
- and pcre_get_substring_list() functions (see below). It is never
- returned by pcre_exec().
+ This error is used by the pcre_copy_substring(), pcre_get_substring(),
+ and pcre_get_substring_list() functions (see below). It is never re-
+ turned 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),
- PCRE_ERROR_SHORTUTF8 is returned instead of PCRE_ERROR_BADUTF8.
+ 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_ER-
+ ROR_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
- onwards, there are no restrictions on partial matching.
+ 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 on-
+ wards, 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)
@@ -3706,8 +3703,8 @@ 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
- description above.
+ field in a pcre_extra structure (or defaulted) was reached. See the de-
+ scription above.
PCRE_ERROR_BADNEWLINE (-23)
@@ -3720,30 +3717,30 @@ 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
- pcrejit documentation for more details.
+ This error is returned when a pattern that was successfully studied us-
+ ing 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)
@@ -3752,38 +3749,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
- details.
+ This error is returned when a pattern that was successfully studied us-
+ ing a JIT compile option is being matched, but the matching mode (par-
+ tial 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 de-
+ tails.
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 in-
+ formation 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
@@ -3792,10 +3789,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
@@ -3805,24 +3802,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
@@ -3831,28 +3828,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.
@@ -3869,78 +3866,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 re-
+ turned 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 terminating zero, or one of these error codes:
+ 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 ob-
+ tained 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
- error code
+ 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 er-
+ ror 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.
@@ -3959,7 +3956,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(?<xxx>\d+)...
@@ -3968,35 +3965,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.
@@ -4005,77 +4002,77 @@ 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
- hence the captured data, if any.
+ the name-to-number table for the given name. The function itself re-
+ turns the length of each entry, or PCRE_ERROR_NOSUBSTRING (-7) if there
+ are none. The format of the table is described above in the section en-
+ titled Information about a pattern above. Given all the relevant en-
+ tries 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
- 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
+ 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 de-
+ scribed in the pcrestack documentation. The estimate that is output by
+ pcretest when called with the -m and -C options is obtained by calling
+ 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 re-
+ turns 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
- obtained from the heap.
+ If PCRE has been compiled to use the heap instead of the stack for re-
+ cursion, the value returned is the size of each block that is obtained
+ from the heap.
MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
@@ -4085,26 +4082,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():
@@ -4126,55 +4123,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-
- 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
- description is not repeated here.
+ 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_AT-
+ START, PCRE_NO_UTF8_CHECK, PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE,
+ PCRE_NO_START_OPTIMIZE, PCRE_PARTIAL_HARD, PCRE_PARTIAL_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-
- ples, in the pcrepartial documentation.
+ 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 de-
+ tailed discussion of partial and multi-segment matching, with examples,
+ 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
<.*>
@@ -4189,79 +4186,79 @@ MATCHING A PATTERN: THE ALTERNATIVE FUNCTION
<something> <something else>
<something> <something else> <something further>
- 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 de-
+ scribed 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).
@@ -4307,16 +4304,15 @@ DESCRIPTION
the 16-bit library, pcre32_callout for the 32-bit library). By default,
this variable contains NULL, which disables all calling out.
- Within a regular expression, (?C) indicates the points at which the
- external function is to be called. Different callout points can be
- identified by putting a number less than 256 after the letter C. The
- default value is zero. For example, this pattern has two callout
- points:
+ Within a regular expression, (?C) indicates the points at which the ex-
+ ternal function is to be called. Different callout points can be iden-
+ tified by putting a number less than 256 after the letter C. The de-
+ fault value is zero. For example, this pattern has two callout points:
(?C1)abc(?C2)def
- If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled,
- PCRE automatically inserts callouts, all with number 255, before each
+ If the PCRE_AUTO_CALLOUT option bit is set when a pattern is compiled,
+ PCRE automatically inserts callouts, all with number 255, before each
item in the pattern. For example, if PCRE_AUTO_CALLOUT is used with the
pattern
@@ -4326,21 +4322,21 @@ DESCRIPTION
(?C255)A(?C255)((?C255)\d{2}(?C255)|(?C255)-(?C255)-(?C255))(?C255)
- Notice that there is a callout before and after each parenthesis and
+ Notice that there is a callout before and after each parenthesis and
alternation bar. If the pattern contains a conditional group whose con-
- dition is an assertion, an automatic callout is inserted immediately
- before the condition. Such a callout may also be inserted explicitly,
+ dition is an assertion, an automatic callout is inserted immediately
+ before the condition. Such a callout may also be inserted explicitly,
for example:
(?(?C9)(?=a)ab|de)
- This applies only to assertion conditions (because they are themselves
+ This applies only to assertion conditions (because they are themselves
independent groups).
- Automatic callouts can be used for tracking the progress of pattern
- matching. The pcretest program has a pattern qualifier (/C) that sets
- automatic callouts; when it is used, the output indicates how the pat-
- tern is being matched. This is useful information when you are trying
+ Automatic callouts can be used for tracking the progress of pattern
+ matching. The pcretest program has a pattern qualifier (/C) that sets
+ automatic callouts; when it is used, the output indicates how the pat-
+ tern is being matched. This is useful information when you are trying
to optimize the performance of a particular pattern.
@@ -4350,10 +4346,10 @@ MISSING CALLOUTS
piles and matches patterns, callouts sometimes do not happen exactly as
you might expect.
- At compile time, PCRE "auto-possessifies" repeated items when it knows
- that what follows cannot be part of the repeat. For example, a+[bc] is
- compiled as if it were a++[bc]. The pcretest output when this pattern
- is anchored and then applied with automatic callouts to the string
+ At compile time, PCRE "auto-possessifies" repeated items when it knows
+ that what follows cannot be part of the repeat. For example, a+[bc] is
+ compiled as if it were a++[bc]. The pcretest output when this pattern
+ is anchored and then applied with automatic callouts to the string
"aaaa" is:
--->aaaa
@@ -4362,11 +4358,11 @@ MISSING CALLOUTS
+3 ^ ^ [bc]
No match
- This indicates that when matching [bc] fails, there is no backtracking
- into a+ and therefore the callouts that would be taken for the back-
- tracks do not occur. You can disable the auto-possessify feature by
+ This indicates that when matching [bc] fails, there is no backtracking
+ into a+ and therefore the callouts that would be taken for the back-
+ tracks do not occur. You can disable the auto-possessify feature by
passing PCRE_NO_AUTO_POSSESS to pcre_compile(), or starting the pattern
- with (*NO_AUTO_POSSESS). If this is done in pcretest (using the /O
+ with (*NO_AUTO_POSSESS). If this is done in pcretest (using the /O
qualifier), the output changes to this:
--->aaaa
@@ -4381,34 +4377,34 @@ MISSING CALLOUTS
This time, when matching [bc] fails, the matcher backtracks into a+ and
tries again, repeatedly, until a+ itself fails.
- Other optimizations that provide fast "no match" results also affect
+ Other optimizations that provide fast "no match" results also affect
callouts. For example, if the pattern is
ab(?C4)cd
PCRE knows that any matching string must contain the letter "d". If the
- subject string is "abyz", the lack of "d" means that matching doesn't
- ever start, and the callout is never reached. However, with "abyd",
+ subject string is "abyz", the lack of "d" means that matching doesn't
+ ever start, and the callout is never reached. However, with "abyd",
though the result is still no match, the callout is obeyed.
- If the pattern is studied, PCRE knows the minimum length of a matching
- string, and will immediately give a "no match" return without actually
- running a match if the subject is not long enough, or, for unanchored
+ If the pattern is studied, PCRE knows the minimum length of a matching
+ string, and will immediately give a "no match" return without actually
+ running a match if the subject is not long enough, or, for unanchored
patterns, if it has been scanned far enough.
- You can disable these optimizations by passing the PCRE_NO_START_OPTI-
- MIZE option to the matching function, or by starting the pattern with
- (*NO_START_OPT). This slows down the matching process, but does ensure
+ You can disable these optimizations by passing the PCRE_NO_START_OPTI-
+ MIZE option to the matching function, or by starting the pattern with
+ (*NO_START_OPT). This slows down the matching process, but does ensure
that callouts such as the example above are obeyed.
THE CALLOUT INTERFACE
- During matching, when PCRE reaches a callout point, the external func-
+ During matching, when PCRE reaches a callout point, the external func-
tion defined by pcre_callout or pcre[16|32]_callout is called (if it is
- set). This applies to both normal and DFA matching. The only argument
- to the callout function is a pointer to a pcre_callout or
- pcre[16|32]_callout block. These structures contains the following
+ set). This applies to both normal and DFA matching. The only argument
+ to the callout function is a pointer to a pcre_callout or
+ pcre[16|32]_callout block. These structures contains the following
fields:
int version;
@@ -4429,93 +4425,92 @@ THE CALLOUT INTERFACE
const PCRE_UCHAR16 *mark; (16-bit version)
const PCRE_UCHAR32 *mark; (32-bit version)
- The version field is an integer containing the version number of the
- block format. The initial version was 0; the current version is 2. The
- version number will change again in future if additional fields are
+ The version field is an integer containing the version number of the
+ block format. The initial version was 0; the current version is 2. The
+ version number will change again in future if additional fields are
added, but the intention is never to remove any of the existing fields.
- The callout_number field contains the number of the callout, as com-
- piled into the pattern (that is, the number after ?C for manual call-
+ The callout_number field contains the number of the callout, as com-
+ piled into the pattern (that is, the number after ?C for manual call-
outs, and 255 for automatically generated callouts).
- The offset_vector field is a pointer to the vector of offsets that was
- passed by the caller to the matching function. When pcre_exec() or
- pcre[16|32]_exec() is used, the contents can be inspected, in order to
- extract substrings that have been matched so far, in the same way as
- for extracting substrings after a match has completed. For the DFA
+ The offset_vector field is a pointer to the vector of offsets that was
+ passed by the caller to the matching function. When pcre_exec() or
+ pcre[16|32]_exec() is used, the contents can be inspected, in order to
+ extract substrings that have been matched so far, in the same way as
+ for extracting substrings after a match has completed. For the DFA
matching functions, this field is not useful.
The subject and subject_length fields contain copies of the values that
were passed to the matching function.
- The start_match field normally contains the offset within the subject
- at which the current match attempt started. However, if the escape
- sequence \K has been encountered, this value is changed to reflect the
- modified starting point. If the pattern is not anchored, the callout
+ The start_match field normally contains the offset within the subject
+ at which the current match attempt started. However, if the escape se-
+ quence \K has been encountered, this value is changed to reflect the
+ modified starting point. If the pattern is not anchored, the callout
function may be called several times from the same point in the pattern
for different starting points in the subject.
- The current_position field contains the offset within the subject of
+ The current_position field contains the offset within the subject of
the current match pointer.
- When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top
- field contains one more than the number of the highest numbered cap-
- tured substring so far. If no substrings have been captured, the value
- of capture_top is one. This is always the case when the DFA functions
+ When the pcre_exec() or pcre[16|32]_exec() is used, the capture_top
+ field contains one more than the number of the highest numbered cap-
+ tured substring so far. If no substrings have been captured, the value
+ of capture_top is one. This is always the case when the DFA functions
are used, because they do not support captured substrings.
- The capture_last field contains the number of the most recently cap-
- tured substring. However, when a recursion exits, the value reverts to
- what it was outside the recursion, as do the values of all captured
- substrings. If no substrings have been captured, the value of cap-
- ture_last is -1. This is always the case for the DFA matching func-
+ The capture_last field contains the number of the most recently cap-
+ tured substring. However, when a recursion exits, the value reverts to
+ what it was outside the recursion, as do the values of all captured
+ substrings. If no substrings have been captured, the value of cap-
+ ture_last is -1. This is always the case for the DFA matching func-
tions.
- The callout_data field contains a value that is passed to a matching
- function specifically so that it can be passed back in callouts. It is
- passed in the callout_data field of a pcre_extra or pcre[16|32]_extra
- data structure. If no such data was passed, the value of callout_data
- in a callout block is NULL. There is a description of the pcre_extra
+ The callout_data field contains a value that is passed to a matching
+ function specifically so that it can be passed back in callouts. It is
+ passed in the callout_data field of a pcre_extra or pcre[16|32]_extra
+ data structure. If no such data was passed, the value of callout_data
+ in a callout block is NULL. There is a description of the pcre_extra
structure in the pcreapi documentation.
- The pattern_position field is present from version 1 of the callout
+ The pattern_position field is present from version 1 of the callout
structure. It contains the offset to the next item to be matched in the
pattern string.
- The next_item_length field is present from version 1 of the callout
+ The next_item_length field is present from version 1 of the callout
structure. It contains the length of the next item to be matched in the
- pattern string. When the callout immediately precedes an alternation
- bar, a closing parenthesis, or the end of the pattern, the length is
- zero. When the callout precedes an opening parenthesis, the length is
+ pattern string. When the callout immediately precedes an alternation
+ bar, a closing parenthesis, or the end of the pattern, the length is
+ zero. When the callout precedes an opening parenthesis, the length is
that of the entire subpattern.
- The pattern_position and next_item_length fields are intended to help
- in distinguishing between different automatic callouts, which all have
+ The pattern_position and next_item_length fields are intended to help
+ in distinguishing between different automatic callouts, which all have
the same callout number. However, they are set for all callouts.
- The mark field is present from version 2 of the callout structure. In
- callouts from pcre_exec() or pcre[16|32]_exec() it contains a pointer
- to the zero-terminated name of the most recently passed (*MARK),
- (*PRUNE), or (*THEN) item in the match, or NULL if no such items have
- been passed. Instances of (*PRUNE) or (*THEN) without a name do not
- obliterate a previous (*MARK). In callouts from the DFA matching func-
+ The mark field is present from version 2 of the callout structure. In
+ callouts from pcre_exec() or pcre[16|32]_exec() it contains a pointer
+ to the zero-terminated name of the most recently passed (*MARK),
+ (*PRUNE), or (*THEN) item in the match, or NULL if no such items have
+ been passed. Instances of (*PRUNE) or (*THEN) without a name do not
+ obliterate a previous (*MARK). In callouts from the DFA matching func-
tions this field always contains NULL.
RETURN VALUES
- The external callout function returns an integer to PCRE. If the value
- is zero, matching proceeds as normal. If the value is greater than
- zero, matching fails at the current point, but the testing of other
+ The external callout function returns an integer to PCRE. If the value
+ is zero, matching proceeds as normal. If the value is greater than
+ zero, matching fails at the current point, but the testing of other
matching possibilities goes ahead, just as if a lookahead assertion had
- failed. If the value is less than zero, the match is abandoned, the
+ failed. If the value is less than zero, the match is abandoned, the
matching function returns the negative value.
- Negative values should normally be chosen from the set of
- PCRE_ERROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a stan-
- dard "no match" failure. The error number PCRE_ERROR_CALLOUT is
- reserved for use by callout functions; it will never be used by PCRE
- itself.
+ Negative values should normally be chosen from the set of PCRE_ER-
+ ROR_xxx values. In particular, PCRE_ERROR_NOMATCH forces a standard "no
+ match" failure. The error number PCRE_ERROR_CALLOUT is reserved for
+ use by callout functions; it will never be used by PCRE itself.
AUTHOR
@@ -4542,8 +4537,8 @@ NAME
DIFFERENCES BETWEEN PCRE AND PERL
This document describes the differences in the ways that PCRE and Perl
- handle regular expressions. The differences described here are with
- respect to Perl versions 5.10 and above.
+ handle regular expressions. The differences described here are with re-
+ spect to Perl versions 5.10 and above.
1. PCRE has only a subset of Perl's Unicode support. Details of what it
does have are given in the pcreunicode page.
@@ -4614,8 +4609,8 @@ DIFFERENCES BETWEEN PCRE AND PERL
the section on recursion differences from Perl in the pcrepattern page.
10. If any of the backtracking control verbs are used in a subpattern
- that is called as a subroutine (whether or not recursively), their
- effect is confined to that subpattern; it does not extend to the sur-
+ that is called as a subroutine (whether or not recursively), their ef-
+ fect is confined to that subpattern; it does not extend to the sur-
rounding pattern. This is not always the case in Perl. In particular,
if (*THEN) is present in a group that is called as a subroutine, its
action is limited to that group, even if the group does not contain any
@@ -4633,8 +4628,8 @@ DIFFERENCES BETWEEN PCRE AND PERL
13. There are some differences that are concerned with the settings of
captured strings when part of a pattern is repeated. For example,
- matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2
- unset, but in PCRE it is set to "b".
+ matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 un-
+ set, but in PCRE it is set to "b".
14. PCRE's handling of duplicate subpattern numbers and duplicate sub-
pattern names is not as general as Perl's. This is a consequence of the
@@ -4647,11 +4642,11 @@ DIFFERENCES BETWEEN PCRE AND PERL
turing subpattern number 1. To avoid this confusing situation, an error
is given at compile time.
- 15. Perl recognizes comments in some places that PCRE does not, for
- example, between the ( and ? at the start of a subpattern. If the /x
- modifier is set, Perl allows white space between ( and ? (though cur-
- rent Perls warn that this is deprecated) but PCRE never does, even if
- the PCRE_EXTENDED option is set.
+ 15. Perl recognizes comments in some places that PCRE does not, for ex-
+ ample, between the ( and ? at the start of a subpattern. If the /x mod-
+ ifier is set, Perl allows white space between ( and ? (though current
+ Perls warn that this is deprecated) but PCRE never does, even if the
+ PCRE_EXTENDED option is set.
16. Perl, when in warning mode, gives warnings for character classes
such as [A-\d] or [a-[:digit:]]. It then treats the hyphens as liter-
@@ -4746,10 +4741,10 @@ PCRE REGULAR EXPRESSION DETAILS
Perl's regular expressions are described in its own documentation, and
regular expressions in general are covered in a number of books, some
- of which have copious examples. Jeffrey Friedl's "Mastering Regular
- Expressions", published by O'Reilly, covers regular expressions in
- great detail. This description of PCRE's regular expressions is
- intended as reference material.
+ of which have copious examples. Jeffrey Friedl's "Mastering Regular Ex-
+ pressions", published by O'Reilly, covers regular expressions in great
+ detail. This description of PCRE's regular expressions is intended as
+ reference material.
This document discusses the patterns that are supported by PCRE when
one its main matching functions, pcre_exec() (8-bit) or
@@ -4768,8 +4763,8 @@ SPECIAL START-OF-PATTERN ITEMS
set by special items at the start of a pattern. These are not Perl-com-
patible, but are provided to make these options accessible to pattern
writers who are not able to change the program that processes the pat-
- tern. Any number of these items may appear, but they must all be
- together right at the start of the pattern string, and the letters must
+ tern. Any number of these items may appear, but they must all be to-
+ gether right at the start of the pattern string, and the letters must
be in upper case.
UTF support
@@ -4788,16 +4783,16 @@ SPECIAL START-OF-PATTERN ITEMS
(*UTF32)
(*UTF)
- (*UTF) is a generic sequence that can be used with any of the
- libraries. Starting a pattern with such a sequence is equivalent to
- setting the relevant option. How setting a UTF mode affects pattern
- matching is mentioned in several places below. There is also a summary
- of features in the pcreunicode page.
+ (*UTF) is a generic sequence that can be used with any of the li-
+ braries. Starting a pattern with such a sequence is equivalent to set-
+ ting the relevant option. How setting a UTF mode affects pattern match-
+ ing is mentioned in several places below. There is also a summary of
+ features in the pcreunicode page.
Some applications that allow their users to supply patterns may wish to
restrict them to non-UTF data for security reasons. If the
- PCRE_NEVER_UTF option is set at compile time, (*UTF) etc. are not
- allowed, and their appearance causes an error.
+ PCRE_NEVER_UTF option is set at compile time, (*UTF) etc. are not al-
+ lowed, and their appearance causes an error.
Unicode property support
@@ -4841,8 +4836,8 @@ SPECIAL START-OF-PATTERN ITEMS
(*ANY) all Unicode newline sequences
These override the default and the options given to the compiling func-
- tion. For example, on a Unix system where LF is the default newline
- sequence, the pattern
+ tion. For example, on a Unix system where LF is the default newline se-
+ quence, the pattern
(*CR)a.b
@@ -4909,8 +4904,8 @@ CHARACTERS AND METACHARACTERS
matching for characters 128 and above, you must ensure that PCRE is
compiled with Unicode property support as well as with UTF support.
- The power of regular expressions comes from the ability to include
- alternatives and repetitions in the pattern. These are encoded in the
+ The power of regular expressions comes from the ability to include al-
+ ternatives and repetitions in the pattern. These are encoded in the
pattern by the use of metacharacters, which do not stand for themselves
but instead are interpreted in some special way.
@@ -4974,9 +4969,9 @@ BACKSLASH
If you want to remove the special meaning from a sequence of charac-
ters, you can do so by putting them between \Q and \E. This is differ-
- ent from Perl in that $ and @ are handled as literals in \Q...\E
- sequences in PCRE, whereas in Perl, $ and @ cause variable interpola-
- tion. Note the following examples:
+ ent from Perl in that $ and @ are handled as literals in \Q...\E se-
+ quences in PCRE, whereas in Perl, $ and @ cause variable interpolation.
+ Note the following examples:
Pattern PCRE matches Perl matches
@@ -4998,8 +4993,8 @@ BACKSLASH
acters in patterns in a visible manner. There is no restriction on the
appearance of non-printing characters, apart from the binary zero that
terminates a pattern, but when a pattern is being prepared by text
- editing, it is often easier to use one of the following escape
- sequences than the binary character it represents. In an ASCII or Uni-
+ editing, it is often easier to use one of the following escape se-
+ quences than the binary character it represents. In an ASCII or Uni-
code environment, these escapes are as follows:
\a alarm, that is, the BEL character (hex 07)
@@ -5028,8 +5023,8 @@ BACKSLASH
ate the appropriate EBCDIC code values. The \c escape is processed as
specified for Perl in the perlebcdic document. The only characters that
are allowed after \c are A-Z, a-z, or one of @, [, \, ], ^, _, or ?.
- Any other character provokes a compile-time error. The sequence \c@
- encodes character code 0; after \c the letters (in either case) encode
+ Any other character provokes a compile-time error. The sequence \c@ en-
+ codes character code 0; after \c the letters (in either case) encode
characters 1-26 (hex 01 to hex 1A); [, \, ], ^, and _ encode characters
27-31 (hex 1B to hex 1F), and \c? becomes either 255 (hex FF) or 95
(hex 5F).
@@ -5048,8 +5043,8 @@ BACKSLASH
95; otherwise it generates 255.
After \0 up to two further octal digits are read. If there are fewer
- than two digits, just those that are present are used. Thus the
- sequence \0\x\015 specifies two binary zeros followed by a CR character
+ than two digits, just those that are present are used. Thus the se-
+ quence \0\x\015 specifies two binary zeros followed by a CR character
(code value 13). Make sure you supply two digits after the initial zero
if the pattern character that follows is itself an octal digit.
@@ -5140,15 +5135,15 @@ BACKSLASH
\N is not allowed in a character class. \B, \R, and \X are not special
inside a character class. Like other unrecognized escape sequences,
- they are treated as the literal characters "B", "R", and "X" by
- default, but cause an error if the PCRE_EXTRA option is set. Outside a
+ they are treated as the literal characters "B", "R", and "X" by de-
+ fault, but cause an error if the PCRE_EXTRA option is set. Outside a
character class, these sequences have different meanings.
Unsupported escape sequences
In Perl, the sequences \l, \L, \u, and \U are recognized by its string
- handler and used to modify the case of following characters. By
- default, PCRE does not support these escape sequences. However, if the
+ handler and used to modify the case of following characters. By de-
+ fault, PCRE does not support these escape sequences. However, if the
PCRE_JAVASCRIPT_COMPAT option is set, \U matches a "U" character, and
\u can be used to define a character by code point, as described in the
previous section.
@@ -5199,13 +5194,13 @@ BACKSLASH
For compatibility with Perl, \s did not used to match the VT character
(code 11), which made it different from the the POSIX "space" class.
- However, Perl added VT at release 5.18, and PCRE followed suit at
- release 8.34. The default \s characters are now HT (9), LF (10), VT
- (11), FF (12), CR (13), and space (32), which are defined as white
- space in the "C" locale. This list may vary if locale-specific matching
- is taking place. For example, in some locales the "non-breaking space"
- character (\xA0) is recognized as white space, and in others the VT
- character is not.
+ However, Perl added VT at release 5.18, and PCRE followed suit at re-
+ lease 8.34. The default \s characters are now HT (9), LF (10), VT (11),
+ FF (12), CR (13), and space (32), which are defined as white space in
+ the "C" locale. This list may vary if locale-specific matching is tak-
+ ing place. For example, in some locales the "non-breaking space" char-
+ acter (\xA0) is recognized as white space, and in others the VT charac-
+ ter is not.
A "word" character is an underscore or any character that is a letter
or digit. By default, the definition of letters and digits is con-
@@ -5282,8 +5277,8 @@ BACKSLASH
(?>\r\n|\n|\x0b|\f|\r|\x85)
- This is an example of an "atomic group", details of which are given
- below. This particular group matches either the two-character sequence
+ This is an example of an "atomic group", details of which are given be-
+ low. This particular group matches either the two-character sequence
CR followed by LF, or one of the single characters LF (linefeed,
U+000A), VT (vertical tab, U+000B), FF (form feed, U+000C), CR (car-
riage return, U+000D), or NEL (next line, U+0085). The two-character
@@ -5298,10 +5293,10 @@ BACKSLASH
the complete set of Unicode line endings) by setting the option
PCRE_BSR_ANYCRLF either at compile time or when the pattern is matched.
(BSR is an abbrevation for "backslash R".) This can be made the default
- when PCRE is built; if this is the case, the other behaviour can be
- requested via the PCRE_BSR_UNICODE option. It is also possible to
- specify these settings by starting a pattern string with one of the
- following sequences:
+ when PCRE is built; if this is the case, the other behaviour can be re-
+ quested via the PCRE_BSR_UNICODE option. It is also possible to spec-
+ ify these settings by starting a pattern string with one of the follow-
+ ing sequences:
(*BSR_ANYCRLF) CR, LF, or CRLF only
(*BSR_UNICODE) any Unicode newline sequence
@@ -5318,8 +5313,8 @@ BACKSLASH
They can also be combined with the (*UTF8), (*UTF16), (*UTF32), (*UTF)
or (*UCP) special sequences. Inside a character class, \R is treated as
- an unrecognized escape sequence, and so matches the letter "R" by
- default, but causes an error if PCRE_EXTRA is set.
+ an unrecognized escape sequence, and so matches the letter "R" by de-
+ fault, but causes an error if PCRE_EXTRA is set.
Unicode character properties
@@ -5335,10 +5330,10 @@ BACKSLASH
The property names represented by xx above are limited to the Unicode
script names, the general category properties, "Any", which matches any
- character (including newline), and some special PCRE properties
- (described in the next section). Other Perl properties such as "InMu-
- sicalSymbols" are not currently supported by PCRE. Note that \P{Any}
- does not match any characters, so always causes a match failure.
+ character (including newline), and some special PCRE properties (de-
+ scribed in the next section). Other Perl properties such as "InMusi-
+ calSymbols" are not currently supported by PCRE. Note that \P{Any} does
+ not match any characters, so always causes a match failure.
Sets of Unicode characters are defined as belonging to certain scripts.
A character from one of these sets can be matched using a script name.
@@ -5355,16 +5350,16 @@ BACKSLASH
ian, Caucasian_Albanian, Chakma, Cham, Cherokee, Common, Coptic, Cunei-
form, Cypriot, Cyrillic, Deseret, Devanagari, Duployan, Egyptian_Hiero-
glyphs, Elbasan, Ethiopic, Georgian, Glagolitic, Gothic, Grantha,
- Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana,
- Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip-
+ Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Im-
+ perial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip-
tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li,
Kharoshthi, Khmer, Khojki, Khudawadi, Lao, Latin, Lepcha, Limbu, Lin-
ear_A, Linear_B, Lisu, Lycian, Lydian, Mahajani, Malayalam, Mandaic,
- Manichaean, Meetei_Mayek, Mende_Kikakui, Meroitic_Cursive,
- Meroitic_Hieroglyphs, Miao, Modi, Mongolian, Mro, Myanmar, Nabataean,
- New_Tai_Lue, Nko, Ogham, Ol_Chiki, Old_Italic, Old_North_Arabian,
- Old_Permic, Old_Persian, Old_South_Arabian, Old_Turkic, Oriya, Osmanya,
- Pahawh_Hmong, Palmyrene, Pau_Cin_Hau, Phags_Pa, Phoenician,
+ Manichaean, Meetei_Mayek, Mende_Kikakui, Meroitic_Cursive, Meroitic_Hi-
+ eroglyphs, Miao, Modi, Mongolian, Mro, Myanmar, Nabataean, New_Tai_Lue,
+ Nko, Ogham, Ol_Chiki, Old_Italic, Old_North_Arabian, Old_Permic,
+ Old_Persian, Old_South_Arabian, Old_Turkic, Oriya, Osmanya, Pa-
+ hawh_Hmong, Palmyrene, Pau_Cin_Hau, Phags_Pa, Phoenician,
Psalter_Pahlavi, Rejang, Runic, Samaritan, Saurashtra, Sharada, Sha-
vian, Siddham, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac,
Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu,
@@ -5477,9 +5472,9 @@ BACKSLASH
This simple definition was extended in Unicode to include more compli-
cated kinds of composite character by giving each character a grapheme
- breaking property, and creating rules that use these properties to
- define the boundaries of extended grapheme clusters. In releases of
- PCRE later than 8.31, \X matches one of these clusters.
+ breaking property, and creating rules that use these properties to de-
+ fine the boundaries of extended grapheme clusters. In releases of PCRE
+ later than 8.31, \X matches one of these clusters.
\X always matches at least one character. Then it decides whether to
add additional characters according to the following rules for ending a
@@ -5507,8 +5502,8 @@ BACKSLASH
PCRE's additional properties
As well as the standard Unicode properties described above, PCRE sup-
- ports four more that make it possible to convert traditional escape
- sequences such as \w and \s to use Unicode properties. PCRE uses these
+ ports four more that make it possible to convert traditional escape se-
+ quences such as \w and \s to use Unicode properties. PCRE uses these
non-standard, non-Perl properties internally when PCRE_UCP is set. How-
ever, they may also be used explicitly. These properties are:
@@ -5522,8 +5517,8 @@ BACKSLASH
form feed, or carriage return, and any other character that has the Z
(separator) property. Xsp is the same as Xps; it used to exclude ver-
tical tab, for Perl compatibility, but Perl changed, and so PCRE fol-
- lowed at release 8.34. Xwd matches the same characters as Xan, plus
- underscore.
+ lowed at release 8.34. Xwd matches the same characters as Xan, plus un-
+ derscore.
There is another non-standard property, Xuc, which matches any charac-
ter that can be represented by a Universal Character Name in C++ and
@@ -5553,11 +5548,11 @@ BACKSLASH
matches "foobar", the first substring is still set to "foo".
- Perl documents that the use of \K within assertions is "not well
- defined". In PCRE, \K is acted upon when it occurs inside positive
- assertions, but is ignored in negative assertions. Note that when a
- pattern such as (?=ab\K) matches, the reported start of the match can
- be greater than the end of the match.
+ Perl documents that the use of \K within assertions is "not well de-
+ fined". In PCRE, \K is acted upon when it occurs inside positive asser-
+ tions, but is ignored in negative assertions. Note that when a pattern
+ such as (?=ab\K) matches, the reported start of the match can be
+ greater than the end of the match.
Simple assertions
@@ -5578,9 +5573,9 @@ BACKSLASH
Inside a character class, \b has a different meaning; it matches the
backspace character. If any other of these assertions appears in a
character class, by default it matches the corresponding literal char-
- acter (for example, \B matches the letter B). However, if the
- PCRE_EXTRA option is set, an "invalid escape sequence" error is gener-
- ated instead.
+ acter (for example, \B matches the letter B). However, if the PCRE_EX-
+ TRA option is set, an "invalid escape sequence" error is generated in-
+ stead.
A word boundary is a position in the subject string where the current
character and the previous character do not both match \w or \W (i.e.
@@ -5644,8 +5639,8 @@ CIRCUMFLEX AND DOLLAR
constructs that can cause a pattern to be anchored.)
The dollar character is an assertion that is true only if the current
- matching point is at the end of the subject string, or immediately
- before a newline at the end of the string (by default). Note, however,
+ matching point is at the end of the subject string, or immediately be-
+ fore a newline at the end of the string (by default). Note, however,
that it does not actually match the newline. Dollar need not be the
last character of the pattern if a number of alternatives are involved,
but it should be the last item in any branch in which it appears. Dol-
@@ -5692,18 +5687,18 @@ FULL STOP (PERIOD, DOT) AND \N
any of the other line ending characters.
The behaviour of dot with regard to newlines can be changed. If the
- PCRE_DOTALL option is set, a dot matches any one character, without
- exception. If the two-character sequence CRLF is present in the subject
+ PCRE_DOTALL option is set, a dot matches any one character, without ex-
+ ception. If the two-character sequence CRLF is present in the subject
string, it takes two dots to match it.
The handling of dot is entirely independent of the handling of circum-
flex and dollar, the only relationship being that they both involve
newlines. Dot has no special meaning in a character class.
- The escape sequence \N behaves like a dot, except that it is not
- affected by the PCRE_DOTALL option. In other words, it matches any
- character except one that signifies the end of a line. Perl also uses
- \N to match characters by name; PCRE does not support this.
+ The escape sequence \N behaves like a dot, except that it is not af-
+ fected by the PCRE_DOTALL option. In other words, it matches any char-
+ acter except one that signifies the end of a line. Perl also uses \N to
+ match characters by name; PCRE does not support this.
MATCHING A SINGLE DATA UNIT
@@ -5738,11 +5733,11 @@ MATCHING A SINGLE DATA UNIT
(?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C))
A group that starts with (?| resets the capturing parentheses numbers
- in each alternative (see "Duplicate Subpattern Numbers" below). The
- assertions at the start of each branch check the next UTF-8 character
- for values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The
- character's individual bytes are then captured by the appropriate num-
- ber of groups.
+ in each alternative (see "Duplicate Subpattern Numbers" below). The as-
+ sertions at the start of each branch check the next UTF-8 character for
+ values whose encoding uses 1, 2, 3, or 4 bytes, respectively. The char-
+ acter's individual bytes are then captured by the appropriate number of
+ groups.
SQUARE BRACKETS AND CHARACTER CLASSES
@@ -5788,80 +5783,79 @@ SQUARE BRACKETS AND CHARACTER CLASSES
with UTF support.
Characters that might indicate line breaks are never treated in any
- special way when matching character classes, whatever line-ending
- sequence is in use, and whatever setting of the PCRE_DOTALL and
- PCRE_MULTILINE options is used. A class such as [^a] always matches one
- of these characters.
+ special way when matching character classes, whatever line-ending se-
+ quence is in use, and whatever setting of the PCRE_DOTALL and PCRE_MUL-
+ TILINE options is used. A class such as [^a] always matches one of
+ these characters.
The minus (hyphen) character can be used to specify a range of charac-
- ters in a character class. For example, [d-m] matches any letter
- between d and m, inclusive. If a minus character is required in a
- class, it must be escaped with a backslash or appear in a position
- where it cannot be interpreted as indicating a range, typically as the
- first or last character in the class, or immediately after a range. For
- example, [b-d-z] matches letters in the range b to d, a hyphen charac-
- ter, or z.
+ ters in a character class. For example, [d-m] matches any letter be-
+ tween d and m, inclusive. If a minus character is required in a class,
+ it must be escaped with a backslash or appear in a position where it
+ cannot be interpreted as indicating a range, typically as the first or
+ last character in the class, or immediately after a range. For example,
+ [b-d-z] matches letters in the range b to d, a hyphen character, or z.
It is not possible to have the literal character "]" as the end charac-
- ter of a range. A pattern such as [W-]46] is interpreted as a class of
- two characters ("W" and "-") followed by a literal string "46]", so it
- would match "W46]" or "-46]". However, if the "]" is escaped with a
- backslash it is interpreted as the end of range, so [W-\]46] is inter-
- preted as a class containing a range followed by two other characters.
- The octal or hexadecimal representation of "]" can also be used to end
+ ter of a range. A pattern such as [W-]46] is interpreted as a class of
+ two characters ("W" and "-") followed by a literal string "46]", so it
+ would match "W46]" or "-46]". However, if the "]" is escaped with a
+ backslash it is interpreted as the end of range, so [W-\]46] is inter-
+ preted as a class containing a range followed by two other characters.
+ The octal or hexadecimal representation of "]" can also be used to end
a range.
- An error is generated if a POSIX character class (see below) or an
- escape sequence other than one that defines a single character appears
- at a point where a range ending character is expected. For example,
+ An error is generated if a POSIX character class (see below) or an es-
+ cape sequence other than one that defines a single character appears at
+ a point where a range ending character is expected. For example,
[z-\xff] is valid, but [A-\d] and [A-[:digit:]] are not.
- Ranges operate in the collating sequence of character values. They can
- also be used for characters specified numerically, for example
- [\000-\037]. Ranges can include any characters that are valid for the
+ Ranges operate in the collating sequence of character values. They can
+ also be used for characters specified numerically, for example
+ [\000-\037]. Ranges can include any characters that are valid for the
current mode.
If a range that includes letters is used when caseless matching is set,
it matches the letters in either case. For example, [W-c] is equivalent
- to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if
- character tables for a French locale are in use, [\xc8-\xcb] matches
- accented E characters in both cases. In UTF modes, PCRE supports the
- concept of case for characters with values greater than 128 only when
+ to [][\\^_`wxyzabc], matched caselessly, and in a non-UTF mode, if
+ character tables for a French locale are in use, [\xc8-\xcb] matches
+ accented E characters in both cases. In UTF modes, PCRE supports the
+ concept of case for characters with values greater than 128 only when
it is compiled with Unicode property support.
- The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V,
+ The character escape sequences \d, \D, \h, \H, \p, \P, \s, \S, \v, \V,
\w, and \W may appear in a character class, and add the characters that
- they match to the class. For example, [\dABCDEF] matches any hexadeci-
- mal digit. In UTF modes, the PCRE_UCP option affects the meanings of
- \d, \s, \w and their upper case partners, just as it does when they
- appear outside a character class, as described in the section entitled
+ they match to the class. For example, [\dABCDEF] matches any hexadeci-
+ mal digit. In UTF modes, the PCRE_UCP option affects the meanings of
+ \d, \s, \w and their upper case partners, just as it does when they ap-
+ pear outside a character class, as described in the section entitled
"Generic character types" above. The escape sequence \b has a different
- meaning inside a character class; it matches the backspace character.
- The sequences \B, \N, \R, and \X are not special inside a character
- class. Like any other unrecognized escape sequences, they are treated
- as the literal characters "B", "N", "R", and "X" by default, but cause
+ meaning inside a character class; it matches the backspace character.
+ The sequences \B, \N, \R, and \X are not special inside a character
+ class. Like any other unrecognized escape sequences, they are treated
+ as the literal characters "B", "N", "R", and "X" by default, but cause
an error if the PCRE_EXTRA option is set.
- A circumflex can conveniently be used with the upper case character
- types to specify a more restricted set of characters than the matching
- lower case type. For example, the class [^\W_] matches any letter or
+ A circumflex can conveniently be used with the upper case character
+ types to specify a more restricted set of characters than the matching
+ lower case type. For example, the class [^\W_] matches any letter or
digit, but not underscore, whereas [\w] includes underscore. A positive
character class should be read as "something OR something OR ..." and a
negative class as "NOT something AND NOT something AND NOT ...".
- The only metacharacters that are recognized in character classes are
- backslash, hyphen (only where it can be interpreted as specifying a
- range), circumflex (only at the start), opening square bracket (only
- when it can be interpreted as introducing a POSIX class name, or for a
- special compatibility feature - see the next two sections), and the
- terminating closing square bracket. However, escaping other non-
- alphanumeric characters does no harm.
+ The only metacharacters that are recognized in character classes are
+ backslash, hyphen (only where it can be interpreted as specifying a
+ range), circumflex (only at the start), opening square bracket (only
+ when it can be interpreted as introducing a POSIX class name, or for a
+ special compatibility feature - see the next two sections), and the
+ terminating closing square bracket. However, escaping other non-al-
+ phanumeric characters does no harm.
POSIX CHARACTER CLASSES
Perl supports the POSIX notation for character classes. This uses names
- enclosed by [: and :] within the enclosing square brackets. PCRE also
+ enclosed by [: and :] within the enclosing square brackets. PCRE also
supports this notation. For example,
[01[:alpha:]%]
@@ -5884,28 +5878,28 @@ POSIX CHARACTER CLASSES
word "word" characters (same as \w)
xdigit hexadecimal digits
- The default "space" characters are HT (9), LF (10), VT (11), FF (12),
- CR (13), and space (32). If locale-specific matching is taking place,
- the list of space characters may be different; there may be fewer or
+ The default "space" characters are HT (9), LF (10), VT (11), FF (12),
+ CR (13), and space (32). If locale-specific matching is taking place,
+ the list of space characters may be different; there may be fewer or
more of them. "Space" used to be different to \s, which did not include
VT, for Perl compatibility. However, Perl changed at release 5.18, and
- PCRE followed at release 8.34. "Space" and \s now match the same set
+ PCRE followed at release 8.34. "Space" and \s now match the same set
of characters.
- The name "word" is a Perl extension, and "blank" is a GNU extension
- from Perl 5.8. Another Perl extension is negation, which is indicated
+ The name "word" is a Perl extension, and "blank" is a GNU extension
+ from Perl 5.8. Another Perl extension is negation, which is indicated
by a ^ character after the colon. For example,
[12[:^digit:]]
- matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the
+ matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the
POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but
these are not supported, and an error is given if they are encountered.
By default, characters with values greater than 128 do not match any of
- the POSIX character classes. However, if the PCRE_UCP option is passed
- to pcre_compile(), some of the classes are changed so that Unicode
- character properties are used. This is achieved by replacing certain
+ the POSIX character classes. However, if the PCRE_UCP option is passed
+ to pcre_compile(), some of the classes are changed so that Unicode
+ character properties are used. This is achieved by replacing certain
POSIX classes by other sequences, as follows:
[:alnum:] becomes \p{Xan}
@@ -5917,10 +5911,10 @@ POSIX CHARACTER CLASSES
[:upper:] becomes \p{Lu}
[:word:] becomes \p{Xwd}
- Negated versions, such as [:^alpha:] use \P instead of \p. Three other
+ Negated versions, such as [:^alpha:] use \P instead of \p. Three other
POSIX classes are handled specially in UCP mode:
- [:graph:] This matches characters that have glyphs that mark the page
+ [:graph:] This matches characters that have glyphs that mark the page
when printed. In Unicode property terms, it matches all char-
acters with the L, M, N, P, S, or Cf properties, except for:
@@ -5929,59 +5923,59 @@ POSIX CHARACTER CLASSES
U+2066 - U+2069 Various "isolate"s
- [:print:] This matches the same characters as [:graph:] plus space
- characters that are not controls, that is, characters with
+ [:print:] This matches the same characters as [:graph:] plus space
+ characters that are not controls, that is, characters with
the Zs property.
[:punct:] This matches all characters that have the Unicode P (punctua-
- tion) property, plus those characters whose code points are
+ tion) property, plus those characters whose code points are
less than 128 that have the S (Symbol) property.
- The other POSIX classes are unchanged, and match only characters with
+ The other POSIX classes are unchanged, and match only characters with
code points less than 128.
COMPATIBILITY FEATURE FOR WORD BOUNDARIES
- In the POSIX.2 compliant library that was included in 4.4BSD Unix, the
- ugly syntax [[:<:]] and [[:>:]] is used for matching "start of word"
+ In the POSIX.2 compliant library that was included in 4.4BSD Unix, the
+ ugly syntax [[:<:]] and [[:>:]] is used for matching "start of word"
and "end of word". PCRE treats these items as follows:
[[:<:]] is converted to \b(?=\w)
[[:>:]] is converted to \b(?<=\w)
Only these exact character sequences are recognized. A sequence such as
- [a[:<:]b] provokes error for an unrecognized POSIX class name. This
- support is not compatible with Perl. It is provided to help migrations
+ [a[:<:]b] provokes error for an unrecognized POSIX class name. This
+ support is not compatible with Perl. It is provided to help migrations
from other environments, and is best not used in any new patterns. Note
- that \b matches at the start and the end of a word (see "Simple asser-
- tions" above), and in a Perl-style pattern the preceding or following
- character normally shows which is wanted, without the need for the
- assertions that are used above in order to give exactly the POSIX be-
- haviour.
+ that \b matches at the start and the end of a word (see "Simple asser-
+ tions" above), and in a Perl-style pattern the preceding or following
+ character normally shows which is wanted, without the need for the as-
+ sertions that are used above in order to give exactly the POSIX behav-
+ iour.
VERTICAL BAR
- Vertical bar characters are used to separate alternative patterns. For
+ Vertical bar characters are used to separate alternative patterns. For
example, the pattern
gilbert|sullivan
- matches either "gilbert" or "sullivan". Any number of alternatives may
- appear, and an empty alternative is permitted (matching the empty
+ matches either "gilbert" or "sullivan". Any number of alternatives may
+ appear, and an empty alternative is permitted (matching the empty
string). The matching process tries each alternative in turn, from left
- to right, and the first one that succeeds is used. If the alternatives
- are within a subpattern (defined below), "succeeds" means matching the
+ to right, and the first one that succeeds is used. If the alternatives
+ are within a subpattern (defined below), "succeeds" means matching the
rest of the main pattern as well as the alternative in the subpattern.
INTERNAL OPTION SETTING
- The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and
- PCRE_EXTENDED options (which are Perl-compatible) can be changed from
- within the pattern by a sequence of Perl option letters enclosed
- between "(?" and ")". The option letters are
+ The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and
+ PCRE_EXTENDED options (which are Perl-compatible) can be changed from
+ within the pattern by a sequence of Perl option letters enclosed be-
+ tween "(?" and ")". The option letters are
i for PCRE_CASELESS
m for PCRE_MULTILINE
@@ -5990,48 +5984,48 @@ INTERNAL OPTION SETTING
For example, (?im) sets caseless, multiline matching. It is also possi-
ble to unset these options by preceding the letter with a hyphen, and a
- combined setting and unsetting such as (?im-sx), which sets PCRE_CASE-
- LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED,
- is also permitted. If a letter appears both before and after the
- hyphen, the option is unset.
+ combined setting and unsetting such as (?im-sx), which sets PCRE_CASE-
+ LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED,
+ is also permitted. If a letter appears both before and after the hy-
+ phen, the option is unset.
- The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA
- can be changed in the same way as the Perl-compatible options by using
+ The PCRE-specific options PCRE_DUPNAMES, PCRE_UNGREEDY, and PCRE_EXTRA
+ can be changed in the same way as the Perl-compatible options by using
the characters J, U and X respectively.
- When one of these option changes occurs at top level (that is, not
- inside subpattern parentheses), the change applies to the remainder of
- the pattern that follows. An option change within a subpattern (see
- below for a description of subpatterns) affects only that part of the
+ When one of these option changes occurs at top level (that is, not in-
+ side subpattern parentheses), the change applies to the remainder of
+ the pattern that follows. An option change within a subpattern (see be-
+ low for a description of subpatterns) affects only that part of the
subpattern that follows it, so
(a(?i)b)c
matches abc and aBc and no other strings (assuming PCRE_CASELESS is not
- used). By this means, options can be made to have different settings
- in different parts of the pattern. Any changes made in one alternative
- do carry on into subsequent branches within the same subpattern. For
+ used). By this means, options can be made to have different settings
+ in different parts of the pattern. Any changes made in one alternative
+ do carry on into subsequent branches within the same subpattern. For
example,
(a(?i)b|c)
- matches "ab", "aB", "c", and "C", even though when matching "C" the
- first branch is abandoned before the option setting. This is because
- the effects of option settings happen at compile time. There would be
+ matches "ab", "aB", "c", and "C", even though when matching "C" the
+ first branch is abandoned before the option setting. This is because
+ the effects of option settings happen at compile time. There would be
some very weird behaviour otherwise.
- Note: There are other PCRE-specific options that can be set by the
- application when the compiling or matching functions are called. In
- some cases the pattern can contain special leading sequences such as
- (*CRLF) to override what the application has set or what has been
- defaulted. Details are given in the section entitled "Newline
- sequences" above. There are also the (*UTF8), (*UTF16),(*UTF32), and
- (*UCP) leading sequences that can be used to set UTF and Unicode prop-
- erty modes; they are equivalent to setting the PCRE_UTF8, PCRE_UTF16,
- PCRE_UTF32 and the PCRE_UCP options, respectively. The (*UTF) sequence
- is a generic version that can be used with any of the libraries. How-
- ever, the application can set the PCRE_NEVER_UTF option, which locks
- out the use of the (*UTF) sequences.
+ Note: There are other PCRE-specific options that can be set by the ap-
+ plication when the compiling or matching functions are called. In some
+ cases the pattern can contain special leading sequences such as (*CRLF)
+ to override what the application has set or what has been defaulted.
+ Details are given in the section entitled "Newline sequences" above.
+ There are also the (*UTF8), (*UTF16),(*UTF32), and (*UCP) leading se-
+ quences that can be used to set UTF and Unicode property modes; they
+ are equivalent to setting the PCRE_UTF8, PCRE_UTF16, PCRE_UTF32 and the
+ PCRE_UCP options, respectively. The (*UTF) sequence is a generic ver-
+ sion that can be used with any of the libraries. However, the applica-
+ tion can set the PCRE_NEVER_UTF option, which locks out the use of the
+ (*UTF) sequences.
SUBPATTERNS
@@ -6043,18 +6037,18 @@ SUBPATTERNS
cat(aract|erpillar|)
- matches "cataract", "caterpillar", or "cat". Without the parentheses,
+ matches "cataract", "caterpillar", or "cat". Without the parentheses,
it would match "cataract", "erpillar" or an empty string.
- 2. It sets up the subpattern as a capturing subpattern. This means
- that, when the whole pattern matches, that portion of the subject
+ 2. It sets up the subpattern as a capturing subpattern. This means
+ that, when the whole pattern matches, that portion of the subject
string that matched the subpattern is passed back to the caller via the
- ovector argument of the matching function. (This applies only to the
- traditional matching functions; the DFA matching functions do not sup-
+ ovector argument of the matching function. (This applies only to the
+ traditional matching functions; the DFA matching functions do not sup-
port capturing.)
Opening parentheses are counted from left to right (starting from 1) to
- obtain numbers for the capturing subpatterns. For example, if the
+ obtain numbers for the capturing subpatterns. For example, if the
string "the red king" is matched against the pattern
the ((red|white) (king|queen))
@@ -6062,12 +6056,12 @@ SUBPATTERNS
the captured substrings are "red king", "red", and "king", and are num-
bered 1, 2, and 3, respectively.
- The fact that plain parentheses fulfil two functions is not always
- helpful. There are often times when a grouping subpattern is required
- without a capturing requirement. If an opening parenthesis is followed
- by a question mark and a colon, the subpattern does not do any captur-
- ing, and is not counted when computing the number of any subsequent
- capturing subpatterns. For example, if the string "the white queen" is
+ The fact that plain parentheses fulfil two functions is not always
+ helpful. There are often times when a grouping subpattern is required
+ without a capturing requirement. If an opening parenthesis is followed
+ by a question mark and a colon, the subpattern does not do any captur-
+ ing, and is not counted when computing the number of any subsequent
+ capturing subpatterns. For example, if the string "the white queen" is
matched against the pattern
the ((?:red|white) (king|queen))
@@ -6075,37 +6069,37 @@ SUBPATTERNS
the captured substrings are "white queen" and "queen", and are numbered
1 and 2. The maximum number of capturing subpatterns is 65535.
- As a convenient shorthand, if any option settings are required at the
- start of a non-capturing subpattern, the option letters may appear
- between the "?" and the ":". Thus the two patterns
+ As a convenient shorthand, if any option settings are required at the
+ start of a non-capturing subpattern, the option letters may appear be-
+ tween the "?" and the ":". Thus the two patterns
(?i:saturday|sunday)
(?:(?i)saturday|sunday)
match exactly the same set of strings. Because alternative branches are
- tried from left to right, and options are not reset until the end of
- the subpattern is reached, an option setting in one branch does affect
- subsequent branches, so the above patterns match "SUNDAY" as well as
+ tried from left to right, and options are not reset until the end of
+ the subpattern is reached, an option setting in one branch does affect
+ subsequent branches, so the above patterns match "SUNDAY" as well as
"Saturday".
DUPLICATE SUBPATTERN NUMBERS
Perl 5.10 introduced a feature whereby each alternative in a subpattern
- uses the same numbers for its capturing parentheses. Such a subpattern
- starts with (?| and is itself a non-capturing subpattern. For example,
+ uses the same numbers for its capturing parentheses. Such a subpattern
+ starts with (?| and is itself a non-capturing subpattern. For example,
consider this pattern:
(?|(Sat)ur|(Sun))day
- Because the two alternatives are inside a (?| group, both sets of cap-
- turing parentheses are numbered one. Thus, when the pattern matches,
- you can look at captured substring number one, whichever alternative
- matched. This construct is useful when you want to capture part, but
+ Because the two alternatives are inside a (?| group, both sets of cap-
+ turing parentheses are numbered one. Thus, when the pattern matches,
+ you can look at captured substring number one, whichever alternative
+ matched. This construct is useful when you want to capture part, but
not all, of one of a number of alternatives. Inside a (?| group, paren-
- theses are numbered as usual, but the number is reset at the start of
- each branch. The numbers of any capturing parentheses that follow the
- subpattern start after the highest number used in any branch. The fol-
+ theses are numbered as usual, but the number is reset at the start of
+ each branch. The numbers of any capturing parentheses that follow the
+ subpattern start after the highest number used in any branch. The fol-
lowing example is taken from the Perl documentation. The numbers under-
neath show in which buffer the captured content will be stored.
@@ -6113,58 +6107,58 @@ DUPLICATE SUBPATTERN NUMBERS
/ ( a ) (?| x ( y ) z | (p (q) r) | (t) u (v) ) ( z ) /x
# 1 2 2 3 2 3 4
- A back reference to a numbered subpattern uses the most recent value
- that is set for that number by any subpattern. The following pattern
+ A back reference to a numbered subpattern uses the most recent value
+ that is set for that number by any subpattern. The following pattern
matches "abcabc" or "defdef":
/(?|(abc)|(def))\1/
- In contrast, a subroutine call to a numbered subpattern always refers
- to the first one in the pattern with the given number. The following
+ In contrast, a subroutine call to a numbered subpattern always refers
+ to the first one in the pattern with the given number. The following
pattern matches "abcabc" or "defabc":
/(?|(abc)|(def))(?1)/
- If a condition test for a subpattern's having matched refers to a non-
- unique number, the test is true if any of the subpatterns of that num-
+ If a condition test for a subpattern's having matched refers to a non-
+ unique number, the test is true if any of the subpatterns of that num-
ber have matched.
- An alternative approach to using this "branch reset" feature is to use
+ An alternative approach to using this "branch reset" feature is to use
duplicate named subpatterns, as described in the next section.
NAMED SUBPATTERNS
- Identifying capturing parentheses by number is simple, but it can be
- very hard to keep track of the numbers in complicated regular expres-
- sions. Furthermore, if an expression is modified, the numbers may
- change. To help with this difficulty, PCRE supports the naming of sub-
+ Identifying capturing parentheses by number is simple, but it can be
+ very hard to keep track of the numbers in complicated regular expres-
+ sions. Furthermore, if an expression is modified, the numbers may
+ change. To help with this difficulty, PCRE supports the naming of sub-
patterns. This feature was not added to Perl until release 5.10. Python
- had the feature earlier, and PCRE introduced it at release 4.0, using
- the Python syntax. PCRE now supports both the Perl and the Python syn-
- tax. Perl allows identically numbered subpatterns to have different
+ had the feature earlier, and PCRE introduced it at release 4.0, using
+ the Python syntax. PCRE now supports both the Perl and the Python syn-
+ tax. Perl allows identically numbered subpatterns to have different
names, but PCRE does not.
- In PCRE, a subpattern can be named in one of three ways: (?<name>...)
- or (?'name'...) as in Perl, or (?P<name>...) as in Python. References
- to capturing parentheses from other parts of the pattern, such as back
- references, recursion, and conditions, can be made by name as well as
+ In PCRE, a subpattern can be named in one of three ways: (?<name>...)
+ or (?'name'...) as in Perl, or (?P<name>...) as in Python. References
+ to capturing parentheses from other parts of the pattern, such as back
+ references, recursion, and conditions, can be made by name as well as
by number.
- Names consist of up to 32 alphanumeric characters and underscores, but
- must start with a non-digit. Named capturing parentheses are still
- allocated numbers as well as names, exactly as if the names were not
- present. The PCRE API provides function calls for extracting the name-
- to-number translation table from a compiled pattern. There is also a
+ Names consist of up to 32 alphanumeric characters and underscores, but
+ must start with a non-digit. Named capturing parentheses are still al-
+ located numbers as well as names, exactly as if the names were not
+ present. The PCRE API provides function calls for extracting the name-
+ to-number translation table from a compiled pattern. There is also a
convenience function for extracting a captured substring by name.
- By default, a name must be unique within a pattern, but it is possible
+ By default, a name must be unique within a pattern, but it is possible
to relax this constraint by setting the PCRE_DUPNAMES option at compile
- time. (Duplicate names are also always permitted for subpatterns with
- the same number, set up as described in the previous section.) Dupli-
- cate names can be useful for patterns where only one instance of the
- named parentheses can match. Suppose you want to match the name of a
- weekday, either as a 3-letter abbreviation or as the full name, and in
+ time. (Duplicate names are also always permitted for subpatterns with
+ the same number, set up as described in the previous section.) Dupli-
+ cate names can be useful for patterns where only one instance of the
+ named parentheses can match. Suppose you want to match the name of a
+ weekday, either as a 3-letter abbreviation or as the full name, and in
both cases you want to extract the abbreviation. This pattern (ignoring
the line breaks) does the job:
@@ -6174,18 +6168,18 @@ NAMED SUBPATTERNS
(?<DN>Thu)(?:rsday)?|
(?<DN>Sat)(?:urday)?
- There are five capturing substrings, but only one is ever set after a
+ There are five capturing substrings, but only one is ever set after a
match. (An alternative way of solving this problem is to use a "branch
reset" subpattern, as described in the previous section.)
- The convenience function for extracting the data by name returns the
- substring for the first (and in this example, the only) subpattern of
- that name that matched. This saves searching to find which numbered
+ The convenience function for extracting the data by name returns the
+ substring for the first (and in this example, the only) subpattern of
+ that name that matched. This saves searching to find which numbered
subpattern it was.
- If you make a back reference to a non-unique named subpattern from
- elsewhere in the pattern, the subpatterns to which the name refers are
- checked in the order in which they appear in the overall pattern. The
+ If you make a back reference to a non-unique named subpattern from
+ elsewhere in the pattern, the subpatterns to which the name refers are
+ checked in the order in which they appear in the overall pattern. The
first one that is set is used for the reference. For example, this pat-
tern matches both "foofoo" and "barbar" but not "foobar" or "barfoo":
@@ -6193,29 +6187,29 @@ NAMED SUBPATTERNS
If you make a subroutine call to a non-unique named subpattern, the one
- that corresponds to the first occurrence of the name is used. In the
+ that corresponds to the first occurrence of the name is used. In the
absence of duplicate numbers (see the previous section) this is the one
with the lowest number.
If you use a named reference in a condition test (see the section about
conditions below), either to check whether a subpattern has matched, or
- to check for recursion, all subpatterns with the same name are tested.
- If the condition is true for any one of them, the overall condition is
- true. This is the same behaviour as testing by number. For further
- details of the interfaces for handling named subpatterns, see the
- pcreapi documentation.
+ to check for recursion, all subpatterns with the same name are tested.
+ If the condition is true for any one of them, the overall condition is
+ true. This is the same behaviour as testing by number. For further de-
+ tails of the interfaces for handling named subpatterns, see the pcreapi
+ documentation.
Warning: You cannot use different names to distinguish between two sub-
- patterns with the same number because PCRE uses only the numbers when
+ patterns with the same number because PCRE uses only the numbers when
matching. For this reason, an error is given at compile time if differ-
- ent names are given to subpatterns with the same number. However, you
+ ent names are given to subpatterns with the same number. However, you
can always give the same name to subpatterns with the same number, even
when PCRE_DUPNAMES is not set.
REPETITION
- Repetition is specified by quantifiers, which can follow any of the
+ Repetition is specified by quantifiers, which can follow any of the
following items:
a literal data character
@@ -6229,17 +6223,17 @@ REPETITION
a parenthesized subpattern (including assertions)
a subroutine call to a subpattern (recursive or otherwise)
- The general repetition quantifier specifies a minimum and maximum num-
- ber of permitted matches, by giving the two numbers in curly brackets
- (braces), separated by a comma. The numbers must be less than 65536,
+ The general repetition quantifier specifies a minimum and maximum num-
+ ber of permitted matches, by giving the two numbers in curly brackets
+ (braces), separated by a comma. The numbers must be less than 65536,
and the first must be less than or equal to the second. For example:
z{2,4}
- matches "zz", "zzz", or "zzzz". A closing brace on its own is not a
- special character. If the second number is omitted, but the comma is
- present, there is no upper limit; if the second number and the comma
- are both omitted, the quantifier specifies an exact number of required
+ matches "zz", "zzz", or "zzzz". A closing brace on its own is not a
+ special character. If the second number is omitted, but the comma is
+ present, there is no upper limit; if the second number and the comma
+ are both omitted, the quantifier specifies an exact number of required
matches. Thus
[aeiou]{3,}
@@ -6248,50 +6242,50 @@ REPETITION
\d{8}
- matches exactly 8 digits. An opening curly bracket that appears in a
- position where a quantifier is not allowed, or one that does not match
- the syntax of a quantifier, is taken as a literal character. For exam-
+ matches exactly 8 digits. An opening curly bracket that appears in a
+ position where a quantifier is not allowed, or one that does not match
+ the syntax of a quantifier, is taken as a literal character. For exam-
ple, {,6} is not a quantifier, but a literal string of four characters.
In UTF modes, quantifiers apply to characters rather than to individual
- data units. Thus, for example, \x{100}{2} matches two characters, each
+ data units. Thus, for example, \x{100}{2} matches two characters, each
of which is represented by a two-byte sequence in a UTF-8 string. Simi-
- larly, \X{3} matches three Unicode extended grapheme clusters, each of
- which may be several data units long (and they may be of different
+ larly, \X{3} matches three Unicode extended grapheme clusters, each of
+ which may be several data units long (and they may be of different
lengths).
The quantifier {0} is permitted, causing the expression to behave as if
the previous item and the quantifier were not present. This may be use-
- ful for subpatterns that are referenced as subroutines from elsewhere
+ ful for subpatterns that are referenced as subroutines from elsewhere
in the pattern (but see also the section entitled "Defining subpatterns
- for use by reference only" below). Items other than subpatterns that
+ for use by reference only" below). Items other than subpatterns that
have a {0} quantifier are omitted from the compiled pattern.
- For convenience, the three most common quantifiers have single-charac-
+ For convenience, the three most common quantifiers have single-charac-
ter abbreviations:
* is equivalent to {0,}
+ is equivalent to {1,}
? is equivalent to {0,1}
- It is possible to construct infinite loops by following a subpattern
+ It is possible to construct infinite loops by following a subpattern
that can match no characters with a quantifier that has no upper limit,
for example:
(a?)*
Earlier versions of Perl and PCRE used to give an error at compile time
- for such patterns. However, because there are cases where this can be
- useful, such patterns are now accepted, but if any repetition of the
- subpattern does in fact match no characters, the loop is forcibly bro-
+ for such patterns. However, because there are cases where this can be
+ useful, such patterns are now accepted, but if any repetition of the
+ subpattern does in fact match no characters, the loop is forcibly bro-
ken.
- By default, the quantifiers are "greedy", that is, they match as much
- as possible (up to the maximum number of permitted times), without
- causing the rest of the pattern to fail. The classic example of where
+ By default, the quantifiers are "greedy", that is, they match as much
+ as possible (up to the maximum number of permitted times), without
+ causing the rest of the pattern to fail. The classic example of where
this gives problems is in trying to match comments in C programs. These
- appear between /* and */ and within the comment, individual * and /
- characters may appear. An attempt to match C comments by applying the
+ appear between /* and */ and within the comment, individual * and /
+ characters may appear. An attempt to match C comments by applying the
pattern
/\*.*\*/
@@ -6300,19 +6294,19 @@ REPETITION
/* first comment */ not comment /* second comment */
- fails, because it matches the entire string owing to the greediness of
+ fails, because it matches the entire string owing to the greediness of
the .* item.
- However, if a quantifier is followed by a question mark, it ceases to
+ However, if a quantifier is followed by a question mark, it ceases to
be greedy, and instead matches the minimum number of times possible, so
the pattern
/\*.*?\*/
- does the right thing with the C comments. The meaning of the various
- quantifiers is not otherwise changed, just the preferred number of
- matches. Do not confuse this use of question mark with its use as a
- quantifier in its own right. Because it has two uses, it can sometimes
+ does the right thing with the C comments. The meaning of the various
+ quantifiers is not otherwise changed, just the preferred number of
+ matches. Do not confuse this use of question mark with its use as a
+ quantifier in its own right. Because it has two uses, it can sometimes
appear doubled, as in
\d??\d
@@ -6320,45 +6314,45 @@ REPETITION
which matches one digit by preference, but can match two if that is the
only way the rest of the pattern matches.
- If the PCRE_UNGREEDY option is set (an option that is not available in
- Perl), the quantifiers are not greedy by default, but individual ones
- can be made greedy by following them with a question mark. In other
+ If the PCRE_UNGREEDY option is set (an option that is not available in
+ Perl), the quantifiers are not greedy by default, but individual ones
+ can be made greedy by following them with a question mark. In other
words, it inverts the default behaviour.
- When a parenthesized subpattern is quantified with a minimum repeat
- count that is greater than 1 or with a limited maximum, more memory is
- required for the compiled pattern, in proportion to the size of the
+ When a parenthesized subpattern is quantified with a minimum repeat
+ count that is greater than 1 or with a limited maximum, more memory is
+ required for the compiled pattern, in proportion to the size of the
minimum or maximum.
If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv-
- alent to Perl's /s) is set, thus allowing the dot to match newlines,
- the pattern is implicitly anchored, because whatever follows will be
- tried against every character position in the subject string, so there
- is no point in retrying the overall match at any position after the
- first. PCRE normally treats such a pattern as though it were preceded
+ alent to Perl's /s) is set, thus allowing the dot to match newlines,
+ the pattern is implicitly anchored, because whatever follows will be
+ tried against every character position in the subject string, so there
+ is no point in retrying the overall match at any position after the
+ first. PCRE normally treats such a pattern as though it were preceded
by \A.
- In cases where it is known that the subject string contains no new-
- lines, it is worth setting PCRE_DOTALL in order to obtain this opti-
+ In cases where it is known that the subject string contains no new-
+ lines, it is worth setting PCRE_DOTALL in order to obtain this opti-
mization, or alternatively using ^ to indicate anchoring explicitly.
- However, there are some cases where the optimization cannot be used.
+ However, there are some cases where the optimization cannot be used.
When .* is inside capturing parentheses that are the subject of a back
reference elsewhere in the pattern, a match at the start may fail where
a later one succeeds. Consider, for example:
(.*)abc\1
- If the subject is "xyz123abc123" the match point is the fourth charac-
+ If the subject is "xyz123abc123" the match point is the fourth charac-
ter. For this reason, such a pattern is not implicitly anchored.
- Another case where implicit anchoring is not applied is when the lead-
- ing .* is inside an atomic group. Once again, a match at the start may
+ Another case where implicit anchoring is not applied is when the lead-
+ ing .* is inside an atomic group. Once again, a match at the start may
fail where a later one succeeds. Consider this pattern:
(?>.*?a)b
- It matches "ab" in the subject "aab". The use of the backtracking con-
+ It matches "ab" in the subject "aab". The use of the backtracking con-
trol verbs (*PRUNE) and (*SKIP) also disable this optimization.
When a capturing subpattern is repeated, the value captured is the sub-
@@ -6367,8 +6361,8 @@ REPETITION
(tweedle[dume]{3}\s*)+
has matched "tweedledum tweedledee" the value of the captured substring
- is "tweedledee". However, if there are nested capturing subpatterns,
- the corresponding captured values may have been set in previous itera-
+ is "tweedledee". However, if there are nested capturing subpatterns,
+ the corresponding captured values may have been set in previous itera-
tions. For example, after
/(a|(b))+/
@@ -6378,53 +6372,53 @@ REPETITION
ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
- With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
- repetition, failure of what follows normally causes the repeated item
- to be re-evaluated to see if a different number of repeats allows the
- rest of the pattern to match. Sometimes it is useful to prevent this,
- either to change the nature of the match, or to cause it fail earlier
- than it otherwise might, when the author of the pattern knows there is
+ With both maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
+ repetition, failure of what follows normally causes the repeated item
+ to be re-evaluated to see if a different number of repeats allows the
+ rest of the pattern to match. Sometimes it is useful to prevent this,
+ either to change the nature of the match, or to cause it fail earlier
+ than it otherwise might, when the author of the pattern knows there is
no point in carrying on.
- Consider, for example, the pattern \d+foo when applied to the subject
+ Consider, for example, the pattern \d+foo when applied to the subject
line
123456bar
After matching all 6 digits and then failing to match "foo", the normal
- action of the matcher is to try again with only 5 digits matching the
- \d+ item, and then with 4, and so on, before ultimately failing.
- "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides
- the means for specifying that once a subpattern has matched, it is not
+ action of the matcher is to try again with only 5 digits matching the
+ \d+ item, and then with 4, and so on, before ultimately failing.
+ "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides
+ the means for specifying that once a subpattern has matched, it is not
to be re-evaluated in this way.
- If we use atomic grouping for the previous example, the matcher gives
- up immediately on failing to match "foo" the first time. The notation
+ If we use atomic grouping for the previous example, the matcher gives
+ up immediately on failing to match "foo" the first time. The notation
is a kind of special parenthesis, starting with (?> as in this example:
(?>\d+)foo
- This kind of parenthesis "locks up" the part of the pattern it con-
- tains once it has matched, and a failure further into the pattern is
- prevented from backtracking into it. Backtracking past it to previous
+ This kind of parenthesis "locks up" the part of the pattern it con-
+ tains once it has matched, and a failure further into the pattern is
+ prevented from backtracking into it. Backtracking past it to previous
items, however, works as normal.
- An alternative description is that a subpattern of this type matches
- the string of characters that an identical standalone pattern would
+ An alternative description is that a subpattern of this type matches
+ the string of characters that an identical standalone pattern would
match, if anchored at the current point in the subject string.
Atomic grouping subpatterns are not capturing subpatterns. Simple cases
such as the above example can be thought of as a maximizing repeat that
- must swallow everything it can. So, while both \d+ and \d+? are pre-
- pared to adjust the number of digits they match in order to make the
+ must swallow everything it can. So, while both \d+ and \d+? are pre-
+ pared to adjust the number of digits they match in order to make the
rest of the pattern match, (?>\d+) can only match an entire sequence of
digits.
- Atomic groups in general can of course contain arbitrarily complicated
- subpatterns, and can be nested. However, when the subpattern for an
+ Atomic groups in general can of course contain arbitrarily complicated
+ subpatterns, and can be nested. However, when the subpattern for an
atomic group is just a single repeated item, as in the example above, a
- simpler notation, called a "possessive quantifier" can be used. This
- consists of an additional + character following a quantifier. Using
+ simpler notation, called a "possessive quantifier" can be used. This
+ consists of an additional + character following a quantifier. Using
this notation, the previous example can be rewritten as
\d++foo
@@ -6434,46 +6428,46 @@ ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
(abc|xyz){2,3}+
- Possessive quantifiers are always greedy; the setting of the
- PCRE_UNGREEDY option is ignored. They are a convenient notation for the
- simpler forms of atomic group. However, there is no difference in the
- meaning of a possessive quantifier and the equivalent atomic group,
- though there may be a performance difference; possessive quantifiers
+ Possessive quantifiers are always greedy; the setting of the PCRE_UN-
+ GREEDY option is ignored. They are a convenient notation for the sim-
+ pler forms of atomic group. However, there is no difference in the
+ meaning of a possessive quantifier and the equivalent atomic group,
+ though there may be a performance difference; possessive quantifiers
should be slightly faster.
- The possessive quantifier syntax is an extension to the Perl 5.8 syn-
- tax. Jeffrey Friedl originated the idea (and the name) in the first
+ The possessive quantifier syntax is an extension to the Perl 5.8 syn-
+ tax. Jeffrey Friedl originated the idea (and the name) in the first
edition of his book. Mike McCloskey liked it, so implemented it when he
- built Sun's Java package, and PCRE copied it from there. It ultimately
+ built Sun's Java package, and PCRE copied it from there. It ultimately
found its way into Perl at release 5.10.
PCRE has an optimization that automatically "possessifies" certain sim-
- ple pattern constructs. For example, the sequence A+B is treated as
- A++B because there is no point in backtracking into a sequence of A's
+ ple pattern constructs. For example, the sequence A+B is treated as
+ A++B because there is no point in backtracking into a sequence of A's
when B must follow.
- When a pattern contains an unlimited repeat inside a subpattern that
- can itself be repeated an unlimited number of times, the use of an
- atomic group is the only way to avoid some failing matches taking a
+ When a pattern contains an unlimited repeat inside a subpattern that
+ can itself be repeated an unlimited number of times, the use of an
+ atomic group is the only way to avoid some failing matches taking a
very long time indeed. The pattern
(\D+|<\d+>)*[!?]
- matches an unlimited number of substrings that either consist of non-
- digits, or digits enclosed in <>, followed by either ! or ?. When it
+ matches an unlimited number of substrings that either consist of non-
+ digits, or digits enclosed in <>, followed by either ! or ?. When it
matches, it runs quickly. However, if it is applied to
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
- it takes a long time before reporting failure. This is because the
- string can be divided between the internal \D+ repeat and the external
- * repeat in a large number of ways, and all have to be tried. (The
- example uses [!?] rather than a single character at the end, because
- both PCRE and Perl have an optimization that allows for fast failure
- when a single character is used. They remember the last single charac-
- ter that is required for a match, and fail early if it is not present
- in the string.) If the pattern is changed so that it uses an atomic
- group, like this:
+ it takes a long time before reporting failure. This is because the
+ string can be divided between the internal \D+ repeat and the external
+ * repeat in a large number of ways, and all have to be tried. (The ex-
+ ample uses [!?] rather than a single character at the end, because both
+ PCRE and Perl have an optimization that allows for fast failure when a
+ single character is used. They remember the last single character that
+ is required for a match, and fail early if it is not present in the
+ string.) If the pattern is changed so that it uses an atomic group,
+ like this:
((?>\D+)|<\d+>)*[!?]
@@ -6484,28 +6478,28 @@ BACK REFERENCES
Outside a character class, a backslash followed by a digit greater than
0 (and possibly further digits) is a back reference to a capturing sub-
- pattern earlier (that is, to its left) in the pattern, provided there
+ pattern earlier (that is, to its left) in the pattern, provided there
have been that many previous capturing left parentheses.
However, if the decimal number following the backslash is less than 10,
- it is always taken as a back reference, and causes an error only if
- there are not that many capturing left parentheses in the entire pat-
- tern. In other words, the parentheses that are referenced need not be
- to the left of the reference for numbers less than 10. A "forward back
- reference" of this type can make sense when a repetition is involved
- and the subpattern to the right has participated in an earlier itera-
+ it is always taken as a back reference, and causes an error only if
+ there are not that many capturing left parentheses in the entire pat-
+ tern. In other words, the parentheses that are referenced need not be
+ to the left of the reference for numbers less than 10. A "forward back
+ reference" of this type can make sense when a repetition is involved
+ and the subpattern to the right has participated in an earlier itera-
tion.
- It is not possible to have a numerical "forward back reference" to a
- subpattern whose number is 10 or more using this syntax because a
- sequence such as \50 is interpreted as a character defined in octal.
- See the subsection entitled "Non-printing characters" above for further
- details of the handling of digits following a backslash. There is no
- such problem when named parentheses are used. A back reference to any
- subpattern is possible using named parentheses (see below).
+ It is not possible to have a numerical "forward back reference" to a
+ subpattern whose number is 10 or more using this syntax because a se-
+ quence such as \50 is interpreted as a character defined in octal. See
+ the subsection entitled "Non-printing characters" above for further de-
+ tails of the handling of digits following a backslash. There is no such
+ problem when named parentheses are used. A back reference to any sub-
+ pattern is possible using named parentheses (see below).
- Another way of avoiding the ambiguity inherent in the use of digits
- following a backslash is to use the \g escape sequence. This escape
+ Another way of avoiding the ambiguity inherent in the use of digits
+ following a backslash is to use the \g escape sequence. This escape
must be followed by an unsigned number or a negative number, optionally
enclosed in braces. These examples are all identical:
@@ -6513,7 +6507,7 @@ BACK REFERENCES
(ring), \g1
(ring), \g{1}
- An unsigned number specifies an absolute reference without the ambigu-
+ An unsigned number specifies an absolute reference without the ambigu-
ity that is present in the older syntax. It is also useful when literal
digits follow the reference. A negative number is a relative reference.
Consider this example:
@@ -6522,126 +6516,126 @@ BACK REFERENCES
The sequence \g{-1} is a reference to the most recently started captur-
ing subpattern before \g, that is, is it equivalent to \2 in this exam-
- ple. Similarly, \g{-2} would be equivalent to \1. The use of relative
- references can be helpful in long patterns, and also in patterns that
- are created by joining together fragments that contain references
+ ple. Similarly, \g{-2} would be equivalent to \1. The use of relative
+ references can be helpful in long patterns, and also in patterns that
+ are created by joining together fragments that contain references
within themselves.
- A back reference matches whatever actually matched the capturing sub-
- pattern in the current subject string, rather than anything matching
+ A back reference matches whatever actually matched the capturing sub-
+ pattern in the current subject string, rather than anything matching
the subpattern itself (see "Subpatterns as subroutines" below for a way
of doing that). So the pattern
(sens|respons)e and \1ibility
- matches "sense and sensibility" and "response and responsibility", but
- not "sense and responsibility". If caseful matching is in force at the
- time of the back reference, the case of letters is relevant. For exam-
+ matches "sense and sensibility" and "response and responsibility", but
+ not "sense and responsibility". If caseful matching is in force at the
+ time of the back reference, the case of letters is relevant. For exam-
ple,
((?i)rah)\s+\1
- matches "rah rah" and "RAH RAH", but not "RAH rah", even though the
+ matches "rah rah" and "RAH RAH", but not "RAH rah", even though the
original capturing subpattern is matched caselessly.
- There are several different ways of writing back references to named
- subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or
- \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's
+ There are several different ways of writing back references to named
+ subpatterns. The .NET syntax \k{name} and the Perl syntax \k<name> or
+ \k'name' are supported, as is the Python syntax (?P=name). Perl 5.10's
unified back reference syntax, in which \g can be used for both numeric
- and named references, is also supported. We could rewrite the above
- example in any of the following ways:
+ and named references, is also supported. We could rewrite the above ex-
+ ample in any of the following ways:
(?<p1>(?i)rah)\s+\k<p1>
(?'p1'(?i)rah)\s+\k{p1}
(?P<p1>(?i)rah)\s+(?P=p1)
(?<p1>(?i)rah)\s+\g{p1}
- A subpattern that is referenced by name may appear in the pattern
- before or after the reference.
+ A subpattern that is referenced by name may appear in the pattern be-
+ fore or after the reference.
- There may be more than one back reference to the same subpattern. If a
- subpattern has not actually been used in a particular match, any back
+ There may be more than one back reference to the same subpattern. If a
+ subpattern has not actually been used in a particular match, any back
references to it always fail by default. For example, the pattern
(a|(bc))\2
- always fails if it starts to match "a" rather than "bc". However, if
+ always fails if it starts to match "a" rather than "bc". However, if
the PCRE_JAVASCRIPT_COMPAT option is set at compile time, a back refer-
ence to an unset value matches an empty string.
- Because there may be many capturing parentheses in a pattern, all dig-
- its following a backslash are taken as part of a potential back refer-
- ence number. If the pattern continues with a digit character, some
- delimiter must be used to terminate the back reference. If the
- PCRE_EXTENDED option is set, this can be white space. Otherwise, the
- \g{ syntax or an empty comment (see "Comments" below) can be used.
+ Because there may be many capturing parentheses in a pattern, all dig-
+ its following a backslash are taken as part of a potential back refer-
+ ence number. If the pattern continues with a digit character, some de-
+ limiter must be used to terminate the back reference. If the PCRE_EX-
+ TENDED option is set, this can be white space. Otherwise, the \g{ syn-
+ tax or an empty comment (see "Comments" below) can be used.
Recursive back references
- A back reference that occurs inside the parentheses to which it refers
- fails when the subpattern is first used, so, for example, (a\1) never
- matches. However, such references can be useful inside repeated sub-
+ A back reference that occurs inside the parentheses to which it refers
+ fails when the subpattern is first used, so, for example, (a\1) never
+ matches. However, such references can be useful inside repeated sub-
patterns. For example, the pattern
(a|b\1)+
matches any number of "a"s and also "aba", "ababbaa" etc. At each iter-
- ation of the subpattern, the back reference matches the character
- string corresponding to the previous iteration. In order for this to
- work, the pattern must be such that the first iteration does not need
- to match the back reference. This can be done using alternation, as in
+ ation of the subpattern, the back reference matches the character
+ string corresponding to the previous iteration. In order for this to
+ work, the pattern must be such that the first iteration does not need
+ to match the back reference. This can be done using alternation, as in
the example above, or by a quantifier with a minimum of zero.
- Back references of this type cause the group that they reference to be
- treated as an atomic group. Once the whole group has been matched, a
- subsequent matching failure cannot cause backtracking into the middle
+ Back references of this type cause the group that they reference to be
+ treated as an atomic group. Once the whole group has been matched, a
+ subsequent matching failure cannot cause backtracking into the middle
of the group.
ASSERTIONS
- An assertion is a test on the characters following or preceding the
- current matching point that does not actually consume any characters.
- The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are
- described above.
+ An assertion is a test on the characters following or preceding the
+ current matching point that does not actually consume any characters.
+ The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are de-
+ scribed above.
- More complicated assertions are coded as subpatterns. There are two
- kinds: those that look ahead of the current position in the subject
- string, and those that look behind it. An assertion subpattern is
- matched in the normal way, except that it does not cause the current
+ More complicated assertions are coded as subpatterns. There are two
+ kinds: those that look ahead of the current position in the subject
+ string, and those that look behind it. An assertion subpattern is
+ matched in the normal way, except that it does not cause the current
matching position to be changed.
- Assertion subpatterns are not capturing subpatterns. If such an asser-
- tion contains capturing subpatterns within it, these are counted for
- the purposes of numbering the capturing subpatterns in the whole pat-
- tern. However, substring capturing is carried out only for positive
- assertions. (Perl sometimes, but not always, does do capturing in nega-
+ Assertion subpatterns are not capturing subpatterns. If such an asser-
+ tion contains capturing subpatterns within it, these are counted for
+ the purposes of numbering the capturing subpatterns in the whole pat-
+ tern. However, substring capturing is carried out only for positive as-
+ sertions. (Perl sometimes, but not always, does do capturing in nega-
tive assertions.)
- WARNING: If a positive assertion containing one or more capturing sub-
- patterns succeeds, but failure to match later in the pattern causes
+ WARNING: If a positive assertion containing one or more capturing sub-
+ patterns succeeds, but failure to match later in the pattern causes
backtracking over this assertion, the captures within the assertion are
- reset only if no higher numbered captures are already set. This is,
- unfortunately, a fundamental limitation of the current implementation,
- and as PCRE1 is now in maintenance-only status, it is unlikely ever to
+ reset only if no higher numbered captures are already set. This is, un-
+ fortunately, a fundamental limitation of the current implementation,
+ and as PCRE1 is now in maintenance-only status, it is unlikely ever to
change.
- For compatibility with Perl, assertion subpatterns may be repeated;
- though it makes no sense to assert the same thing several times, the
- side effect of capturing parentheses may occasionally be useful. In
+ For compatibility with Perl, assertion subpatterns may be repeated;
+ though it makes no sense to assert the same thing several times, the
+ side effect of capturing parentheses may occasionally be useful. In
practice, there only three cases:
- (1) If the quantifier is {0}, the assertion is never obeyed during
- matching. However, it may contain internal capturing parenthesized
+ (1) If the quantifier is {0}, the assertion is never obeyed during
+ matching. However, it may contain internal capturing parenthesized
groups that are called from elsewhere via the subroutine mechanism.
- (2) If quantifier is {0,n} where n is greater than zero, it is treated
- as if it were {0,1}. At run time, the rest of the pattern match is
+ (2) If quantifier is {0,n} where n is greater than zero, it is treated
+ as if it were {0,1}. At run time, the rest of the pattern match is
tried with and without the assertion, the order depending on the greed-
iness of the quantifier.
- (3) If the minimum repetition is greater than zero, the quantifier is
- ignored. The assertion is obeyed just once when encountered during
+ (3) If the minimum repetition is greater than zero, the quantifier is
+ ignored. The assertion is obeyed just once when encountered during
matching.
Lookahead assertions
@@ -6651,38 +6645,38 @@ ASSERTIONS
\w+(?=;)
- matches a word followed by a semicolon, but does not include the semi-
+ matches a word followed by a semicolon, but does not include the semi-
colon in the match, and
foo(?!bar)
- matches any occurrence of "foo" that is not followed by "bar". Note
+ matches any occurrence of "foo" that is not followed by "bar". Note
that the apparently similar pattern
(?!foo)bar
- does not find an occurrence of "bar" that is preceded by something
- other than "foo"; it finds any occurrence of "bar" whatsoever, because
+ does not find an occurrence of "bar" that is preceded by something
+ other than "foo"; it finds any occurrence of "bar" whatsoever, because
the assertion (?!foo) is always true when the next three characters are
"bar". A lookbehind assertion is needed to achieve the other effect.
If you want to force a matching failure at some point in a pattern, the
- most convenient way to do it is with (?!) because an empty string
- always matches, so an assertion that requires there not to be an empty
+ most convenient way to do it is with (?!) because an empty string al-
+ ways matches, so an assertion that requires there not to be an empty
string must always fail. The backtracking control verb (*FAIL) or (*F)
is a synonym for (?!).
Lookbehind assertions
- Lookbehind assertions start with (?<= for positive assertions and (?<!
+ Lookbehind assertions start with (?<= for positive assertions and (?<!
for negative assertions. For example,
(?<!foo)bar
- does find an occurrence of "bar" that is not preceded by "foo". The
- contents of a lookbehind assertion are restricted such that all the
+ does find an occurrence of "bar" that is not preceded by "foo". The
+ contents of a lookbehind assertion are restricted such that all the
strings it matches must have a fixed length. However, if there are sev-
- eral top-level alternatives, they do not all have to have the same
+ eral top-level alternatives, they do not all have to have the same
fixed length. Thus
(?<=bullock|donkey)
@@ -6691,62 +6685,62 @@ ASSERTIONS
(?<!dogs?|cats?)
- causes an error at compile time. Branches that match different length
- strings are permitted only at the top level of a lookbehind assertion.
+ causes an error at compile time. Branches that match different length
+ strings are permitted only at the top level of a lookbehind assertion.
This is an extension compared with Perl, which requires all branches to
match the same length of string. An assertion such as
(?<=ab(c|de))
- is not permitted, because its single top-level branch can match two
+ is not permitted, because its single top-level branch can match two
different lengths, but it is acceptable to PCRE if rewritten to use two
top-level branches:
(?<=abc|abde)
- In some cases, the escape sequence \K (see above) can be used instead
+ In some cases, the escape sequence \K (see above) can be used instead
of a lookbehind assertion to get round the fixed-length restriction.
- The implementation of lookbehind assertions is, for each alternative,
- to temporarily move the current position back by the fixed length and
+ The implementation of lookbehind assertions is, for each alternative,
+ to temporarily move the current position back by the fixed length and
then try to match. If there are insufficient characters before the cur-
rent position, the assertion fails.
- In a UTF mode, PCRE does not allow the \C escape (which matches a sin-
- gle data unit even in a UTF mode) to appear in lookbehind assertions,
- because it makes it impossible to calculate the length of the lookbe-
- hind. The \X and \R escapes, which can match different numbers of data
+ In a UTF mode, PCRE does not allow the \C escape (which matches a sin-
+ gle data unit even in a UTF mode) to appear in lookbehind assertions,
+ because it makes it impossible to calculate the length of the lookbe-
+ hind. The \X and \R escapes, which can match different numbers of data
units, are also not permitted.
- "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in
- lookbehinds, as long as the subpattern matches a fixed-length string.
+ "Subroutine" calls (see below) such as (?2) or (?&X) are permitted in
+ lookbehinds, as long as the subpattern matches a fixed-length string.
Recursion, however, is not supported.
- Possessive quantifiers can be used in conjunction with lookbehind
- assertions to specify efficient matching of fixed-length strings at the
+ Possessive quantifiers can be used in conjunction with lookbehind as-
+ sertions to specify efficient matching of fixed-length strings at the
end of subject strings. Consider a simple pattern such as
abcd$
- when applied to a long string that does not match. Because matching
+ when applied to a long string that does not match. Because matching
proceeds from left to right, PCRE will look for each "a" in the subject
- and then see if what follows matches the rest of the pattern. If the
+ and then see if what follows matches the rest of the pattern. If the
pattern is specified as
^.*abcd$
- the initial .* matches the entire string at first, but when this fails
+ the initial .* matches the entire string at first, but when this fails
(because there is no following "a"), it backtracks to match all but the
- last character, then all but the last two characters, and so on. Once
- again the search for "a" covers the entire string, from right to left,
+ last character, then all but the last two characters, and so on. Once
+ again the search for "a" covers the entire string, from right to left,
so we are no better off. However, if the pattern is written as
^.*+(?<=abcd)
- there can be no backtracking for the .*+ item; it can match only the
- entire string. The subsequent lookbehind assertion does a single test
- on the last four characters. If it fails, the match fails immediately.
- For long strings, this approach makes a significant difference to the
+ there can be no backtracking for the .*+ item; it can match only the
+ entire string. The subsequent lookbehind assertion does a single test
+ on the last four characters. If it fails, the match fails immediately.
+ For long strings, this approach makes a significant difference to the
processing time.
Using multiple assertions
@@ -6755,18 +6749,18 @@ ASSERTIONS
(?<=\d{3})(?<!999)foo
- matches "foo" preceded by three digits that are not "999". Notice that
- each of the assertions is applied independently at the same point in
- the subject string. First there is a check that the previous three
- characters are all digits, and then there is a check that the same
+ matches "foo" preceded by three digits that are not "999". Notice that
+ each of the assertions is applied independently at the same point in
+ the subject string. First there is a check that the previous three
+ characters are all digits, and then there is a check that the same
three characters are not "999". This pattern does not match "foo" pre-
- ceded by six characters, the first of which are digits and the last
- three of which are not "999". For example, it doesn't match "123abc-
+ ceded by six characters, the first of which are digits and the last
+ three of which are not "999". For example, it doesn't match "123abc-
foo". A pattern to do that is
(?<=\d{3}...)(?<!999)foo
- This time the first assertion looks at the preceding six characters,
+ This time the first assertion looks at the preceding six characters,
checking that the first three are digits, and then the second assertion
checks that the preceding three characters are not "999".
@@ -6774,99 +6768,99 @@ ASSERTIONS
(?<=(?<!foo)bar)baz
- matches an occurrence of "baz" that is preceded by "bar" which in turn
+ matches an occurrence of "baz" that is preceded by "bar" which in turn
is not preceded by "foo", while
(?<=\d{3}(?!999)...)foo
- is another pattern that matches "foo" preceded by three digits and any
+ is another pattern that matches "foo" preceded by three digits and any
three characters that are not "999".
CONDITIONAL SUBPATTERNS
- It is possible to cause the matching process to obey a subpattern con-
- ditionally or to choose between two alternative subpatterns, depending
- on the result of an assertion, or whether a specific capturing subpat-
- tern has already been matched. The two possible forms of conditional
+ It is possible to cause the matching process to obey a subpattern con-
+ ditionally or to choose between two alternative subpatterns, depending
+ on the result of an assertion, or whether a specific capturing subpat-
+ tern has already been matched. The two possible forms of conditional
subpattern are:
(?(condition)yes-pattern)
(?(condition)yes-pattern|no-pattern)
- If the condition is satisfied, the yes-pattern is used; otherwise the
- no-pattern (if present) is used. If there are more than two alterna-
- tives in the subpattern, a compile-time error occurs. Each of the two
+ If the condition is satisfied, the yes-pattern is used; otherwise the
+ no-pattern (if present) is used. If there are more than two alterna-
+ tives in the subpattern, a compile-time error occurs. Each of the two
alternatives may itself contain nested subpatterns of any form, includ-
- ing conditional subpatterns; the restriction to two alternatives
- applies only at the level of the condition. This pattern fragment is an
+ ing conditional subpatterns; the restriction to two alternatives ap-
+ plies only at the level of the condition. This pattern fragment is an
example where the alternatives are complex:
(?(1) (A|B|C) | (D | (?(2)E|F) | E) )
- There are four kinds of condition: references to subpatterns, refer-
+ There are four kinds of condition: references to subpatterns, refer-
ences to recursion, a pseudo-condition called DEFINE, and assertions.
Checking for a used subpattern by number
- If the text between the parentheses consists of a sequence of digits,
+ If the text between the parentheses consists of a sequence of digits,
the condition is true if a capturing subpattern of that number has pre-
- viously matched. If there is more than one capturing subpattern with
- the same number (see the earlier section about duplicate subpattern
- numbers), the condition is true if any of them have matched. An alter-
- native notation is to precede the digits with a plus or minus sign. In
- this case, the subpattern number is relative rather than absolute. The
- most recently opened parentheses can be referenced by (?(-1), the next
- most recent by (?(-2), and so on. Inside loops it can also make sense
+ viously matched. If there is more than one capturing subpattern with
+ the same number (see the earlier section about duplicate subpattern
+ numbers), the condition is true if any of them have matched. An alter-
+ native notation is to precede the digits with a plus or minus sign. In
+ this case, the subpattern number is relative rather than absolute. The
+ most recently opened parentheses can be referenced by (?(-1), the next
+ most recent by (?(-2), and so on. Inside loops it can also make sense
to refer to subsequent groups. The next parentheses to be opened can be
- referenced as (?(+1), and so on. (The value zero in any of these forms
+ referenced as (?(+1), and so on. (The value zero in any of these forms
is not used; it provokes a compile-time error.)
- Consider the following pattern, which contains non-significant white
+ Consider the following pattern, which contains non-significant white
space to make it more readable (assume the PCRE_EXTENDED option) and to
divide it into three parts for ease of discussion:
( \( )? [^()]+ (?(1) \) )
- The first part matches an optional opening parenthesis, and if that
+ The first part matches an optional opening parenthesis, and if that
character is present, sets it as the first captured substring. The sec-
- ond part matches one or more characters that are not parentheses. The
- third part is a conditional subpattern that tests whether or not the
- first set of parentheses matched. If they did, that is, if subject
- started with an opening parenthesis, the condition is true, and so the
- yes-pattern is executed and a closing parenthesis is required. Other-
- wise, since no-pattern is not present, the subpattern matches nothing.
- In other words, this pattern matches a sequence of non-parentheses,
- optionally enclosed in parentheses.
-
- If you were embedding this pattern in a larger one, you could use a
+ ond part matches one or more characters that are not parentheses. The
+ third part is a conditional subpattern that tests whether or not the
+ first set of parentheses matched. If they did, that is, if subject
+ started with an opening parenthesis, the condition is true, and so the
+ yes-pattern is executed and a closing parenthesis is required. Other-
+ wise, since no-pattern is not present, the subpattern matches nothing.
+ In other words, this pattern matches a sequence of non-parentheses, op-
+ tionally enclosed in parentheses.
+
+ If you were embedding this pattern in a larger one, you could use a
relative reference:
...other stuff... ( \( )? [^()]+ (?(-1) \) ) ...
- This makes the fragment independent of the parentheses in the larger
+ This makes the fragment independent of the parentheses in the larger
pattern.
Checking for a used subpattern by name
- Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a
- used subpattern by name. For compatibility with earlier versions of
- PCRE, which had this facility before Perl, the syntax (?(name)...) is
+ Perl uses the syntax (?(<name>)...) or (?('name')...) to test for a
+ used subpattern by name. For compatibility with earlier versions of
+ PCRE, which had this facility before Perl, the syntax (?(name)...) is
also recognized.
Rewriting the above example to use a named subpattern gives this:
(?<OPEN> \( )? [^()]+ (?(<OPEN>) \) )
- If the name used in a condition of this kind is a duplicate, the test
- is applied to all subpatterns of the same name, and is true if any one
+ If the name used in a condition of this kind is a duplicate, the test
+ is applied to all subpatterns of the same name, and is true if any one
of them has matched.
Checking for pattern recursion
If the condition is the string (R), and there is no subpattern with the
- name R, the condition is true if a recursive call to the whole pattern
+ name R, the condition is true if a recursive call to the whole pattern
or any subpattern has been made. If digits or a name preceded by amper-
sand follow the letter R, for example:
@@ -6874,51 +6868,51 @@ CONDITIONAL SUBPATTERNS
the condition is true if the most recent recursion is into a subpattern
whose number or name is given. This condition does not check the entire
- recursion stack. If the name used in a condition of this kind is a
- duplicate, the test is applied to all subpatterns of the same name, and
+ recursion stack. If the name used in a condition of this kind is a du-
+ plicate, the test is applied to all subpatterns of the same name, and
is true if any one of them is the most recent recursion.
- At "top level", all these recursion test conditions are false. The
+ At "top level", all these recursion test conditions are false. The
syntax for recursive patterns is described below.
Defining subpatterns for use by reference only
- If the condition is the string (DEFINE), and there is no subpattern
- with the name DEFINE, the condition is always false. In this case,
- there may be only one alternative in the subpattern. It is always
- skipped if control reaches this point in the pattern; the idea of
- DEFINE is that it can be used to define subroutines that can be refer-
- enced from elsewhere. (The use of subroutines is described below.) For
- example, a pattern to match an IPv4 address such as "192.168.23.245"
+ If the condition is the string (DEFINE), and there is no subpattern
+ with the name DEFINE, the condition is always false. In this case,
+ there may be only one alternative in the subpattern. It is always
+ skipped if control reaches this point in the pattern; the idea of DE-
+ FINE is that it can be used to define subroutines that can be refer-
+ enced from elsewhere. (The use of subroutines is described below.) For
+ example, a pattern to match an IPv4 address such as "192.168.23.245"
could be written like this (ignore white space and line breaks):
(?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
\b (?&byte) (\.(?&byte)){3} \b
- The first part of the pattern is a DEFINE group inside which a another
- group named "byte" is defined. This matches an individual component of
- an IPv4 address (a number less than 256). When matching takes place,
- this part of the pattern is skipped because DEFINE acts like a false
- condition. The rest of the pattern uses references to the named group
- to match the four dot-separated components of an IPv4 address, insist-
+ The first part of the pattern is a DEFINE group inside which a another
+ group named "byte" is defined. This matches an individual component of
+ an IPv4 address (a number less than 256). When matching takes place,
+ this part of the pattern is skipped because DEFINE acts like a false
+ condition. The rest of the pattern uses references to the named group
+ to match the four dot-separated components of an IPv4 address, insist-
ing on a word boundary at each end.
Assertion conditions
- If the condition is not in any of the above formats, it must be an
- assertion. This may be a positive or negative lookahead or lookbehind
- assertion. Consider this pattern, again containing non-significant
+ If the condition is not in any of the above formats, it must be an as-
+ sertion. This may be a positive or negative lookahead or lookbehind
+ assertion. Consider this pattern, again containing non-significant
white space, and with the two alternatives on the second line:
(?(?=[^a-z]*[a-z])
\d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )
- The condition is a positive lookahead assertion that matches an
- optional sequence of non-letters followed by a letter. In other words,
- it tests for the presence of at least one letter in the subject. If a
- letter is found, the subject is matched against the first alternative;
- otherwise it is matched against the second. This pattern matches
- strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
+ The condition is a positive lookahead assertion that matches an op-
+ tional sequence of non-letters followed by a letter. In other words, it
+ tests for the presence of at least one letter in the subject. If a let-
+ ter is found, the subject is matched against the first alternative;
+ otherwise it is matched against the second. This pattern matches
+ strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
letters and dd are digits.
@@ -6927,41 +6921,41 @@ COMMENTS
There are two ways of including comments in patterns that are processed
by PCRE. In both cases, the start of the comment must not be in a char-
acter class, nor in the middle of any other sequence of related charac-
- ters such as (?: or a subpattern name or number. The characters that
+ ters such as (?: or a subpattern name or number. The characters that
make up a comment play no part in the pattern matching.
- The sequence (?# marks the start of a comment that continues up to the
- next closing parenthesis. Nested parentheses are not permitted. If the
+ The sequence (?# marks the start of a comment that continues up to the
+ next closing parenthesis. Nested parentheses are not permitted. If the
PCRE_EXTENDED option is set, an unescaped # character also introduces a
- comment, which in this case continues to immediately after the next
- newline character or character sequence in the pattern. Which charac-
+ comment, which in this case continues to immediately after the next
+ newline character or character sequence in the pattern. Which charac-
ters are interpreted as newlines is controlled by the options passed to
- a compiling function or by a special sequence at the start of the pat-
+ a compiling function or by a special sequence at the start of the pat-
tern, as described in the section entitled "Newline conventions" above.
Note that the end of this type of comment is a literal newline sequence
- in the pattern; escape sequences that happen to represent a newline do
- not count. For example, consider this pattern when PCRE_EXTENDED is
+ in the pattern; escape sequences that happen to represent a newline do
+ not count. For example, consider this pattern when PCRE_EXTENDED is
set, and the default newline convention is in force:
abc #comment \n still comment
- On encountering the # character, pcre_compile() skips along, looking
- for a newline in the pattern. The sequence \n is still literal at this
- stage, so it does not terminate the comment. Only an actual character
+ On encountering the # character, pcre_compile() skips along, looking
+ for a newline in the pattern. The sequence \n is still literal at this
+ stage, so it does not terminate the comment. Only an actual character
with the code value 0x0a (the default newline) does so.
RECURSIVE PATTERNS
- Consider the problem of matching a string in parentheses, allowing for
- unlimited nested parentheses. Without the use of recursion, the best
- that can be done is to use a pattern that matches up to some fixed
- depth of nesting. It is not possible to handle an arbitrary nesting
+ Consider the problem of matching a string in parentheses, allowing for
+ unlimited nested parentheses. Without the use of recursion, the best
+ that can be done is to use a pattern that matches up to some fixed
+ depth of nesting. It is not possible to handle an arbitrary nesting
depth.
For some time, Perl has provided a facility that allows regular expres-
- sions to recurse (amongst other things). It does this by interpolating
- Perl code in the expression at run time, and the code can refer to the
+ sions to recurse (amongst other things). It does this by interpolating
+ Perl code in the expression at run time, and the code can refer to the
expression itself. A Perl pattern using code interpolation to solve the
parentheses problem can be created like this:
@@ -6971,201 +6965,201 @@ RECURSIVE PATTERNS
refers recursively to the pattern in which it appears.
Obviously, PCRE cannot support the interpolation of Perl code. Instead,
- it supports special syntax for recursion of the entire pattern, and
- also for individual subpattern recursion. After its introduction in
- PCRE and Python, this kind of recursion was subsequently introduced
+ it supports special syntax for recursion of the entire pattern, and
+ also for individual subpattern recursion. After its introduction in
+ PCRE and Python, this kind of recursion was subsequently introduced
into Perl at release 5.10.
- A special item that consists of (? followed by a number greater than
- zero and a closing parenthesis is a recursive subroutine call of the
- subpattern of the given number, provided that it occurs inside that
- subpattern. (If not, it is a non-recursive subroutine call, which is
- described in the next section.) The special item (?R) or (?0) is a
- recursive call of the entire regular expression.
+ A special item that consists of (? followed by a number greater than
+ zero and a closing parenthesis is a recursive subroutine call of the
+ subpattern of the given number, provided that it occurs inside that
+ subpattern. (If not, it is a non-recursive subroutine call, which is
+ described in the next section.) The special item (?R) or (?0) is a re-
+ cursive call of the entire regular expression.
- This PCRE pattern solves the nested parentheses problem (assume the
+ This PCRE pattern solves the nested parentheses problem (assume the
PCRE_EXTENDED option is set so that white space is ignored):
\( ( [^()]++ | (?R) )* \)
- First it matches an opening parenthesis. Then it matches any number of
- substrings which can either be a sequence of non-parentheses, or a
- recursive match of the pattern itself (that is, a correctly parenthe-
- sized substring). Finally there is a closing parenthesis. Note the use
- of a possessive quantifier to avoid backtracking into sequences of non-
+ First it matches an opening parenthesis. Then it matches any number of
+ substrings which can either be a sequence of non-parentheses, or a re-
+ cursive match of the pattern itself (that is, a correctly parenthesized
+ substring). Finally there is a closing parenthesis. Note the use of a
+ possessive quantifier to avoid backtracking into sequences of non-
parentheses.
- If this were part of a larger pattern, you would not want to recurse
+ If this were part of a larger pattern, you would not want to recurse
the entire pattern, so instead you could use this:
( \( ( [^()]++ | (?1) )* \) )
- We have put the pattern into parentheses, and caused the recursion to
+ We have put the pattern into parentheses, and caused the recursion to
refer to them instead of the whole pattern.
- In a larger pattern, keeping track of parenthesis numbers can be
- tricky. This is made easier by the use of relative references. Instead
+ In a larger pattern, keeping track of parenthesis numbers can be
+ tricky. This is made easier by the use of relative references. Instead
of (?1) in the pattern above you can write (?-2) to refer to the second
- most recently opened parentheses preceding the recursion. In other
- words, a negative number counts capturing parentheses leftwards from
+ most recently opened parentheses preceding the recursion. In other
+ words, a negative number counts capturing parentheses leftwards from
the point at which it is encountered.
- It is also possible to refer to subsequently opened parentheses, by
- writing references such as (?+2). However, these cannot be recursive
- because the reference is not inside the parentheses that are refer-
- enced. They are always non-recursive subroutine calls, as described in
+ It is also possible to refer to subsequently opened parentheses, by
+ writing references such as (?+2). However, these cannot be recursive
+ because the reference is not inside the parentheses that are refer-
+ enced. They are always non-recursive subroutine calls, as described in
the next section.
- An alternative approach is to use named parentheses instead. The Perl
- syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also
+ An alternative approach is to use named parentheses instead. The Perl
+ syntax for this is (?&name); PCRE's earlier syntax (?P>name) is also
supported. We could rewrite the above example as follows:
(?<pn> \( ( [^()]++ | (?&pn) )* \) )
- If there is more than one subpattern with the same name, the earliest
+ If there is more than one subpattern with the same name, the earliest
one is used.
- This particular example pattern that we have been looking at contains
+ This particular example pattern that we have been looking at contains
nested unlimited repeats, and so the use of a possessive quantifier for
matching strings of non-parentheses is important when applying the pat-
- tern to strings that do not match. For example, when this pattern is
+ tern to strings that do not match. For example, when this pattern is
applied to
(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
- it yields "no match" quickly. However, if a possessive quantifier is
- not used, the match runs for a very long time indeed because there are
- so many different ways the + and * repeats can carve up the subject,
+ it yields "no match" quickly. However, if a possessive quantifier is
+ not used, the match runs for a very long time indeed because there are
+ so many different ways the + and * repeats can carve up the subject,
and all have to be tested before failure can be reported.
- At the end of a match, the values of capturing parentheses are those
- from the outermost level. If you want to obtain intermediate values, a
- callout function can be used (see below and the pcrecallout documenta-
+ At the end of a match, the values of capturing parentheses are those
+ from the outermost level. If you want to obtain intermediate values, a
+ callout function can be used (see below and the pcrecallout documenta-
tion). If the pattern above is matched against
(ab(cd)ef)
- the value for the inner capturing parentheses (numbered 2) is "ef",
- which is the last value taken on at the top level. If a capturing sub-
- pattern is not matched at the top level, its final captured value is
- unset, even if it was (temporarily) set at a deeper level during the
+ the value for the inner capturing parentheses (numbered 2) is "ef",
+ which is the last value taken on at the top level. If a capturing sub-
+ pattern is not matched at the top level, its final captured value is
+ unset, even if it was (temporarily) set at a deeper level during the
matching process.
- If there are more than 15 capturing parentheses in a pattern, PCRE has
- to obtain extra memory to store data during a recursion, which it does
+ If there are more than 15 capturing parentheses in a pattern, PCRE has
+ to obtain extra memory to store data during a recursion, which it does
by using pcre_malloc, freeing it via pcre_free afterwards. If no memory
can be obtained, the match fails with the PCRE_ERROR_NOMEMORY error.
- Do not confuse the (?R) item with the condition (R), which tests for
- recursion. Consider this pattern, which matches text in angle brack-
- ets, allowing for arbitrary nesting. Only digits are allowed in nested
- brackets (that is, when recursing), whereas any characters are permit-
+ Do not confuse the (?R) item with the condition (R), which tests for
+ recursion. Consider this pattern, which matches text in angle brack-
+ ets, allowing for arbitrary nesting. Only digits are allowed in nested
+ brackets (that is, when recursing), whereas any characters are permit-
ted at the outer level.
< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >
- In this pattern, (?(R) is the start of a conditional subpattern, with
- two different alternatives for the recursive and non-recursive cases.
+ In this pattern, (?(R) is the start of a conditional subpattern, with
+ two different alternatives for the recursive and non-recursive cases.
The (?R) item is the actual recursive call.
Differences in recursion processing between PCRE and Perl
- Recursion processing in PCRE differs from Perl in two important ways.
- In PCRE (like Python, but unlike Perl), a recursive subpattern call is
+ Recursion processing in PCRE differs from Perl in two important ways.
+ In PCRE (like Python, but unlike Perl), a recursive subpattern call is
always treated as an atomic group. That is, once it has matched some of
the subject string, it is never re-entered, even if it contains untried
- alternatives and there is a subsequent matching failure. This can be
- illustrated by the following pattern, which purports to match a palin-
- dromic string that contains an odd number of characters (for example,
+ alternatives and there is a subsequent matching failure. This can be
+ illustrated by the following pattern, which purports to match a palin-
+ dromic string that contains an odd number of characters (for example,
"a", "aba", "abcba", "abcdcba"):
^(.|(.)(?1)\2)$
The idea is that it either matches a single character, or two identical
- characters surrounding a sub-palindrome. In Perl, this pattern works;
- in PCRE it does not if the pattern is longer than three characters.
+ characters surrounding a sub-palindrome. In Perl, this pattern works;
+ in PCRE it does not if the pattern is longer than three characters.
Consider the subject string "abcba":
- At the top level, the first character is matched, but as it is not at
+ At the top level, the first character is matched, but as it is not at
the end of the string, the first alternative fails; the second alterna-
tive is taken and the recursion kicks in. The recursive call to subpat-
- tern 1 successfully matches the next character ("b"). (Note that the
+ tern 1 successfully matches the next character ("b"). (Note that the
beginning and end of line tests are not part of the recursion).
- Back at the top level, the next character ("c") is compared with what
- subpattern 2 matched, which was "a". This fails. Because the recursion
- is treated as an atomic group, there are now no backtracking points,
- and so the entire match fails. (Perl is able, at this point, to re-
- enter the recursion and try the second alternative.) However, if the
- pattern is written with the alternatives in the other order, things are
+ Back at the top level, the next character ("c") is compared with what
+ subpattern 2 matched, which was "a". This fails. Because the recursion
+ is treated as an atomic group, there are now no backtracking points,
+ and so the entire match fails. (Perl is able, at this point, to re-en-
+ ter the recursion and try the second alternative.) However, if the pat-
+ tern is written with the alternatives in the other order, things are
different:
^((.)(?1)\2|.)$
- This time, the recursing alternative is tried first, and continues to
- recurse until it runs out of characters, at which point the recursion
- fails. But this time we do have another alternative to try at the
- higher level. That is the big difference: in the previous case the
- remaining alternative is at a deeper recursion level, which PCRE cannot
+ This time, the recursing alternative is tried first, and continues to
+ recurse until it runs out of characters, at which point the recursion
+ fails. But this time we do have another alternative to try at the
+ higher level. That is the big difference: in the previous case the re-
+ maining alternative is at a deeper recursion level, which PCRE cannot
use.
- To change the pattern so that it matches all palindromic strings, not
- just those with an odd number of characters, it is tempting to change
+ To change the pattern so that it matches all palindromic strings, not
+ just those with an odd number of characters, it is tempting to change
the pattern to this:
^((.)(?1)\2|.?)$
- Again, this works in Perl, but not in PCRE, and for the same reason.
- When a deeper recursion has matched a single character, it cannot be
- entered again in order to match an empty string. The solution is to
- separate the two cases, and write out the odd and even cases as alter-
+ Again, this works in Perl, but not in PCRE, and for the same reason.
+ When a deeper recursion has matched a single character, it cannot be
+ entered again in order to match an empty string. The solution is to
+ separate the two cases, and write out the odd and even cases as alter-
natives at the higher level:
^(?:((.)(?1)\2|)|((.)(?3)\4|.))
- If you want to match typical palindromic phrases, the pattern has to
+ If you want to match typical palindromic phrases, the pattern has to
ignore all non-word characters, which can be done like this:
^\W*+(?:((.)\W*+(?1)\W*+\2|)|((.)\W*+(?3)\W*+\4|\W*+.\W*+))\W*+$
If run with the PCRE_CASELESS option, this pattern matches phrases such
as "A man, a plan, a canal: Panama!" and it works well in both PCRE and
- Perl. Note the use of the possessive quantifier *+ to avoid backtrack-
- ing into sequences of non-word characters. Without this, PCRE takes a
- great deal longer (ten times or more) to match typical phrases, and
+ Perl. Note the use of the possessive quantifier *+ to avoid backtrack-
+ ing into sequences of non-word characters. Without this, PCRE takes a
+ great deal longer (ten times or more) to match typical phrases, and
Perl takes so long that you think it has gone into a loop.
- WARNING: The palindrome-matching patterns above work only if the sub-
- ject string does not start with a palindrome that is shorter than the
- entire string. For example, although "abcba" is correctly matched, if
- the subject is "ababa", PCRE finds the palindrome "aba" at the start,
- then fails at top level because the end of the string does not follow.
- Once again, it cannot jump back into the recursion to try other alter-
+ WARNING: The palindrome-matching patterns above work only if the sub-
+ ject string does not start with a palindrome that is shorter than the
+ entire string. For example, although "abcba" is correctly matched, if
+ the subject is "ababa", PCRE finds the palindrome "aba" at the start,
+ then fails at top level because the end of the string does not follow.
+ Once again, it cannot jump back into the recursion to try other alter-
natives, so the entire match fails.
- The second way in which PCRE and Perl differ in their recursion pro-
- cessing is in the handling of captured values. In Perl, when a subpat-
- tern is called recursively or as a subpattern (see the next section),
- it has no access to any values that were captured outside the recur-
- sion, whereas in PCRE these values can be referenced. Consider this
+ The second way in which PCRE and Perl differ in their recursion pro-
+ cessing is in the handling of captured values. In Perl, when a subpat-
+ tern is called recursively or as a subpattern (see the next section),
+ it has no access to any values that were captured outside the recur-
+ sion, whereas in PCRE these values can be referenced. Consider this
pattern:
^(.)(\1|a(?2))
- In PCRE, this pattern matches "bab". The first capturing parentheses
- match "b", then in the second group, when the back reference \1 fails
- to match "b", the second alternative matches "a" and then recurses. In
- the recursion, \1 does now match "b" and so the whole match succeeds.
- In Perl, the pattern fails to match because inside the recursive call
+ In PCRE, this pattern matches "bab". The first capturing parentheses
+ match "b", then in the second group, when the back reference \1 fails
+ to match "b", the second alternative matches "a" and then recurses. In
+ the recursion, \1 does now match "b" and so the whole match succeeds.
+ In Perl, the pattern fails to match because inside the recursive call
\1 cannot access the externally set value.
SUBPATTERNS AS SUBROUTINES
- If the syntax for a recursive subpattern call (either by number or by
- name) is used outside the parentheses to which it refers, it operates
- like a subroutine in a programming language. The called subpattern may
- be defined before or after the reference. A numbered reference can be
+ If the syntax for a recursive subpattern call (either by number or by
+ name) is used outside the parentheses to which it refers, it operates
+ like a subroutine in a programming language. The called subpattern may
+ be defined before or after the reference. A numbered reference can be
absolute or relative, as in these examples:
(...(absolute)...)...(?2)...
@@ -7176,79 +7170,79 @@ SUBPATTERNS AS SUBROUTINES
(sens|respons)e and \1ibility
- matches "sense and sensibility" and "response and responsibility", but
+ matches "sense and sensibility" and "response and responsibility", but
not "sense and responsibility". If instead the pattern
(sens|respons)e and (?1)ibility
- is used, it does match "sense and responsibility" as well as the other
- two strings. Another example is given in the discussion of DEFINE
+ is used, it does match "sense and responsibility" as well as the other
+ two strings. Another example is given in the discussion of DEFINE
above.
- All subroutine calls, whether recursive or not, are always treated as
- atomic groups. That is, once a subroutine has matched some of the sub-
+ All subroutine calls, whether recursive or not, are always treated as
+ atomic groups. That is, once a subroutine has matched some of the sub-
ject string, it is never re-entered, even if it contains untried alter-
- natives and there is a subsequent matching failure. Any capturing
- parentheses that are set during the subroutine call revert to their
+ natives and there is a subsequent matching failure. Any capturing
+ parentheses that are set during the subroutine call revert to their
previous values afterwards.
- Processing options such as case-independence are fixed when a subpat-
- tern is defined, so if it is used as a subroutine, such options cannot
+ Processing options such as case-independence are fixed when a subpat-
+ tern is defined, so if it is used as a subroutine, such options cannot
be changed for different calls. For example, consider this pattern:
(abc)(?i:(?-1))
- It matches "abcabc". It does not match "abcABC" because the change of
+ It matches "abcabc". It does not match "abcABC" because the change of
processing option does not affect the called subpattern.
ONIGURUMA SUBROUTINE SYNTAX
- For compatibility with Oniguruma, the non-Perl syntax \g followed by a
+ For compatibility with Oniguruma, the non-Perl syntax \g followed by a
name or a number enclosed either in angle brackets or single quotes, is
- an alternative syntax for referencing a subpattern as a subroutine,
- possibly recursively. Here are two of the examples used above, rewrit-
+ an alternative syntax for referencing a subpattern as a subroutine,
+ possibly recursively. Here are two of the examples used above, rewrit-
ten using this syntax:
(?<pn> \( ( (?>[^()]+) | \g<pn> )* \) )
(sens|respons)e and \g'1'ibility
- PCRE supports an extension to Oniguruma: if a number is preceded by a
+ PCRE supports an extension to Oniguruma: if a number is preceded by a
plus or a minus sign it is taken as a relative reference. For example:
(abc)(?i:\g<-1>)
- Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not
- synonymous. The former is a back reference; the latter is a subroutine
+ Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not
+ synonymous. The former is a back reference; the latter is a subroutine
call.
CALLOUTS
Perl has a feature whereby using the sequence (?{...}) causes arbitrary
- Perl code to be obeyed in the middle of matching a regular expression.
+ Perl code to be obeyed in the middle of matching a regular expression.
This makes it possible, amongst other things, to extract different sub-
strings that match the same pair of parentheses when there is a repeti-
tion.
PCRE provides a similar feature, but of course it cannot obey arbitrary
Perl code. The feature is called "callout". The caller of PCRE provides
- an external function by putting its entry point in the global variable
- pcre_callout (8-bit library) or pcre[16|32]_callout (16-bit or 32-bit
- library). By default, this variable contains NULL, which disables all
+ an external function by putting its entry point in the global variable
+ pcre_callout (8-bit library) or pcre[16|32]_callout (16-bit or 32-bit
+ library). By default, this variable contains NULL, which disables all
calling out.
- Within a regular expression, (?C) indicates the points at which the
- external function is to be called. If you want to identify different
- callout points, you can put a number less than 256 after the letter C.
- The default value is zero. For example, this pattern has two callout
+ Within a regular expression, (?C) indicates the points at which the ex-
+ ternal function is to be called. If you want to identify different
+ callout points, you can put a number less than 256 after the letter C.
+ The default value is zero. For example, this pattern has two callout
points:
(?C1)abc(?C2)def
- If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call-
- outs are automatically installed before each item in the pattern. They
- are all numbered 255. If there is a conditional group in the pattern
+ If the PCRE_AUTO_CALLOUT flag is passed to a compiling function, call-
+ outs are automatically installed before each item in the pattern. They
+ are all numbered 255. If there is a conditional group in the pattern
whose condition is an assertion, an additional callout is inserted just
before the condition. An explicit callout may also be set at this posi-
tion, as in this example:
@@ -7258,120 +7252,120 @@ CALLOUTS
Note that this applies only to assertion conditions, not to other types
of condition.
- During matching, when PCRE reaches a callout point, the external func-
- tion is called. It is provided with the number of the callout, the
- position in the pattern, and, optionally, one item of data originally
- supplied by the caller of the matching function. The callout function
+ During matching, when PCRE reaches a callout point, the external func-
+ tion is called. It is provided with the number of the callout, the po-
+ sition in the pattern, and, optionally, one item of data originally
+ supplied by the caller of the matching function. The callout function
may cause matching to proceed, to backtrack, or to fail altogether.
- By default, PCRE implements a number of optimizations at compile time
- and matching time, and one side-effect is that sometimes callouts are
- skipped. If you need all possible callouts to happen, you need to set
- options that disable the relevant optimizations. More details, and a
- complete description of the interface to the callout function, are
+ By default, PCRE implements a number of optimizations at compile time
+ and matching time, and one side-effect is that sometimes callouts are
+ skipped. If you need all possible callouts to happen, you need to set
+ options that disable the relevant optimizations. More details, and a
+ complete description of the interface to the callout function, are
given in the pcrecallout documentation.
BACKTRACKING CONTROL
- Perl 5.10 introduced a number of "Special Backtracking Control Verbs",
- which are still described in the Perl documentation as "experimental
- and subject to change or removal in a future version of Perl". It goes
- on to say: "Their usage in production code should be noted to avoid
- problems during upgrades." The same remarks apply to the PCRE features
+ Perl 5.10 introduced a number of "Special Backtracking Control Verbs",
+ which are still described in the Perl documentation as "experimental
+ and subject to change or removal in a future version of Perl". It goes
+ on to say: "Their usage in production code should be noted to avoid
+ problems during upgrades." The same remarks apply to the PCRE features
described in this section.
- The new verbs make use of what was previously invalid syntax: an open-
+ The new verbs make use of what was previously invalid syntax: an open-
ing parenthesis followed by an asterisk. They are generally of the form
- (*VERB) or (*VERB:NAME). Some may take either form, possibly behaving
- differently depending on whether or not a name is present. A name is
+ (*VERB) or (*VERB:NAME). Some may take either form, possibly behaving
+ differently depending on whether or not a name is present. A name is
any sequence of characters that does not include a closing parenthesis.
The maximum length of name is 255 in the 8-bit library and 65535 in the
- 16-bit and 32-bit libraries. If the name is empty, that is, if the
- closing parenthesis immediately follows the colon, the effect is as if
- the colon were not there. Any number of these verbs may occur in a
+ 16-bit and 32-bit libraries. If the name is empty, that is, if the
+ closing parenthesis immediately follows the colon, the effect is as if
+ the colon were not there. Any number of these verbs may occur in a
pattern.
- Since these verbs are specifically related to backtracking, most of
- them can be used only when the pattern is to be matched using one of
- the traditional matching functions, because these use a backtracking
- algorithm. With the exception of (*FAIL), which behaves like a failing
- negative assertion, the backtracking control verbs cause an error if
+ Since these verbs are specifically related to backtracking, most of
+ them can be used only when the pattern is to be matched using one of
+ the traditional matching functions, because these use a backtracking
+ algorithm. With the exception of (*FAIL), which behaves like a failing
+ negative assertion, the backtracking control verbs cause an error if
encountered by a DFA matching function.
- The behaviour of these verbs in repeated groups, assertions, and in
+ The behaviour of these verbs in repeated groups, assertions, and in
subpatterns called as subroutines (whether or not recursively) is docu-
mented below.
Optimizations that affect backtracking verbs
- PCRE contains some optimizations that are used to speed up matching by
+ PCRE contains some optimizations that are used to speed up matching by
running some checks at the start of each match attempt. For example, it
- may know the minimum length of matching subject, or that a particular
+ may know the minimum length of matching subject, or that a particular
character must be present. When one of these optimizations bypasses the
- running of a match, any included backtracking verbs will not, of
+ running of a match, any included backtracking verbs will not, of
course, be processed. You can suppress the start-of-match optimizations
- by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com-
+ by setting the PCRE_NO_START_OPTIMIZE option when calling pcre_com-
pile() or pcre_exec(), or by starting the pattern with (*NO_START_OPT).
There is more discussion of this option in the section entitled "Option
bits for pcre_exec()" in the pcreapi documentation.
- Experiments with Perl suggest that it too has similar optimizations,
+ Experiments with Perl suggest that it too has similar optimizations,
sometimes leading to anomalous results.
Verbs that act immediately
- The following verbs act as soon as they are encountered. They may not
+ The following verbs act as soon as they are encountered. They may not
be followed by a name.
(*ACCEPT)
- This verb causes the match to end successfully, skipping the remainder
- of the pattern. However, when it is inside a subpattern that is called
- as a subroutine, only that subpattern is ended successfully. Matching
+ This verb causes the match to end successfully, skipping the remainder
+ of the pattern. However, when it is inside a subpattern that is called
+ as a subroutine, only that subpattern is ended successfully. Matching
then continues at the outer level. If (*ACCEPT) in triggered in a posi-
- tive assertion, the assertion succeeds; in a negative assertion, the
+ tive assertion, the assertion succeeds; in a negative assertion, the
assertion fails.
- If (*ACCEPT) is inside capturing parentheses, the data so far is cap-
+ If (*ACCEPT) is inside capturing parentheses, the data so far is cap-
tured. For example:
A((?:A|B(*ACCEPT)|C)D)
- This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap-
+ This matches "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap-
tured by the outer parentheses.
(*FAIL) or (*F)
- This verb causes a matching failure, forcing backtracking to occur. It
- is equivalent to (?!) but easier to read. The Perl documentation notes
- that it is probably useful only when combined with (?{}) or (??{}).
- Those are, of course, Perl features that are not present in PCRE. The
- nearest equivalent is the callout feature, as for example in this pat-
+ This verb causes a matching failure, forcing backtracking to occur. It
+ is equivalent to (?!) but easier to read. The Perl documentation notes
+ that it is probably useful only when combined with (?{}) or (??{}).
+ Those are, of course, Perl features that are not present in PCRE. The
+ nearest equivalent is the callout feature, as for example in this pat-
tern:
a+(?C)(*FAIL)
- A match with the string "aaaa" always fails, but the callout is taken
+ A match with the string "aaaa" always fails, but the callout is taken
before each backtrack happens (in this example, 10 times).
Recording which path was taken
- There is one verb whose main purpose is to track how a match was
- arrived at, though it also has a secondary use in conjunction with
- advancing the match starting point (see (*SKIP) below).
+ There is one verb whose main purpose is to track how a match was ar-
+ rived at, though it also has a secondary use in conjunction with ad-
+ vancing the match starting point (see (*SKIP) below).
(*MARK:NAME) or (*:NAME)
- A name is always required with this verb. There may be as many
- instances of (*MARK) as you like in a pattern, and their names do not
+ A name is always required with this verb. There may be as many in-
+ stances of (*MARK) as you like in a pattern, and their names do not
have to be unique.
- When a match succeeds, the name of the last-encountered (*MARK:NAME),
- (*PRUNE:NAME), or (*THEN:NAME) on the matching path is passed back to
- the caller as described in the section entitled "Extra data for
- pcre_exec()" in the pcreapi documentation. Here is an example of
- pcretest output, where the /K modifier requests the retrieval and out-
+ When a match succeeds, the name of the last-encountered (*MARK:NAME),
+ (*PRUNE:NAME), or (*THEN:NAME) on the matching path is passed back to
+ the caller as described in the section entitled "Extra data for
+ pcre_exec()" in the pcreapi documentation. Here is an example of
+ pcretest output, where the /K modifier requests the retrieval and out-
putting of (*MARK) data:
re> /X(*MARK:A)Y|X(*MARK:B)Z/K
@@ -7383,73 +7377,73 @@ BACKTRACKING CONTROL
MK: B
The (*MARK) name is tagged with "MK:" in this output, and in this exam-
- ple it indicates which of the two alternatives matched. This is a more
- efficient way of obtaining this information than putting each alterna-
+ ple it indicates which of the two alternatives matched. This is a more
+ efficient way of obtaining this information than putting each alterna-
tive in its own capturing parentheses.
- If a verb with a name is encountered in a positive assertion that is
- true, the name is recorded and passed back if it is the last-encoun-
+ If a verb with a name is encountered in a positive assertion that is
+ true, the name is recorded and passed back if it is the last-encoun-
tered. This does not happen for negative assertions or failing positive
assertions.
- After a partial match or a failed match, the last encountered name in
+ After a partial match or a failed match, the last encountered name in
the entire match process is returned. For example:
re> /X(*MARK:A)Y|X(*MARK:B)Z/K
data> XP
No match, mark = B
- Note that in this unanchored example the mark is retained from the
+ Note that in this unanchored example the mark is retained from the
match attempt that started at the letter "X" in the subject. Subsequent
match attempts starting at "P" and then with an empty string do not get
as far as the (*MARK) item, but nevertheless do not reset it.
- If you are interested in (*MARK) values after failed matches, you
- should probably set the PCRE_NO_START_OPTIMIZE option (see above) to
+ If you are interested in (*MARK) values after failed matches, you
+ should probably set the PCRE_NO_START_OPTIMIZE option (see above) to
ensure that the match is always attempted.
Verbs that act after backtracking
The following verbs do nothing when they are encountered. Matching con-
- tinues with what follows, but if there is no subsequent match, causing
- a backtrack to the verb, a failure is forced. That is, backtracking
- cannot pass to the left of the verb. However, when one of these verbs
+ tinues with what follows, but if there is no subsequent match, causing
+ a backtrack to the verb, a failure is forced. That is, backtracking
+ cannot pass to the left of the verb. However, when one of these verbs
appears inside an atomic group or an assertion that is true, its effect
- is confined to that group, because once the group has been matched,
- there is never any backtracking into it. In this situation, backtrack-
- ing can "jump back" to the left of the entire atomic group or asser-
- tion. (Remember also, as stated above, that this localization also
- applies in subroutine calls.)
-
- These verbs differ in exactly what kind of failure occurs when back-
- tracking reaches them. The behaviour described below is what happens
- when the verb is not in a subroutine or an assertion. Subsequent sec-
+ is confined to that group, because once the group has been matched,
+ there is never any backtracking into it. In this situation, backtrack-
+ ing can "jump back" to the left of the entire atomic group or asser-
+ tion. (Remember also, as stated above, that this localization also ap-
+ plies in subroutine calls.)
+
+ These verbs differ in exactly what kind of failure occurs when back-
+ tracking reaches them. The behaviour described below is what happens
+ when the verb is not in a subroutine or an assertion. Subsequent sec-
tions cover these special cases.
(*COMMIT)
- This verb, which may not be followed by a name, causes the whole match
+ This verb, which may not be followed by a name, causes the whole match
to fail outright if there is a later matching failure that causes back-
- tracking to reach it. Even if the pattern is unanchored, no further
- attempts to find a match by advancing the starting point take place. If
- (*COMMIT) is the only backtracking verb that is encountered, once it
+ tracking to reach it. Even if the pattern is unanchored, no further at-
+ tempts to find a match by advancing the starting point take place. If
+ (*COMMIT) is the only backtracking verb that is encountered, once it
has been passed pcre_exec() is committed to finding a match at the cur-
rent starting point, or not at all. For example:
a+(*COMMIT)b
- This matches "xxaab" but not "aacaab". It can be thought of as a kind
+ This matches "xxaab" but not "aacaab". It can be thought of as a kind
of dynamic anchor, or "I've started, so I must finish." The name of the
- most recently passed (*MARK) in the path is passed back when (*COMMIT)
+ most recently passed (*MARK) in the path is passed back when (*COMMIT)
forces a match failure.
- If there is more than one backtracking verb in a pattern, a different
- one that follows (*COMMIT) may be triggered first, so merely passing
+ If there is more than one backtracking verb in a pattern, a different
+ one that follows (*COMMIT) may be triggered first, so merely passing
(*COMMIT) during a match does not always guarantee that a match must be
at this starting point.
- Note that (*COMMIT) at the start of a pattern is not the same as an
- anchor, unless PCRE's start-of-match optimizations are turned off, as
+ Note that (*COMMIT) at the start of a pattern is not the same as an an-
+ chor, unless PCRE's start-of-match optimizations are turned off, as
shown in this output from pcretest:
re> /(*COMMIT)abc/
@@ -7460,207 +7454,207 @@ BACKTRACKING CONTROL
For this pattern, PCRE knows that any match must start with "a", so the
optimization skips along the subject to "a" before applying the pattern
- to the first set of data. The match attempt then succeeds. In the sec-
- ond set of data, the escape sequence \Y is interpreted by the pcretest
- program. It causes the PCRE_NO_START_OPTIMIZE option to be set when
+ to the first set of data. The match attempt then succeeds. In the sec-
+ ond set of data, the escape sequence \Y is interpreted by the pcretest
+ program. It causes the PCRE_NO_START_OPTIMIZE option to be set when
pcre_exec() is called. This disables the optimization that skips along
to the first character. The pattern is now applied starting at "x", and
- so the (*COMMIT) causes the match to fail without trying any other
+ so the (*COMMIT) causes the match to fail without trying any other
starting points.
(*PRUNE) or (*PRUNE:NAME)
- This verb causes the match to fail at the current starting position in
+ This verb causes the match to fail at the current starting position in
the subject if there is a later matching failure that causes backtrack-
- ing to reach it. If the pattern is unanchored, the normal "bumpalong"
- advance to the next starting character then happens. Backtracking can
- occur as usual to the left of (*PRUNE), before it is reached, or when
- matching to the right of (*PRUNE), but if there is no match to the
- right, backtracking cannot cross (*PRUNE). In simple cases, the use of
- (*PRUNE) is just an alternative to an atomic group or possessive quan-
+ ing to reach it. If the pattern is unanchored, the normal "bumpalong"
+ advance to the next starting character then happens. Backtracking can
+ occur as usual to the left of (*PRUNE), before it is reached, or when
+ matching to the right of (*PRUNE), but if there is no match to the
+ right, backtracking cannot cross (*PRUNE). In simple cases, the use of
+ (*PRUNE) is just an alternative to an atomic group or possessive quan-
tifier, but there are some uses of (*PRUNE) that cannot be expressed in
- any other way. In an anchored pattern (*PRUNE) has the same effect as
+ any other way. In an anchored pattern (*PRUNE) has the same effect as
(*COMMIT).
The behaviour of (*PRUNE:NAME) is the not the same as
- (*MARK:NAME)(*PRUNE). It is like (*MARK:NAME) in that the name is
- remembered for passing back to the caller. However, (*SKIP:NAME)
- searches only for names set with (*MARK).
+ (*MARK:NAME)(*PRUNE). It is like (*MARK:NAME) in that the name is re-
+ membered for passing back to the caller. However, (*SKIP:NAME) searches
+ only for names set with (*MARK).
(*SKIP)
- This verb, when given without a name, is like (*PRUNE), except that if
- the pattern is unanchored, the "bumpalong" advance is not to the next
+ This verb, when given without a name, is like (*PRUNE), except that if
+ the pattern is unanchored, the "bumpalong" advance is not to the next
character, but to the position in the subject where (*SKIP) was encoun-
- tered. (*SKIP) signifies that whatever text was matched leading up to
+ tered. (*SKIP) signifies that whatever text was matched leading up to
it cannot be part of a successful match. Consider:
a+(*SKIP)b
- If the subject is "aaaac...", after the first match attempt fails
- (starting at the first character in the string), the starting point
+ If the subject is "aaaac...", after the first match attempt fails
+ (starting at the first character in the string), the starting point
skips on to start the next attempt at "c". Note that a possessive quan-
- tifer does not have the same effect as this example; although it would
- suppress backtracking during the first match attempt, the second
- attempt would start at the second character instead of skipping on to
+ tifer does not have the same effect as this example; although it would
+ suppress backtracking during the first match attempt, the second at-
+ tempt would start at the second character instead of skipping on to
"c".
(*SKIP:NAME)
When (*SKIP) has an associated name, its behaviour is modified. When it
is triggered, the previous path through the pattern is searched for the
- most recent (*MARK) that has the same name. If one is found, the
+ most recent (*MARK) that has the same name. If one is found, the
"bumpalong" advance is to the subject position that corresponds to that
(*MARK) instead of to where (*SKIP) was encountered. If no (*MARK) with
a matching name is found, the (*SKIP) is ignored.
- Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It
+ Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It
ignores names that are set by (*PRUNE:NAME) or (*THEN:NAME).
(*THEN) or (*THEN:NAME)
- This verb causes a skip to the next innermost alternative when back-
- tracking reaches it. That is, it cancels any further backtracking
- within the current alternative. Its name comes from the observation
+ This verb causes a skip to the next innermost alternative when back-
+ tracking reaches it. That is, it cancels any further backtracking
+ within the current alternative. Its name comes from the observation
that it can be used for a pattern-based if-then-else block:
( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
- If the COND1 pattern matches, FOO is tried (and possibly further items
- after the end of the group if FOO succeeds); on failure, the matcher
- skips to the second alternative and tries COND2, without backtracking
- into COND1. If that succeeds and BAR fails, COND3 is tried. If subse-
- quently BAZ fails, there are no more alternatives, so there is a back-
- track to whatever came before the entire group. If (*THEN) is not
- inside an alternation, it acts like (*PRUNE).
-
- The behaviour of (*THEN:NAME) is the not the same as
- (*MARK:NAME)(*THEN). It is like (*MARK:NAME) in that the name is
- remembered for passing back to the caller. However, (*SKIP:NAME)
- searches only for names set with (*MARK).
-
- A subpattern that does not contain a | character is just a part of the
- enclosing alternative; it is not a nested alternation with only one
- alternative. The effect of (*THEN) extends beyond such a subpattern to
- the enclosing alternative. Consider this pattern, where A, B, etc. are
- complex pattern fragments that do not contain any | characters at this
+ If the COND1 pattern matches, FOO is tried (and possibly further items
+ after the end of the group if FOO succeeds); on failure, the matcher
+ skips to the second alternative and tries COND2, without backtracking
+ into COND1. If that succeeds and BAR fails, COND3 is tried. If subse-
+ quently BAZ fails, there are no more alternatives, so there is a back-
+ track to whatever came before the entire group. If (*THEN) is not in-
+ side an alternation, it acts like (*PRUNE).
+
+ The behaviour of (*THEN:NAME) is the not the same as
+ (*MARK:NAME)(*THEN). It is like (*MARK:NAME) in that the name is re-
+ membered for passing back to the caller. However, (*SKIP:NAME) searches
+ only for names set with (*MARK).
+
+ A subpattern that does not contain a | character is just a part of the
+ enclosing alternative; it is not a nested alternation with only one al-
+ ternative. The effect of (*THEN) extends beyond such a subpattern to
+ the enclosing alternative. Consider this pattern, where A, B, etc. are
+ complex pattern fragments that do not contain any | characters at this
level:
A (B(*THEN)C) | D
- If A and B are matched, but there is a failure in C, matching does not
+ If A and B are matched, but there is a failure in C, matching does not
backtrack into A; instead it moves to the next alternative, that is, D.
- However, if the subpattern containing (*THEN) is given an alternative,
+ However, if the subpattern containing (*THEN) is given an alternative,
it behaves differently:
A (B(*THEN)C | (*FAIL)) | D
- The effect of (*THEN) is now confined to the inner subpattern. After a
+ The effect of (*THEN) is now confined to the inner subpattern. After a
failure in C, matching moves to (*FAIL), which causes the whole subpat-
- tern to fail because there are no more alternatives to try. In this
+ tern to fail because there are no more alternatives to try. In this
case, matching does now backtrack into A.
- Note that a conditional subpattern is not considered as having two
- alternatives, because only one is ever used. In other words, the |
- character in a conditional subpattern has a different meaning. Ignoring
+ Note that a conditional subpattern is not considered as having two al-
+ ternatives, because only one is ever used. In other words, the | char-
+ acter in a conditional subpattern has a different meaning. Ignoring
white space, consider:
^.*? (?(?=a) a | b(*THEN)c )
- If the subject is "ba", this pattern does not match. Because .*? is
- ungreedy, it initially matches zero characters. The condition (?=a)
- then fails, the character "b" is matched, but "c" is not. At this
- point, matching does not backtrack to .*? as might perhaps be expected
- from the presence of the | character. The conditional subpattern is
- part of the single alternative that comprises the whole pattern, and so
- the match fails. (If there was a backtrack into .*?, allowing it to
- match "b", the match would succeed.)
+ If the subject is "ba", this pattern does not match. Because .*? is un-
+ greedy, it initially matches zero characters. The condition (?=a) then
+ fails, the character "b" is matched, but "c" is not. At this point,
+ matching does not backtrack to .*? as might perhaps be expected from
+ the presence of the | character. The conditional subpattern is part of
+ the single alternative that comprises the whole pattern, and so the
+ match fails. (If there was a backtrack into .*?, allowing it to match
+ "b", the match would succeed.)
- The verbs just described provide four different "strengths" of control
+ The verbs just described provide four different "strengths" of control
when subsequent matching fails. (*THEN) is the weakest, carrying on the
- match at the next alternative. (*PRUNE) comes next, failing the match
- at the current starting position, but allowing an advance to the next
- character (for an unanchored pattern). (*SKIP) is similar, except that
+ match at the next alternative. (*PRUNE) comes next, failing the match
+ at the current starting position, but allowing an advance to the next
+ character (for an unanchored pattern). (*SKIP) is similar, except that
the advance may be more than one character. (*COMMIT) is the strongest,
causing the entire match to fail.
More than one backtracking verb
- If more than one backtracking verb is present in a pattern, the one
- that is backtracked onto first acts. For example, consider this pat-
+ If more than one backtracking verb is present in a pattern, the one
+ that is backtracked onto first acts. For example, consider this pat-
tern, where A, B, etc. are complex pattern fragments:
(A(*COMMIT)B(*THEN)C|ABD)
- If A matches but B fails, the backtrack to (*COMMIT) causes the entire
+ If A matches but B fails, the backtrack to (*COMMIT) causes the entire
match to fail. However, if A and B match, but C fails, the backtrack to
- (*THEN) causes the next alternative (ABD) to be tried. This behaviour
- is consistent, but is not always the same as Perl's. It means that if
- two or more backtracking verbs appear in succession, all the the last
+ (*THEN) causes the next alternative (ABD) to be tried. This behaviour
+ is consistent, but is not always the same as Perl's. It means that if
+ two or more backtracking verbs appear in succession, all the the last
of them has no effect. Consider this example:
...(*COMMIT)(*PRUNE)...
If there is a matching failure to the right, backtracking onto (*PRUNE)
- causes it to be triggered, and its action is taken. There can never be
+ causes it to be triggered, and its action is taken. There can never be
a backtrack onto (*COMMIT).
Backtracking verbs in repeated groups
- PCRE differs from Perl in its handling of backtracking verbs in
- repeated groups. For example, consider:
+ PCRE differs from Perl in its handling of backtracking verbs in re-
+ peated groups. For example, consider:
/(a(*COMMIT)b)+ac/
- If the subject is "abac", Perl matches, but PCRE fails because the
+ If the subject is "abac", Perl matches, but PCRE fails because the
(*COMMIT) in the second repeat of the group acts.
Backtracking verbs in assertions
- (*FAIL) in an assertion has its normal effect: it forces an immediate
+ (*FAIL) in an assertion has its normal effect: it forces an immediate
backtrack.
(*ACCEPT) in a positive assertion causes the assertion to succeed with-
- out any further processing. In a negative assertion, (*ACCEPT) causes
+ out any further processing. In a negative assertion, (*ACCEPT) causes
the assertion to fail without any further processing.
- The other backtracking verbs are not treated specially if they appear
- in a positive assertion. In particular, (*THEN) skips to the next
- alternative in the innermost enclosing group that has alternations,
+ The other backtracking verbs are not treated specially if they appear
+ in a positive assertion. In particular, (*THEN) skips to the next al-
+ ternative in the innermost enclosing group that has alternations,
whether or not this is within the assertion.
- Negative assertions are, however, different, in order to ensure that
- changing a positive assertion into a negative assertion changes its
- result. Backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes a neg-
- ative assertion to be true, without considering any further alternative
+ Negative assertions are, however, different, in order to ensure that
+ changing a positive assertion into a negative assertion changes its re-
+ sult. Backtracking into (*COMMIT), (*SKIP), or (*PRUNE) causes a nega-
+ tive assertion to be true, without considering any further alternative
branches in the assertion. Backtracking into (*THEN) causes it to skip
- to the next enclosing alternative within the assertion (the normal be-
- haviour), but if the assertion does not have such an alternative,
+ to the next enclosing alternative within the assertion (the normal be-
+ haviour), but if the assertion does not have such an alternative,
(*THEN) behaves like (*PRUNE).
Backtracking verbs in subroutines
- These behaviours occur whether or not the subpattern is called recur-
+ These behaviours occur whether or not the subpattern is called recur-
sively. Perl's treatment of subroutines is different in some cases.
- (*FAIL) in a subpattern called as a subroutine has its normal effect:
+ (*FAIL) in a subpattern called as a subroutine has its normal effect:
it forces an immediate backtrack.
- (*ACCEPT) in a subpattern called as a subroutine causes the subroutine
- match to succeed without any further processing. Matching then contin-
+ (*ACCEPT) in a subpattern called as a subroutine causes the subroutine
+ match to succeed without any further processing. Matching then contin-
ues after the subroutine call.
(*COMMIT), (*SKIP), and (*PRUNE) in a subpattern called as a subroutine
cause the subroutine match to fail.
- (*THEN) skips to the next alternative in the innermost enclosing group
- within the subpattern that has alternatives. If there is no such group
+ (*THEN) skips to the next alternative in the innermost enclosing group
+ within the subpattern that has alternatives. If there is no such group
within the subpattern, (*THEN) causes the subroutine match to fail.
SEE ALSO
- pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3),
+ pcreapi(3), pcrecallout(3), pcrematching(3), pcresyntax(3), pcre(3),
pcre16(3), pcre32(3).
@@ -7814,16 +7808,16 @@ SCRIPT NAMES FOR \p AND \P
ian, Caucasian_Albanian, Chakma, Cham, Cherokee, Common, Coptic, Cunei-
form, Cypriot, Cyrillic, Deseret, Devanagari, Duployan, Egyptian_Hiero-
glyphs, Elbasan, Ethiopic, Georgian, Glagolitic, Gothic, Grantha,
- Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana,
- Imperial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip-
+ Greek, Gujarati, Gurmukhi, Han, Hangul, Hanunoo, Hebrew, Hiragana, Im-
+ perial_Aramaic, Inherited, Inscriptional_Pahlavi, Inscrip-
tional_Parthian, Javanese, Kaithi, Kannada, Katakana, Kayah_Li,
Kharoshthi, Khmer, Khojki, Khudawadi, Lao, Latin, Lepcha, Limbu, Lin-
ear_A, Linear_B, Lisu, Lycian, Lydian, Mahajani, Malayalam, Mandaic,
- Manichaean, Meetei_Mayek, Mende_Kikakui, Meroitic_Cursive,
- Meroitic_Hieroglyphs, Miao, Modi, Mongolian, Mro, Myanmar, Nabataean,
- New_Tai_Lue, Nko, Ogham, Ol_Chiki, Old_Italic, Old_North_Arabian,
- Old_Permic, Old_Persian, Old_South_Arabian, Old_Turkic, Oriya, Osmanya,
- Pahawh_Hmong, Palmyrene, Pau_Cin_Hau, Phags_Pa, Phoenician,
+ Manichaean, Meetei_Mayek, Mende_Kikakui, Meroitic_Cursive, Meroitic_Hi-
+ eroglyphs, Miao, Modi, Mongolian, Mro, Myanmar, Nabataean, New_Tai_Lue,
+ Nko, Ogham, Ol_Chiki, Old_Italic, Old_North_Arabian, Old_Permic,
+ Old_Persian, Old_South_Arabian, Old_Turkic, Oriya, Osmanya, Pa-
+ hawh_Hmong, Palmyrene, Pau_Cin_Hau, Phags_Pa, Phoenician,
Psalter_Pahlavi, Rejang, Runic, Samaritan, Saurashtra, Sharada, Sha-
vian, Siddham, Sinhala, Sora_Sompeng, Sundanese, Syloti_Nagri, Syriac,
Tagalog, Tagbanwa, Tai_Le, Tai_Tham, Tai_Viet, Takri, Tamil, Telugu,
@@ -7938,9 +7932,9 @@ OPTION SETTING
(?x) extended (ignore white space)
(?-...) unset option(s)
- The following are recognized only at the very start of a pattern or
- after one of the newline or \R options with similar syntax. More than
- one of them may appear.
+ The following are recognized only at the very start of a pattern or af-
+ ter one of the newline or \R options with similar syntax. More than one
+ of them may appear.
(*LIMIT_MATCH=d) set the match limit to d (decimal number)
(*LIMIT_RECURSION=d) set the recursion limit to d (decimal number)
@@ -7958,8 +7952,8 @@ OPTION SETTING
NEWLINE CONVENTION
- These are recognized only at the very start of the pattern or after
- option settings with a similar syntax.
+ These are recognized only at the very start of the pattern or after op-
+ tion settings with a similar syntax.
(*CR) carriage return only
(*LF) linefeed only
@@ -7970,8 +7964,8 @@ NEWLINE CONVENTION
WHAT \R MATCHES
- These are recognized only at the very start of the pattern or after
- option setting with a similar syntax.
+ These are recognized only at the very start of the pattern or after op-
+ tion setting with a similar syntax.
(*BSR_ANYCRLF) CR, LF, or CRLF
(*BSR_UNICODE) any Unicode newline sequence
@@ -8161,8 +8155,8 @@ UNICODE PROPERTY SUPPORT
UTF-16, where they are used in pairs to encode codepoints with values
greater than 0xFFFF. The code points that are encoded by UTF-16 pairs
are available independently in the UTF-8 and UTF-32 encodings. (In
- other words, the whole surrogate thing is a fudge for UTF-16 which
- unfortunately messes up UTF-8 and UTF-32.)
+ other words, the whole surrogate thing is a fudge for UTF-16 which un-
+ fortunately messes up UTF-8 and UTF-32.)
If an invalid UTF-8 string is passed to PCRE, an error return is given.
At compile time, the only additional information is the offset to the
@@ -8263,8 +8257,8 @@ UNICODE PROPERTY SUPPORT
test characters of any code value, but, by default, the characters that
PCRE recognizes as digits, spaces, or word characters remain the same
set as in non-UTF mode, all with values less than 256. This remains
- true even when PCRE is built to include Unicode property support,
- because to do otherwise would slow down PCRE in many common cases. Note
+ true even when PCRE is built to include Unicode property support, be-
+ cause to do otherwise would slow down PCRE in many common cases. Note
in particular that this applies to \b and \B, because they are defined
in terms of \w and \W. If you really want to test for a wider sense of,
say, "digit", you can use explicit Unicode property tests such as
@@ -8354,27 +8348,26 @@ AVAILABILITY OF JIT SUPPORT
If --enable-jit is set on an unsupported platform, compilation fails.
A program that is linked with PCRE 8.20 or later can tell if JIT sup-
- port is available by calling pcre_config() with the PCRE_CONFIG_JIT
- option. The result is 1 when JIT is available, and 0 otherwise. How-
- ever, a simple program does not need to check this in order to use JIT.
- The normal API is implemented in a way that falls back to the interpre-
- tive code if JIT is not available. For programs that need the best pos-
- sible performance, there is also a "fast path" API that is JIT-spe-
- cific.
-
- If your program may sometimes be linked with versions of PCRE that are
- older than 8.20, but you want to use JIT when it is available, you can
+ port is available by calling pcre_config() with the PCRE_CONFIG_JIT op-
+ tion. The result is 1 when JIT is available, and 0 otherwise. However,
+ a simple program does not need to check this in order to use JIT. The
+ normal API is implemented in a way that falls back to the interpretive
+ code if JIT is not available. For programs that need the best possible
+ performance, there is also a "fast path" API that is JIT-specific.
+
+ If your program may sometimes be linked with versions of PCRE that are
+ older than 8.20, but you want to use JIT when it is available, you can
test the values of PCRE_MAJOR and PCRE_MINOR, or the existence of a JIT
- macro such as PCRE_CONFIG_JIT, for compile-time control of your code.
- Also beware that the pcre_jit_exec() function was not available at all
- before 8.32, and may not be available at all if PCRE isn't compiled
- with --enable-jit. See the "JIT FAST PATH API" section below for
- details.
+ macro such as PCRE_CONFIG_JIT, for compile-time control of your code.
+ Also beware that the pcre_jit_exec() function was not available at all
+ before 8.32, and may not be available at all if PCRE isn't compiled
+ with --enable-jit. See the "JIT FAST PATH API" section below for de-
+ tails.
SIMPLE USE OF JIT
- You have to do two things to make use of the JIT support in the sim-
+ You have to do two things to make use of the JIT support in the sim-
plest way:
(1) Call pcre_study() with the PCRE_STUDY_JIT_COMPILE option for
@@ -8382,18 +8375,18 @@ SIMPLE USE OF JIT
pcre_exec().
(2) Use pcre_free_study() to free the pcre_extra block when it is
- no longer needed, instead of just freeing it yourself. This
- ensures that
+ no longer needed, instead of just freeing it yourself. This en-
+ sures that
any JIT data is also freed.
- For a program that may be linked with pre-8.20 versions of PCRE, you
+ For a program that may be linked with pre-8.20 versions of PCRE, you
can insert
#ifndef PCRE_STUDY_JIT_COMPILE
#define PCRE_STUDY_JIT_COMPILE 0
#endif
- so that no option is passed to pcre_study(), and then use something
+ so that no option is passed to pcre_study(), and then use something
like this to free the study data:
#ifdef PCRE_CONFIG_JIT
@@ -8402,11 +8395,11 @@ SIMPLE USE OF JIT
pcre_free(study_ptr);
#endif
- PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for
- complete matches. If you want to run partial matches using the
- PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you
- should set one or both of the following options in addition to, or
- instead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study():
+ PCRE_STUDY_JIT_COMPILE requests the JIT compiler to generate code for
+ complete matches. If you want to run partial matches using the
+ PCRE_PARTIAL_HARD or PCRE_PARTIAL_SOFT options of pcre_exec(), you
+ should set one or both of the following options in addition to, or in-
+ stead of, PCRE_STUDY_JIT_COMPILE when you call pcre_study():
PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE
PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
@@ -8420,44 +8413,44 @@ SIMPLE USE OF JIT
pcre_exec(...)
#endif
- but as described in the "JIT FAST PATH API" section below this assumes
+ but as described in the "JIT FAST PATH API" section below this assumes
version 8.32 and later are compiled with --enable-jit, which may break.
- The JIT compiler generates different optimized code for each of the
- three modes (normal, soft partial, hard partial). When pcre_exec() is
- called, the appropriate code is run if it is available. Otherwise, the
+ The JIT compiler generates different optimized code for each of the
+ three modes (normal, soft partial, hard partial). When pcre_exec() is
+ called, the appropriate code is run if it is available. Otherwise, the
pattern is matched using interpretive code.
- In some circumstances you may need to call additional functions. These
- are described in the section entitled "Controlling the JIT stack"
- below.
-
- If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are
- ignored, and no JIT data is created. Otherwise, the compiled pattern is
- passed to the JIT compiler, which turns it into machine code that exe-
- cutes much faster than the normal interpretive code. When pcre_exec()
- is passed a pcre_extra block containing a pointer to JIT code of the
- appropriate mode (normal or hard/soft partial), it obeys that code
- instead of running the interpreter. The result is identical, but the
- compiled JIT code runs much faster.
-
- There are some pcre_exec() options that are not supported for JIT exe-
- cution. There are also some pattern items that JIT cannot handle.
- Details are given below. In both cases, execution automatically falls
- back to the interpretive code. If you want to know whether JIT was
- actually used for a particular match, you should arrange for a JIT
- callback function to be set up as described in the section entitled
- "Controlling the JIT stack" below, even if you do not need to supply a
- non-default JIT stack. Such a callback function is called whenever JIT
- code is about to be obeyed. If the execution options are not right for
- JIT execution, the callback function is not obeyed.
-
- If the JIT compiler finds an unsupported item, no JIT data is gener-
- ated. You can find out if JIT execution is available after studying a
- pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A
- result of 1 means that JIT compilation was successful. A result of 0
+ In some circumstances you may need to call additional functions. These
+ are described in the section entitled "Controlling the JIT stack" be-
+ low.
+
+ If JIT support is not available, PCRE_STUDY_JIT_COMPILE etc. are ig-
+ nored, and no JIT data is created. Otherwise, the compiled pattern is
+ passed to the JIT compiler, which turns it into machine code that exe-
+ cutes much faster than the normal interpretive code. When pcre_exec()
+ is passed a pcre_extra block containing a pointer to JIT code of the
+ appropriate mode (normal or hard/soft partial), it obeys that code in-
+ stead of running the interpreter. The result is identical, but the com-
+ piled JIT code runs much faster.
+
+ There are some pcre_exec() options that are not supported for JIT exe-
+ cution. There are also some pattern items that JIT cannot handle. De-
+ tails are given below. In both cases, execution automatically falls
+ back to the interpretive code. If you want to know whether JIT was ac-
+ tually used for a particular match, you should arrange for a JIT call-
+ back function to be set up as described in the section entitled "Con-
+ trolling the JIT stack" below, even if you do not need to supply a non-
+ default JIT stack. Such a callback function is called whenever JIT code
+ is about to be obeyed. If the execution options are not right for JIT
+ execution, the callback function is not obeyed.
+
+ If the JIT compiler finds an unsupported item, no JIT data is gener-
+ ated. You can find out if JIT execution is available after studying a
+ pattern by calling pcre_fullinfo() with the PCRE_INFO_JIT option. A re-
+ sult of 1 means that JIT compilation was successful. A result of 0
means that JIT support is not available, or the pattern was not studied
- with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to
+ with PCRE_STUDY_JIT_COMPILE etc., or the JIT compiler was not able to
handle the pattern.
Once a pattern has been studied, with or without JIT, it can be used as
@@ -8466,77 +8459,77 @@ SIMPLE USE OF JIT
UNSUPPORTED OPTIONS AND PATTERN ITEMS
- The only pcre_exec() options that are supported for JIT execution are
+ The only pcre_exec() options that are supported for JIT execution are
PCRE_NO_UTF8_CHECK, PCRE_NO_UTF16_CHECK, PCRE_NO_UTF32_CHECK, PCRE_NOT-
- BOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PAR-
+ BOL, PCRE_NOTEOL, PCRE_NOTEMPTY, PCRE_NOTEMPTY_ATSTART, PCRE_PAR-
TIAL_HARD, and PCRE_PARTIAL_SOFT.
- The only unsupported pattern items are \C (match a single data unit)
- when running in a UTF mode, and a callout immediately before an asser-
+ The only unsupported pattern items are \C (match a single data unit)
+ when running in a UTF mode, and a callout immediately before an asser-
tion condition in a conditional group.
RETURN VALUES FROM JIT EXECUTION
- When a pattern is matched using JIT execution, the return values are
- the same as those given by the interpretive pcre_exec() code, with the
- addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means
- that the memory used for the JIT stack was insufficient. See "Control-
+ When a pattern is matched using JIT execution, the return values are
+ the same as those given by the interpretive pcre_exec() code, with the
+ addition of one new error code: PCRE_ERROR_JIT_STACKLIMIT. This means
+ that the memory used for the JIT stack was insufficient. See "Control-
ling the JIT stack" below for a discussion of JIT stack usage. For com-
- patibility with the interpretive pcre_exec() code, no more than two-
- thirds of the ovector argument is used for passing back captured sub-
+ patibility with the interpretive pcre_exec() code, no more than two-
+ thirds of the ovector argument is used for passing back captured sub-
strings.
- The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if
- searching a very large pattern tree goes on for too long, as it is in
- the same circumstance when JIT is not used, but the details of exactly
- what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error
+ The error code PCRE_ERROR_MATCHLIMIT is returned by the JIT code if
+ searching a very large pattern tree goes on for too long, as it is in
+ the same circumstance when JIT is not used, but the details of exactly
+ what is counted are not the same. The PCRE_ERROR_RECURSIONLIMIT error
code is never returned by JIT execution.
SAVING AND RESTORING COMPILED PATTERNS
- The code that is generated by the JIT compiler is architecture-spe-
- cific, and is also position dependent. For those reasons it cannot be
- saved (in a file or database) and restored later like the bytecode and
- other data of a compiled pattern. Saving and restoring compiled pat-
- terns is not something many people do. More detail about this facility
- is given in the pcreprecompile documentation. It should be possible to
- run pcre_study() on a saved and restored pattern, and thereby recreate
- the JIT data, but because JIT compilation uses significant resources,
- it is probably not worth doing this; you might as well recompile the
+ The code that is generated by the JIT compiler is architecture-spe-
+ cific, and is also position dependent. For those reasons it cannot be
+ saved (in a file or database) and restored later like the bytecode and
+ other data of a compiled pattern. Saving and restoring compiled pat-
+ terns is not something many people do. More detail about this facility
+ is given in the pcreprecompile documentation. It should be possible to
+ run pcre_study() on a saved and restored pattern, and thereby recreate
+ the JIT data, but because JIT compilation uses significant resources,
+ it is probably not worth doing this; you might as well recompile the
original pattern.
CONTROLLING THE JIT STACK
When the compiled JIT code runs, it needs a block of memory to use as a
- stack. By default, it uses 32K on the machine stack. However, some
- large or complicated patterns need more than this. The error
- PCRE_ERROR_JIT_STACKLIMIT is given when there is not enough stack.
- Three functions are provided for managing blocks of memory for use as
- JIT stacks. There is further discussion about the use of JIT stacks in
- the section entitled "JIT stack FAQ" below.
-
- The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments
- are a starting size and a maximum size, and it returns a pointer to an
- opaque structure of type pcre_jit_stack, or NULL if there is an error.
- The pcre_jit_stack_free() function can be used to free a stack that is
- no longer needed. (For the technically minded: the address space is
- allocated by mmap or VirtualAlloc.)
-
- JIT uses far less memory for recursion than the interpretive code, and
- a maximum stack size of 512K to 1M should be more than enough for any
+ stack. By default, it uses 32K on the machine stack. However, some
+ large or complicated patterns need more than this. The error PCRE_ER-
+ ROR_JIT_STACKLIMIT is given when there is not enough stack. Three func-
+ tions are provided for managing blocks of memory for use as JIT stacks.
+ There is further discussion about the use of JIT stacks in the section
+ entitled "JIT stack FAQ" below.
+
+ The pcre_jit_stack_alloc() function creates a JIT stack. Its arguments
+ are a starting size and a maximum size, and it returns a pointer to an
+ opaque structure of type pcre_jit_stack, or NULL if there is an error.
+ The pcre_jit_stack_free() function can be used to free a stack that is
+ no longer needed. (For the technically minded: the address space is al-
+ located by mmap or VirtualAlloc.)
+
+ JIT uses far less memory for recursion than the interpretive code, and
+ a maximum stack size of 512K to 1M should be more than enough for any
pattern.
- The pcre_assign_jit_stack() function specifies which stack JIT code
+ The pcre_assign_jit_stack() function specifies which stack JIT code
should use. Its arguments are as follows:
pcre_extra *extra
pcre_jit_callback callback
void *data
- The extra argument must be the result of studying a pattern with
+ The extra argument must be the result of studying a pattern with
PCRE_STUDY_JIT_COMPILE etc. There are three cases for the values of the
other two options:
@@ -8553,29 +8546,29 @@ CONTROLLING THE JIT STACK
return value must be a valid JIT stack, the result of calling
pcre_jit_stack_alloc().
- A callback function is obeyed whenever JIT code is about to be run; it
- is not obeyed when pcre_exec() is called with options that are incom-
+ A callback function is obeyed whenever JIT code is about to be run; it
+ is not obeyed when pcre_exec() is called with options that are incom-
patible for JIT execution. A callback function can therefore be used to
- determine whether a match operation was executed by JIT or by the
- interpreter.
+ determine whether a match operation was executed by JIT or by the in-
+ terpreter.
You may safely use the same JIT stack for more than one pattern (either
- by assigning directly or by callback), as long as the patterns are all
- matched sequentially in the same thread. In a multithread application,
- if you do not specify a JIT stack, or if you assign or pass back NULL
- from a callback, that is thread-safe, because each thread has its own
- machine stack. However, if you assign or pass back a non-NULL JIT
- stack, this must be a different stack for each thread so that the
- application is thread-safe.
-
- Strictly speaking, even more is allowed. You can assign the same non-
- NULL stack to any number of patterns as long as they are not used for
- matching by multiple threads at the same time. For example, you can
- assign the same stack to all compiled patterns, and use a global mutex
- in the callback to wait until the stack is available for use. However,
+ by assigning directly or by callback), as long as the patterns are all
+ matched sequentially in the same thread. In a multithread application,
+ if you do not specify a JIT stack, or if you assign or pass back NULL
+ from a callback, that is thread-safe, because each thread has its own
+ machine stack. However, if you assign or pass back a non-NULL JIT
+ stack, this must be a different stack for each thread so that the ap-
+ plication is thread-safe.
+
+ Strictly speaking, even more is allowed. You can assign the same non-
+ NULL stack to any number of patterns as long as they are not used for
+ matching by multiple threads at the same time. For example, you can as-
+ sign the same stack to all compiled patterns, and use a global mutex in
+ the callback to wait until the stack is available for use. However,
this is an inefficient solution, and not recommended.
- This is a suggestion for how a multithreaded program that needs to set
+ This is a suggestion for how a multithreaded program that needs to set
up non-default JIT stacks might operate:
During thread initalization
@@ -8587,83 +8580,83 @@ CONTROLLING THE JIT STACK
Use a one-line callback function
return thread_local_var
- All the functions described in this section do nothing if JIT is not
- available, and pcre_assign_jit_stack() does nothing unless the extra
- argument is non-NULL and points to a pcre_extra block that is the
- result of a successful study with PCRE_STUDY_JIT_COMPILE etc.
+ All the functions described in this section do nothing if JIT is not
+ available, and pcre_assign_jit_stack() does nothing unless the extra
+ argument is non-NULL and points to a pcre_extra block that is the re-
+ sult of a successful study with PCRE_STUDY_JIT_COMPILE etc.
JIT STACK FAQ
(1) Why do we need JIT stacks?
- PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack
- where the local data of the current node is pushed before checking its
+ PCRE (and JIT) is a recursive, depth-first engine, so it needs a stack
+ where the local data of the current node is pushed before checking its
child nodes. Allocating real machine stack on some platforms is diffi-
cult. For example, the stack chain needs to be updated every time if we
- extend the stack on PowerPC. Although it is possible, its updating
+ extend the stack on PowerPC. Although it is possible, its updating
time overhead decreases performance. So we do the recursion in memory.
(2) Why don't we simply allocate blocks of memory with malloc()?
- Modern operating systems have a nice feature: they can reserve an
- address space instead of allocating memory. We can safely allocate mem-
- ory pages inside this address space, so the stack could grow without
- moving memory data (this is important because of pointers). Thus we can
- allocate 1M address space, and use only a single memory page (usually
- 4K) if that is enough. However, we can still grow up to 1M anytime if
+ Modern operating systems have a nice feature: they can reserve an ad-
+ dress space instead of allocating memory. We can safely allocate memory
+ pages inside this address space, so the stack could grow without moving
+ memory data (this is important because of pointers). Thus we can allo-
+ cate 1M address space, and use only a single memory page (usually 4K)
+ if that is enough. However, we can still grow up to 1M anytime if
needed.
(3) Who "owns" a JIT stack?
The owner of the stack is the user program, not the JIT studied pattern
- or anything else. The user program must ensure that if a stack is used
- by pcre_exec(), (that is, it is assigned to the pattern currently run-
+ or anything else. The user program must ensure that if a stack is used
+ by pcre_exec(), (that is, it is assigned to the pattern currently run-
ning), that stack must not be used by any other threads (to avoid over-
writing the same memory area). The best practice for multithreaded pro-
- grams is to allocate a stack for each thread, and return this stack
+ grams is to allocate a stack for each thread, and return this stack
through the JIT callback function.
(4) When should a JIT stack be freed?
You can free a JIT stack at any time, as long as it will not be used by
- pcre_exec() again. When you assign the stack to a pattern, only a
- pointer is set. There is no reference counting or any other magic. You
- can free the patterns and stacks in any order, anytime. Just do not
- call pcre_exec() with a pattern pointing to an already freed stack, as
- that will cause SEGFAULT. (Also, do not free a stack currently used by
- pcre_exec() in another thread). You can also replace the stack for a
- pattern at any time. You can even free the previous stack before
- assigning a replacement.
-
- (5) Should I allocate/free a stack every time before/after calling
+ pcre_exec() again. When you assign the stack to a pattern, only a
+ pointer is set. There is no reference counting or any other magic. You
+ can free the patterns and stacks in any order, anytime. Just do not
+ call pcre_exec() with a pattern pointing to an already freed stack, as
+ that will cause SEGFAULT. (Also, do not free a stack currently used by
+ pcre_exec() in another thread). You can also replace the stack for a
+ pattern at any time. You can even free the previous stack before as-
+ signing a replacement.
+
+ (5) Should I allocate/free a stack every time before/after calling
pcre_exec()?
- No, because this is too costly in terms of resources. However, you
- could implement some clever idea which release the stack if it is not
- used in let's say two minutes. The JIT callback can help to achieve
+ No, because this is too costly in terms of resources. However, you
+ could implement some clever idea which release the stack if it is not
+ used in let's say two minutes. The JIT callback can help to achieve
this without keeping a list of the currently JIT studied patterns.
- (6) OK, the stack is for long term memory allocation. But what happens
- if a pattern causes stack overflow with a stack of 1M? Is that 1M kept
+ (6) OK, the stack is for long term memory allocation. But what happens
+ if a pattern causes stack overflow with a stack of 1M? Is that 1M kept
until the stack is freed?
- Especially on embedded sytems, it might be a good idea to release mem-
- ory sometimes without freeing the stack. There is no API for this at
- the moment. Probably a function call which returns with the currently
- allocated memory for any stack and another which allows releasing mem-
+ Especially on embedded sytems, it might be a good idea to release mem-
+ ory sometimes without freeing the stack. There is no API for this at
+ the moment. Probably a function call which returns with the currently
+ allocated memory for any stack and another which allows releasing mem-
ory (shrinking the stack) would be a good idea if someone needs this.
(7) This is too much of a headache. Isn't there any better solution for
JIT stack handling?
- No, thanks to Windows. If POSIX threads were used everywhere, we could
+ No, thanks to Windows. If POSIX threads were used everywhere, we could
throw out this complicated API.
EXAMPLE CODE
- This is a single-threaded example that specifies a JIT stack without
+ This is a single-threaded example that specifies a JIT stack without
using a callback.
int rc;
@@ -8687,56 +8680,56 @@ EXAMPLE CODE
JIT FAST PATH API
- Because the API described above falls back to interpreted execution
+ Because the API described above falls back to interpreted execution
when JIT is not available, it is convenient for programs that are writ-
- ten for general use in many environments. However, calling JIT via
- pcre_exec() does have a performance impact. Programs that are written
- for use where JIT is known to be available, and which need the best
- possible performance, can instead use a "fast path" API to call JIT
- execution directly instead of calling pcre_exec() (obviously only for
+ ten for general use in many environments. However, calling JIT via
+ pcre_exec() does have a performance impact. Programs that are written
+ for use where JIT is known to be available, and which need the best
+ possible performance, can instead use a "fast path" API to call JIT ex-
+ ecution directly instead of calling pcre_exec() (obviously only for
patterns that have been successfully studied by JIT).
- The fast path function is called pcre_jit_exec(), and it takes exactly
- the same arguments as pcre_exec(), plus one additional argument that
- must point to a JIT stack. The JIT stack arrangements described above
+ The fast path function is called pcre_jit_exec(), and it takes exactly
+ the same arguments as pcre_exec(), plus one additional argument that
+ must point to a JIT stack. The JIT stack arrangements described above
do not apply. The return values are the same as for pcre_exec().
- When you call pcre_exec(), as well as testing for invalid options, a
+ When you call pcre_exec(), as well as testing for invalid options, a
number of other sanity checks are performed on the arguments. For exam-
- ple, if the subject pointer is NULL, or its length is negative, an
- immediate error is given. Also, unless PCRE_NO_UTF[8|16|32] is set, a
- UTF subject string is tested for validity. In the interests of speed,
- these checks do not happen on the JIT fast path, and if invalid data is
+ ple, if the subject pointer is NULL, or its length is negative, an im-
+ mediate error is given. Also, unless PCRE_NO_UTF[8|16|32] is set, a UTF
+ subject string is tested for validity. In the interests of speed, these
+ checks do not happen on the JIT fast path, and if invalid data is
passed, the result is undefined.
- Bypassing the sanity checks and the pcre_exec() wrapping can give
+ Bypassing the sanity checks and the pcre_exec() wrapping can give
speedups of more than 10%.
- Note that the pcre_jit_exec() function is not available in versions of
- PCRE before 8.32 (released in November 2012). If you need to support
+ Note that the pcre_jit_exec() function is not available in versions of
+ PCRE before 8.32 (released in November 2012). If you need to support
versions that old you must either use the slower pcre_exec(), or switch
- between the two codepaths by checking the values of PCRE_MAJOR and
+ between the two codepaths by checking the values of PCRE_MAJOR and
PCRE_MINOR.
- Due to an unfortunate implementation oversight, even in versions 8.32
- and later there will be no pcre_jit_exec() stub function defined when
- PCRE is compiled with --disable-jit, which is the default, and there's
- no way to detect whether PCRE was compiled with --enable-jit via a
+ Due to an unfortunate implementation oversight, even in versions 8.32
+ and later there will be no pcre_jit_exec() stub function defined when
+ PCRE is compiled with --disable-jit, which is the default, and there's
+ no way to detect whether PCRE was compiled with --enable-jit via a
macro.
- If you need to support versions older than 8.32, or versions that may
- not build with --enable-jit, you must either use the slower
+ If you need to support versions older than 8.32, or versions that may
+ not build with --enable-jit, you must either use the slower
pcre_exec(), or switch between the two codepaths by checking the values
of PCRE_MAJOR and PCRE_MINOR.
- Switching between the two by checking the version assumes that all the
- versions being targeted are built with --enable-jit. To also support
+ Switching between the two by checking the version assumes that all the
+ versions being targeted are built with --enable-jit. To also support
builds that may use --disable-jit either pcre_exec() must be used, or a
compile-time check for JIT via pcre_config() (which assumes the runtime
- environment will be the same), or as the Git project decided to do,
+ environment will be the same), or as the Git project decided to do,
simply assume that pcre_jit_exec() is present in 8.32 or later unless a
- compile-time flag is provided, see the "grep: un-break building with
- PCRE >= 8.32 without --enable-jit" commit in git.git for an example of
+ compile-time flag is provided, see the "grep: un-break building with
+ PCRE >= 8.32 without --enable-jit" commit in git.git for an example of
that.
@@ -8782,11 +8775,11 @@ PARTIAL MATCHING IN PCRE
If the application sees the user's keystrokes one by one, and can check
that what has been typed so far is potentially valid, it is able to
- raise an error as soon as a mistake is made, by beeping and not
- reflecting the character that has been typed, for example. This immedi-
- ate feedback is likely to be a better user interface than a check that
- is delayed until the entire string has been entered. Partial matching
- can also be useful when the subject string is very long and is not all
+ raise an error as soon as a mistake is made, by beeping and not re-
+ flecting the character that has been typed, for example. This immediate
+ feedback is likely to be a better user interface than a check that is
+ delayed until the entire string has been entered. Partial matching can
+ also be useful when the subject string is very long and is not all
available at once.
PCRE supports partial matching by means of the PCRE_PARTIAL_SOFT and
@@ -8862,8 +8855,8 @@ PARTIAL MATCHING USING pcre_exec() OR pcre[16|32]_exec()
If PCRE_PARTIAL_SOFT is set when pcre_exec() or pcre[16|32]_exec()
identifies a partial match, the partial match is remembered, but match-
ing continues as normal, and other alternatives in the pattern are
- tried. If no complete match can be found, PCRE_ERROR_PARTIAL is
- returned instead of PCRE_ERROR_NOMATCH.
+ tried. If no complete match can be found, PCRE_ERROR_PARTIAL is re-
+ turned instead of PCRE_ERROR_NOMATCH.
This option is "soft" because it prefers a complete match over a par-
tial match. All the various matching items in a pattern behave as if
@@ -8949,8 +8942,8 @@ PARTIAL MATCHING USING pcre_dfa_exec() OR pcre[16|32]_dfa_exec()
Because the DFA functions always search for all possible matches, and
there is no difference between greedy and ungreedy repetition, their
behaviour is different from the standard functions when PCRE_PAR-
- TIAL_HARD is set. Consider the string "dog" matched against the
- ungreedy pattern shown above:
+ TIAL_HARD is set. Consider the string "dog" matched against the un-
+ greedy pattern shown above:
/dog(sbody)??/
@@ -9029,9 +9022,9 @@ MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre[16|32]_dfa_exec()
and calling the function again with the same compiled regular expres-
sion, this time setting the PCRE_DFA_RESTART option. You must pass the
same working space as before, because this is where details of the pre-
- vious partial match are stored. Here is an example using pcretest,
- using the \R escape sequence to set the PCRE_DFA_RESTART option (\D
- specifies the use of the DFA matching function):
+ vious partial match are stored. Here is an example using pcretest, us-
+ ing the \R escape sequence to set the PCRE_DFA_RESTART option (\D spec-
+ ifies the use of the DFA matching function):
re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
data> 23ja\P\D
@@ -9047,11 +9040,11 @@ MULTI-SEGMENT MATCHING WITH pcre_dfa_exec() OR pcre[16|32]_dfa_exec()
to.
That means that, for an unanchored pattern, if a continued match fails,
- it is not possible to try again at a new starting point. All this
- facility is capable of doing is continuing with the previous match
- attempt. In the previous example, if the second set of data is "ug23"
- the result is no match, even though there would be a match for "aug23"
- if the entire string were given at once. Depending on the application,
+ it is not possible to try again at a new starting point. All this fa-
+ cility is capable of doing is continuing with the previous match at-
+ tempt. In the previous example, if the second set of data is "ug23" the
+ result is no match, even though there would be a match for "aug23" if
+ the entire string were given at once. Depending on the application,
this may or may not be what you want. The only way to allow for start-
ing again at the next character is to retain the matched part of the
subject and try a new complete match.
@@ -9100,8 +9093,8 @@ ISSUES WITH MULTI-SEGMENT MATCHING
1. If the pattern contains a test for the beginning of a line, you need
to pass the PCRE_NOTBOL option when the subject string for any call
- does start at the beginning of a line. There is also a PCRE_NOTEOL
- option, but in practice when doing multi-segment matching you should be
+ does start at the beginning of a line. There is also a PCRE_NOTEOL op-
+ tion, but in practice when doing multi-segment matching you should be
using PCRE_PARTIAL_HARD, which includes the effect of PCRE_NOTEOL.
2. Lookbehind assertions that have already been obeyed are catered for
@@ -9213,8 +9206,8 @@ ISSUES WITH MULTI-SEGMENT MATCHING
1234|ABCD
where no string can be a partial match for both alternatives. This is
- not a problem if a standard matching function is used, because the
- entire match has to be rerun each time:
+ not a problem if a standard matching function is used, because the en-
+ tire match has to be rerun each time:
re> /1234|3789/
data> ABC123\P\P
@@ -9264,10 +9257,10 @@ SAVING AND RE-USING PRECOMPILED PCRE PATTERNS
If you save compiled patterns to a file, you can copy them to a differ-
ent host and run them there. If the two hosts have different endianness
- (byte order), you should run the pcre[16|32]_pat-
- tern_to_host_byte_order() function on the new host before trying to
- match the pattern. The matching functions return PCRE_ERROR_BADENDIAN-
- NESS if they detect a pattern with the wrong endianness.
+ (byte order), you should run the pcre[16|32]_pattern_to_host_byte_or-
+ der() function on the new host before trying to match the pattern. The
+ matching functions return PCRE_ERROR_BADENDIANNESS if they detect a
+ pattern with the wrong endianness.
Compiling regular expressions with one version of PCRE for use with a
different version is not guaranteed to work and may cause crashes, and
@@ -9282,8 +9275,8 @@ SAVING A COMPILED PATTERN
find the length of this block in bytes by calling
pcre[16|32]_fullinfo() with an argument of PCRE_INFO_SIZE. You can then
save the data in any appropriate manner. Here is sample code for the
- 8-bit library that compiles a pattern and writes it to a file. It
- assumes that the variable fd refers to a file that is open for output:
+ 8-bit library that compiles a pattern and writes it to a file. It as-
+ sumes that the variable fd refers to a file that is open for output:
int erroroffset, rc, size;
char *error;
@@ -9298,14 +9291,14 @@ SAVING A COMPILED PATTERN
In this example, the bytes that comprise the compiled pattern are
copied exactly. Note that this is binary data that may contain any of
- the 256 possible byte values. On systems that make a distinction
- between binary and non-binary data, be sure that the file is opened for
+ the 256 possible byte values. On systems that make a distinction be-
+ tween binary and non-binary data, be sure that the file is opened for
binary output.
If you want to write more than one pattern to a file, you will have to
devise a way of separating them. For binary data, preceding each pat-
- tern with its length is probably the most straightforward approach.
- Another possibility is to write out the data in hexadecimal instead of
+ tern with its length is probably the most straightforward approach. An-
+ other possibility is to write out the data in hexadecimal instead of
binary, one pattern to a line.
Saving compiled patterns in a file is only one possible way of storing
@@ -9324,8 +9317,8 @@ SAVING A COMPILED PATTERN
study data, and this is what you must save (not the pcre[16|32]_extra
block itself). The length of the study data can be obtained by calling
pcre[16|32]_fullinfo() with an argument of PCRE_INFO_STUDYSIZE. Remem-
- ber to check that pcre[16|32]_study() did return a non-NULL value
- before trying to save the study data.
+ ber to check that pcre[16|32]_study() did return a non-NULL value be-
+ fore trying to save the study data.
RE-USING A PRECOMPILED PATTERN
@@ -9354,18 +9347,18 @@ RE-USING A PRECOMPILED PATTERN
If you saved study data with the compiled pattern, you need to create
your own pcre[16|32]_extra data block and set the study_data field to
- point to the reloaded study data. You must also set the
- PCRE_EXTRA_STUDY_DATA bit in the flags field to indicate that study
- data is present. Then pass the pcre[16|32]_extra block to the matching
- function in the usual way. If the pattern was studied for just-in-time
- optimization, that data cannot be saved, and so is lost by a
- save/restore cycle.
+ point to the reloaded study data. You must also set the PCRE_EX-
+ TRA_STUDY_DATA bit in the flags field to indicate that study data is
+ present. Then pass the pcre[16|32]_extra block to the matching function
+ in the usual way. If the pattern was studied for just-in-time optimiza-
+ tion, that data cannot be saved, and so is lost by a save/restore cy-
+ cle.
COMPATIBILITY WITH DIFFERENT PCRE RELEASES
- In general, it is safest to recompile all saved patterns when you
- update to a new PCRE release, though not all updates actually require
+ In general, it is safest to recompile all saved patterns when you up-
+ date to a new PCRE release, though not all updates actually require
this.
@@ -9454,8 +9447,8 @@ STACK USAGE AT RUN TIME
stack. In some environments the default process stack is quite small,
and if it runs out the result is often SIGSEGV. This issue is probably
the most frequently raised problem with PCRE. Rewriting your pattern
- can often help. The pcrestack documentation discusses this issue in
- detail.
+ can often help. The pcrestack documentation discusses this issue in de-
+ tail.
PROCESSING TIME
@@ -9466,8 +9459,8 @@ PROCESSING TIME
(a|e|i|o|u). In general, the simplest construction that provides the
required behaviour is usually the most efficient. Jeffrey Friedl's book
contains a lot of useful general discussion about optimizing regular
- expressions for efficient performance. This document contains a few
- observations about PCRE.
+ expressions for efficient performance. This document contains a few ob-
+ servations about PCRE.
Using Unicode character properties (the \p, \P, and \X escapes) is
slow, because PCRE has to use a multi-stage table lookup whenever it
@@ -9516,8 +9509,8 @@ PROCESSING TIME
2, 3, or 4 times, and for each of those cases other than 0 or 4, the +
repeats can match different numbers of times.) When the remainder of
the pattern is such that the entire match is going to fail, PCRE has in
- principle to try every possible variation, and this can take an
- extremely long time, even for relatively short strings.
+ principle to try every possible variation, and this can take an ex-
+ tremely long time, even for relatively short strings.
An optimization catches some of the more simple cases such as
@@ -9580,8 +9573,8 @@ DESCRIPTION
This set of functions provides a POSIX-style API for the PCRE regular
expression 8-bit library. See the pcreapi documentation for a descrip-
tion of PCRE's native API, which contains much additional functional-
- ity. There is no POSIX-style wrapper for PCRE's 16-bit and 32-bit
- library.
+ ity. There is no POSIX-style wrapper for PCRE's 16-bit and 32-bit li-
+ brary.
The functions described here are just wrapper functions that ultimately
call the PCRE native API. Their prototypes are defined in the
@@ -9610,12 +9603,12 @@ DESCRIPTION
even less compatible.
The header for these functions is supplied as pcreposix.h to avoid any
- potential clash with other POSIX libraries. It can, of course, be
- renamed or aliased as regex.h, which is the "correct" name. It provides
+ potential clash with other POSIX libraries. It can, of course, be re-
+ named or aliased as regex.h, which is the "correct" name. It provides
two structure types, regex_t for compiled internal forms, and reg-
match_t for returning captured substrings. It also defines some con-
- stants whose names start with "REG_"; these are used for setting
- options and identifying error codes.
+ stants whose names start with "REG_"; these are used for setting op-
+ tions and identifying error codes.
COMPILING A PATTERN
@@ -9676,8 +9669,8 @@ COMPILING A PATTERN
Note that REG_UTF8 is not part of the POSIX standard.
In the absence of these flags, no options are passed to the native
- function. This means the the regex is compiled with PCRE default
- semantics. In particular, the way it handles newline characters in the
+ function. This means the the regex is compiled with PCRE default se-
+ mantics. In particular, the way it handles newline characters in the
subject string is the Perl way, not the POSIX way. Note that setting
PCRE_MULTILINE has only some of the effects specified for REG_NEWLINE.
It does not affect the way newlines are matched by . (they are not) or
@@ -9780,9 +9773,9 @@ MATCHING A PATTERN
relate to the capturing subpatterns of the regular expression. Unused
entries in the array have both structure members set to -1.
- A successful match yields a zero return; various error codes are
- defined in the header file, of which REG_NOMATCH is the "expected"
- failure code.
+ A successful match yields a zero return; various error codes are de-
+ fined in the header file, of which REG_NOMATCH is the "expected" fail-
+ ure code.
ERROR MESSAGES
@@ -9790,9 +9783,9 @@ ERROR MESSAGES
The regerror() function maps a non-zero errorcode from either regcomp()
or regexec() to a printable message. If preg is not NULL, the error
should have arisen from the use of that structure. A message terminated
- by a binary zero is placed in errbuf. The length of the message,
- including the zero, is limited to errbuf_size. The yield of the func-
- tion is the size of buffer needed to hold the whole message.
+ by a binary zero is placed in errbuf. The length of the message, in-
+ cluding the zero, is limited to errbuf_size. The yield of the function
+ is the size of buffer needed to hold the whole message.
MEMORY USAGE
@@ -9909,15 +9902,15 @@ MATCHING INTERFACE
ignored.
CAVEAT: An optional sub-pattern that does not exist in the matched
- string is assigned the empty string. Therefore, the following will
- return false (because the empty string is not a valid number):
+ string is assigned the empty string. Therefore, the following will re-
+ turn false (because the empty string is not a valid number):
int number;
pcrecpp::RE::FullMatch("abc", "[a-z]+(\\d+)?", &number);
The matching interface supports at most 16 arguments per call. If you
- need more, consider using the more general interface
- pcrecpp::RE::DoMatch. See pcrecpp.h for the signature for DoMatch.
+ need more, consider using the more general interface pcrecpp::RE::Do-
+ Match. See pcrecpp.h for the signature for DoMatch.
NOTE: Do not use no_arg, which is used internally to mark the end of a
list of optional arguments, as a placeholder for missing arguments, as
@@ -9982,10 +9975,10 @@ UTF-8 AND THE MATCHING INTERFACE
PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE
- PCRE defines some modifiers to change the behavior of the regular
- expression engine. The C++ wrapper defines an auxiliary class,
- RE_Options, as a vehicle to pass such modifiers to a RE class. Cur-
- rently, the following modifiers are supported:
+ PCRE defines some modifiers to change the behavior of the regular ex-
+ pression engine. The C++ wrapper defines an auxiliary class, RE_Op-
+ tions, as a vehicle to pass such modifiers to a RE class. Currently,
+ the following modifiers are supported:
modifier description Perl corresponding
@@ -10007,8 +10000,8 @@ PASSING MODIFIERS TO THE REGULAR EXPRESSION ENGINE
API reference page.
For each modifier, there are two member functions whose name is made
- out of the modifier in lowercase, without the "PCRE_" prefix. For
- instance, PCRE_CASELESS is handled by
+ out of the modifier in lowercase, without the "PCRE_" prefix. For in-
+ stance, PCRE_CASELESS is handled by
bool caseless()
@@ -10089,12 +10082,12 @@ SCANNING TEXT INCREMENTALLY
...;
}
- Each successful call to "Consume" will set "var/value", and also
- advance "input" so it points past the matched text.
+ Each successful call to "Consume" will set "var/value", and also ad-
+ vance "input" so it points past the matched text.
- The "FindAndConsume" operation is similar to "Consume" but does not
- anchor your match at the beginning of the string. For example, you
- could extract all words from a string by repeatedly calling
+ The "FindAndConsume" operation is similar to "Consume" but does not an-
+ chor your match at the beginning of the string. For example, you could
+ extract all words from a string by repeatedly calling
pcrecpp::RE("(\\w+)").FindAndConsume(&input, &word)
@@ -10138,8 +10131,8 @@ REPLACING PARTS OF STRINGS
string s = "yabba dabba doo";
pcrecpp::RE("b+").GlobalReplace("d", &s);
- will leave "s" containing "yada dada doo". It returns the number of
- replacements made.
+ will leave "s" containing "yada dada doo". It returns the number of re-
+ placements made.
Extract is like Replace, except that if the pattern matches, "rewrite"
is copied into "out" (an additional argument) with substitutions. The
@@ -10196,8 +10189,8 @@ PCRE SAMPLE PROGRAM
If PCRE is installed elsewhere, you may need to add additional options
to the command line. For example, on a Unix-like system that has PCRE
- installed in /usr/local, you can compile the demonstration program
- using a command like this:
+ installed in /usr/local, you can compile the demonstration program us-
+ ing a command like this:
gcc -o pcredemo -I/usr/local/include pcredemo.c \
-L/usr/local/lib -lpcre
@@ -10205,8 +10198,8 @@ PCRE SAMPLE PROGRAM
In a Windows environment, if you want to statically link the program
against a non-dll pcre.a file, you must uncomment the line that defines
PCRE_STATIC before including pcre.h, because otherwise the pcre_mal-
- loc() and pcre_free() exported functions will be declared
- __declspec(dllimport), with unwanted results.
+ loc() and pcre_free() exported functions will be declared __de-
+ clspec(dllimport), with unwanted results.
Once you have compiled and linked the demonstration program, you can
run simple tests like this:
@@ -10215,16 +10208,16 @@ PCRE SAMPLE PROGRAM
./pcredemo -g 'cat|dog' 'the dog sat on the cat'
Note that there is a much more comprehensive test program, called
- pcretest, which supports many more facilities for testing regular
- expressions and both PCRE libraries. The pcredemo program is provided
- as a simple coding example.
+ pcretest, which supports many more facilities for testing regular ex-
+ pressions and both PCRE libraries. The pcredemo program is provided as
+ a simple coding example.
If you try to run pcredemo when PCRE is not installed in the standard
library directory, you may get an error like this on some operating
systems (e.g. Solaris):
- ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or
- directory
+ ld.so.1: a.out: fatal: libpcre.so.0: open failed: No such file or di-
+ rectory
This is caused by the way shared library support works on those sys-
tems. You need to add
@@ -10259,8 +10252,8 @@ SIZE AND OTHER LIMITATIONS
never in practice be relevant.
The maximum length of a compiled pattern is approximately 64K data
- units (bytes for the 8-bit library, 16-bit units for the 16-bit
- library, and 32-bit units for the 32-bit library) if PCRE is compiled
+ units (bytes for the 8-bit library, 16-bit units for the 16-bit li-
+ brary, and 32-bit units for the 32-bit library) if PCRE is compiled
with the default internal linkage size, which is 2 bytes for the 8-bit
and 16-bit libraries, and 4 bytes for the 32-bit library. If you want
to process regular expressions that are truly enormous, you can compile
@@ -10280,10 +10273,10 @@ SIZE AND OTHER LIMITATIONS
the default is 250.
There is a limit to the number of forward references to subsequent sub-
- patterns of around 200,000. Repeated forward references with fixed
- upper limits, for example, (?2){0,100} when subpattern number 2 is to
- the right, are included in the count. There is no limit to the number
- of backward references.
+ patterns of around 200,000. Repeated forward references with fixed up-
+ per limits, for example, (?2){0,100} when subpattern number 2 is to the
+ right, are included in the count. There is no limit to the number of
+ backward references.
The maximum length of name for a named subpattern is 32 characters, and
the maximum number of named subpatterns is 10000.
@@ -10329,8 +10322,8 @@ PCRE DISCUSSION OF STACK USAGE
back up and try a different alternative if the first one fails. As
matching proceeds deeper and deeper into the tree of possibilities, the
recursion depth increases. The match() function is also called in other
- circumstances, for example, whenever a parenthesized sub-pattern is
- entered, and in certain cases of repetition.
+ circumstances, for example, whenever a parenthesized sub-pattern is en-
+ tered, and in certain cases of repetition.
Not all calls of match() increase the recursion depth; for an item such
as a* it may be called several times at the same level, after matching
@@ -10344,8 +10337,8 @@ PCRE DISCUSSION OF STACK USAGE
PCRE_STUDY_JIT_COMPILE option, and just-in-time compiling was success-
ful, and the options passed to pcre[16|32]_exec() were not incompati-
ble, the matching process uses the JIT-compiled code instead of the
- match() function. In this case, the memory requirements are handled
- entirely differently. See the pcrejit documentation for details.
+ match() function. In this case, the memory requirements are handled en-
+ tirely differently. See the pcrejit documentation for details.
The pcre[16|32]_dfa_exec() function operates in an entirely different
way, and uses recursion only when there is a regular expression recur-
@@ -10376,8 +10369,8 @@ PCRE DISCUSSION OF STACK USAGE
end of the data, and is the kind of pattern that might be used when
processing an XML file. Each iteration of the outer parentheses matches
either one character that is not "<" or a "<" that is not followed by
- "inet". However, each time a parenthesis is processed, a recursion
- occurs, so this formulation uses a stack frame for each matched charac-
+ "inet". However, each time a parenthesis is processed, a recursion oc-
+ curs, so this formulation uses a stack frame for each matched charac-
ter. For a long string, a lot of stack is required. Consider now this
rewritten pattern, which matches exactly the same strings:
@@ -10434,11 +10427,11 @@ PCRE DISCUSSION OF STACK USAGE
Obtaining an estimate of stack usage
- The actual amount of stack used per recursion can vary quite a lot,
- depending on the compiler that was used to build PCRE and the optimiza-
+ The actual amount of stack used per recursion can vary quite a lot, de-
+ pending on the compiler that was used to build PCRE and the optimiza-
tion or debugging options that were set for it. The rule of thumb value
- of 500 bytes mentioned above may be larger or smaller than what is
- actually needed. A better approximation can be obtained by running this
+ of 500 bytes mentioned above may be larger or smaller than what is ac-
+ tually needed. A better approximation can be obtained by running this
command:
pcretest -m -C
@@ -10452,9 +10445,9 @@ PCRE DISCUSSION OF STACK USAGE
The value is approximate because some recursions need a bit more (up to
perhaps 16 more bytes).
- If the above command is given when PCRE is compiled to use the heap
- instead of the stack for recursion, the value that is output is the
- size of each block that is obtained from the heap.
+ If the above command is given when PCRE is compiled to use the heap in-
+ stead of the stack for recursion, the value that is output is the size
+ of each block that is obtained from the heap.
Changing stack size in Unix-like systems
@@ -10482,8 +10475,8 @@ PCRE DISCUSSION OF STACK USAGE
Using setrlimit(), as described above, should also work on Mac OS X. It
is also possible to set a stack size when linking a program. There is a
- discussion about stack sizes in Mac OS X at this web site:
- http://developer.apple.com/qa/qa2005/qa1419.html.
+ discussion about stack sizes in Mac OS X at this web site: http://de-
+ veloper.apple.com/qa/qa2005/qa1419.html.
AUTHOR
diff --git a/pcre/doc/pcreapi.3 b/pcre/doc/pcreapi.3
index 6e7c7c6e3ce..d79217818a6 100644
--- a/pcre/doc/pcreapi.3
+++ b/pcre/doc/pcreapi.3
@@ -1227,7 +1227,7 @@ the following negative numbers:
PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid
PCRE_ERROR_UNSET the requested field is not set
.sp
-The "magic number" is placed at the start of each compiled pattern as an simple
+The "magic number" is placed at the start of each compiled pattern as a simple
check against passing an arbitrary memory pointer. The endianness error can
occur if a compiled pattern is saved and reloaded on a different host. Here is
a typical call of \fBpcre_fullinfo()\fP, to obtain the length of the compiled
@@ -1294,7 +1294,7 @@ returned. For anchored patterns, -2 is returned.
.sp
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 \fBuint_t\fP
+otherwise return 0. The fourth argument should point to a \fBuint_t\fP
variable.
.P
In the 8-bit library, the value is always less than 256. In the 16-bit library
@@ -1560,7 +1560,7 @@ returned value 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for
.sp
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 \fBuint32_t\fP variable. If there is no such
+fourth argument should point to a \fBuint32_t\fP variable. If there is no such
value, 0 is returned.
.
.
diff --git a/pcre/doc/pcregrep.txt b/pcre/doc/pcregrep.txt
index 97d9a7bd379..0c873c7a863 100644
--- a/pcre/doc/pcregrep.txt
+++ b/pcre/doc/pcregrep.txt
@@ -26,8 +26,8 @@ DESCRIPTION
If you attempt to use delimiters (for example, by surrounding a pattern
with slashes, as is common in Perl scripts), they are interpreted as
part of the pattern. Quotes can of course be used to delimit patterns
- on the command line because they are interpreted by the shell, and
- indeed quotes are required if a pattern contains white space or shell
+ on the command line because they are interpreted by the shell, and in-
+ deed quotes are required if a pattern contains white space or shell
metacharacters.
The first argument that follows any option settings is treated as the
@@ -37,8 +37,8 @@ DESCRIPTION
or an argument pattern must be provided.
If no files are specified, pcregrep reads the standard input. The stan-
- dard input can also be referenced by a name consisting of a single
- hyphen. For example:
+ dard input can also be referenced by a name consisting of a single hy-
+ phen. For example:
pcregrep some-pattern /file1 - /file3
@@ -47,8 +47,8 @@ DESCRIPTION
the start of each line, followed by a colon. However, there are options
that can change how pcregrep behaves. In particular, the -M option
makes it possible to search for patterns that span line boundaries.
- What defines a line boundary is controlled by the -N (--newline)
- option.
+ What defines a line boundary is controlled by the -N (--newline) op-
+ tion.
The amount of memory used for buffering files that are being scanned is
controlled by a parameter that can be set by the --buffer-size option.
@@ -66,12 +66,12 @@ DESCRIPTION
By default, as soon as one pattern matches a line, no further patterns
are considered. However, if --colour (or --color) is used to colour the
matching substrings, or if --only-matching, --file-offsets, or --line-
- offsets is used to output only the part of the line that matched
- (either shown literally, or as an offset), scanning resumes immediately
+ offsets is used to output only the part of the line that matched (ei-
+ ther shown literally, or as an offset), scanning resumes immediately
following the match, so that further matches on the same line can be
- found. If there are multiple patterns, they are all tried on the
- remainder of the line, but patterns that follow the one that matched
- are not tried on the earlier part of the line.
+ found. If there are multiple patterns, they are all tried on the re-
+ mainder of the line, but patterns that follow the one that matched are
+ not tried on the earlier part of the line.
This behaviour means that the order in which multiple patterns are
specified can affect the output when one of the above options is used.
@@ -80,11 +80,11 @@ DESCRIPTION
overlap).
Patterns that can match an empty string are accepted, but empty string
- matches are never recognized. An example is the pattern
- "(super)?(man)?", in which all components are optional. This pattern
- finds all occurrences of both "super" and "man"; the output differs
- from matching with "super|man" when only the matching substrings are
- being shown.
+ matches are never recognized. An example is the pattern "(su-
+ per)?(man)?", in which all components are optional. This pattern finds
+ all occurrences of both "super" and "man"; the output differs from
+ matching with "super|man" when only the matching substrings are being
+ shown.
If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses
the value to set a locale when calling the PCRE library. The --locale
@@ -105,9 +105,9 @@ BINARY FILES
By default, a file that contains a binary zero byte within the first
1024 bytes is identified as a binary file, and is processed specially.
- (GNU grep also identifies binary files in this manner.) See the
- --binary-files option for a means of changing the way binary files are
- handled.
+ (GNU grep also identifies binary files in this manner.) See the --bi-
+ nary-files option for a means of changing the way binary files are han-
+ dled.
OPTIONS
@@ -151,16 +151,16 @@ OPTIONS
--binary-files=word
Specify how binary files are to be processed. If the word is
- "binary" (the default), pattern matching is performed on
- binary files, but the only output is "Binary file <name>
+ "binary" (the default), pattern matching is performed on bi-
+ nary files, but the only output is "Binary file <name>
matches" when a match succeeds. If the word is "text", which
is equivalent to the -a or --text option, binary files are
processed in the same way as any other file. In this case,
when a match succeeds, the output may be binary garbage,
which can have nasty effects if sent to a terminal. If the
- word is "without-match", which is equivalent to the -I
- option, binary files are not processed at all; they are
- assumed not to be of interest.
+ word is "without-match", which is equivalent to the -I op-
+ tion, binary files are not processed at all; they are assumed
+ not to be of interest.
--buffer-size=number
Set the parameter that controls how much memory is used for
@@ -201,15 +201,15 @@ OPTIONS
ronment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value
of this variable should be a string of two numbers, separated
by a semicolon. They are copied directly into the control
- string for setting colour on a terminal, so it is your
- responsibility to ensure that they make sense. If neither of
+ string for setting colour on a terminal, so it is your re-
+ sponsibility to ensure that they make sense. If neither of
the environment variables is set, the default is "1;31",
which gives red.
-D action, --devices=action
- If an input path is not a regular file or a directory,
- "action" specifies how it is to be processed. Valid values
- are "read" (the default) or "skip" (silently skip the path).
+ If an input path is not a regular file or a directory, "ac-
+ tion" specifies how it is to be processed. Valid values are
+ "read" (the default) or "skip" (silently skip the path).
-d action, --directories=action
If an input path is a directory, "action" specifies how it is
@@ -218,8 +218,8 @@ OPTIONS
"recurse" (equivalent to the -r option), or "skip" (silently
skip the path, the default in Windows environments). In the
"read" case, directories are read as if they were ordinary
- files. In some operating systems the effect of reading a
- directory like this is an immediate end-of-file; in others it
+ files. In some operating systems the effect of reading a di-
+ rectory like this is an immediate end-of-file; in others it
may provoke an error.
-e pattern, --regex=pattern, --regexp=pattern
@@ -249,8 +249,8 @@ OPTIONS
whether listed on the command line, obtained from --file-
list, or by scanning a directory. The pattern is a PCRE regu-
lar expression, and is matched against the final component of
- the file name, not the entire path. The -F, -w, and -x
- options do not apply to this pattern. The option may be given
+ the file name, not the entire path. The -F, -w, and -x op-
+ tions do not apply to this pattern. The option may be given
any number of times in order to specify multiple patterns. If
a file name matches both an --include and an --exclude pat-
tern, it is excluded. There is no short form for this option.
@@ -264,29 +264,29 @@ OPTIONS
--exclude-dir=pattern
Directories whose names match the pattern are skipped without
- being processed, whatever the setting of the --recursive
- option. This applies to all directories, whether listed on
- the command line, obtained from --file-list, or by scanning a
+ being processed, whatever the setting of the --recursive op-
+ tion. This applies to all directories, whether listed on the
+ command line, obtained from --file-list, or by scanning a
parent directory. The pattern is a PCRE regular expression,
and is matched against the final component of the directory
name, not the entire path. The -F, -w, and -x options do not
apply to this pattern. The option may be given any number of
times in order to specify more than one pattern. If a direc-
- tory matches both --include-dir and --exclude-dir, it is
- excluded. There is no short form for this option.
+ tory matches both --include-dir and --exclude-dir, it is ex-
+ cluded. There is no short form for this option.
-F, --fixed-strings
Interpret each data-matching pattern as a list of fixed
- strings, separated by newlines, instead of as a regular
- expression. What constitutes a newline for this purpose is
- controlled by the --newline option. The -w (match as a word)
- and -x (match whole line) options can be used with -F. They
- apply to each of the fixed strings. A line is selected if any
+ strings, separated by newlines, instead of as a regular ex-
+ pression. What constitutes a newline for this purpose is con-
+ trolled by the --newline option. The -w (match as a word) and
+ -x (match whole line) options can be used with -F. They ap-
+ ply to each of the fixed strings. A line is selected if any
of the fixed strings are found in it (subject to -w or -x, if
present). This option applies only to the patterns that are
matched against the contents of files; it does not apply to
- patterns specified by any of the --include or --exclude
- options.
+ patterns specified by any of the --include or --exclude op-
+ tions.
-f filename, --file=filename
Read patterns from the file, one per line, and match them
@@ -358,16 +358,16 @@ OPTIONS
--include=pattern
If any --include patterns are specified, the only files that
are processed are those that match one of the patterns (and
- do not match an --exclude pattern). This option does not
- affect directories, but it applies to all files, whether
- listed on the command line, obtained from --file-list, or by
- scanning a directory. The pattern is a PCRE regular expres-
- sion, and is matched against the final component of the file
- name, not the entire path. The -F, -w, and -x options do not
- apply to this pattern. The option may be given any number of
- times. If a file name matches both an --include and an
- --exclude pattern, it is excluded. There is no short form
- for this option.
+ do not match an --exclude pattern). This option does not af-
+ fect directories, but it applies to all files, whether listed
+ on the command line, obtained from --file-list, or by scan-
+ ning a directory. The pattern is a PCRE regular expression,
+ and is matched against the final component of the file name,
+ not the entire path. The -F, -w, and -x options do not apply
+ to this pattern. The option may be given any number of times.
+ If a file name matches both an --include and an --exclude
+ pattern, it is excluded. There is no short form for this op-
+ tion.
--include-from=filename
Treat each non-empty line of the file as the data for an
@@ -381,8 +381,8 @@ OPTIONS
tories that are processed are those that match one of the
patterns (and do not match an --exclude-dir pattern). This
applies to all directories, whether listed on the command
- line, obtained from --file-list, or by scanning a parent
- directory. The pattern is a PCRE regular expression, and is
+ line, obtained from --file-list, or by scanning a parent di-
+ rectory. The pattern is a PCRE regular expression, and is
matched against the final component of the directory name,
not the entire path. The -F, -w, and -x options do not apply
to this pattern. The option may be given any number of times.
@@ -413,9 +413,9 @@ OPTIONS
--line-buffered
When this option is given, input is read and processed line
- by line, and the output is flushed after each write. By
- default, input is read in large chunks, unless pcregrep can
- determine that it is reading from a terminal (which is cur-
+ by line, and the output is flushed after each write. By de-
+ fault, input is read in large chunks, unless pcregrep can de-
+ termine that it is reading from a terminal (which is cur-
rently possible only in Unix-like environments). Output to
terminal is normally automatically flushed by the operating
system. This option can be useful when the input or output is
@@ -437,9 +437,9 @@ OPTIONS
--locale=locale-name
This option specifies a locale to be used for pattern match-
ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
- ronment variables. If no locale is specified, the PCRE
- library's default (usually the "C" locale) is used. There is
- no short form for this option.
+ ronment variables. If no locale is specified, the PCRE li-
+ brary's default (usually the "C" locale) is used. There is no
+ short form for this option.
--match-limit=number
Processing some regular expression patterns can require a
@@ -447,26 +447,26 @@ OPTIONS
gram crash if not enough is available. Other patterns may
take a very long time to search for all possible matching
strings. The pcre_exec() function that is called by pcregrep
- to do the matching has two parameters that can limit the
- resources that it uses.
+ to do the matching has two parameters that can limit the re-
+ sources that it uses.
- The --match-limit option provides a means of limiting
- resource usage when processing patterns that are not going to
+ The --match-limit option provides a means of limiting re-
+ source usage when processing 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 unlimited repeats. Internally, PCRE uses a func-
- tion 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.
+ tion called match() which it calls repeatedly (sometimes re-
+ cursively). 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.
The --recursion-limit option is similar to --match-limit, but
instead of limiting the total number of times that match() is
called, it limits the depth of recursive calls, which in turn
limits the amount of memory that can be used. The recursion
- depth is a smaller number than the total number of calls,
- because not all calls to match() are recursive. This limit is
+ depth is a smaller number than the total number of calls, be-
+ cause not all calls to match() are recursive. This limit is
of use only if it is set smaller than --match-limit.
There are no short forms for these options. The default set-
@@ -494,30 +494,30 @@ OPTIONS
is read line by line (see --line-buffered.)
-N newline-type, --newline=newline-type
- The PCRE library supports five different conventions for
- indicating the ends of lines. They are the single-character
- sequences CR (carriage return) and LF (linefeed), the two-
- character sequence CRLF, an "anycrlf" convention, which rec-
- ognizes any of the preceding three types, and an "any" con-
- vention, in which any Unicode line ending sequence is assumed
- to end a line. The Unicode sequences are the three just men-
+ The PCRE library supports five different conventions for in-
+ dicating the ends of lines. They are the single-character se-
+ quences CR (carriage return) and LF (linefeed), the two-char-
+ acter sequence CRLF, an "anycrlf" convention, which recog-
+ nizes any of the preceding three types, and an "any" conven-
+ tion, in which any Unicode line ending sequence is assumed to
+ end a line. The Unicode sequences are the three just men-
tioned, plus 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).
- When the PCRE library is built, a default line-ending
- sequence is specified. This is normally the standard
- sequence for the operating system. Unless otherwise specified
- by this option, pcregrep uses the library's default. The
- possible values for this option are CR, LF, CRLF, ANYCRLF, or
- ANY. This makes it possible to use pcregrep to scan files
- that have come from other environments without having to mod-
- ify their line endings. If the data that is being scanned
- does not agree with the convention set by this option, pcre-
- grep may behave in strange ways. Note that this option does
- not apply to files specified by the -f, --exclude-from, or
- --include-from options, which are expected to use the operat-
- ing system's standard newline sequence.
+ When the PCRE library is built, a default line-ending se-
+ quence is specified. This is normally the standard sequence
+ for the operating system. Unless otherwise specified by this
+ option, pcregrep uses the library's default. The possible
+ values for this option are CR, LF, CRLF, ANYCRLF, or ANY.
+ This makes it possible to use pcregrep to scan files that
+ have come from other environments without having to modify
+ their line endings. If the data that is being scanned does
+ not agree with the convention set by this option, pcregrep
+ may behave in strange ways. Note that this option does not
+ apply to files specified by the -f, --exclude-from, or --in-
+ clude-from options, which are expected to use the operating
+ system's standard newline sequence.
-n, --line-number
Precede each output line by its line number in the file, fol-
@@ -538,12 +538,12 @@ OPTIONS
is, the -A, -B, and -C options are ignored. If there is more
than one match in a line, each of them is shown separately.
If -o is combined with -v (invert the sense of the match to
- find non-matching lines), no output is generated, but the
- return code is set appropriately. If the matched portion of
- the line is empty, nothing is output unless the file name or
- line number are being printed, in which case they are shown
- on an otherwise empty line. This option is mutually exclusive
- with --file-offsets and --line-offsets.
+ find non-matching lines), no output is generated, but the re-
+ turn code is set appropriately. If the matched portion of the
+ line is empty, nothing is output unless the file name or line
+ number are being printed, in which case they are shown on an
+ otherwise empty line. This option is mutually exclusive with
+ --file-offsets and --line-offsets.
-onumber, --only-matching=number
Show only the part of the line that matched the capturing
@@ -579,8 +579,8 @@ OPTIONS
it contains, taking note of any --include and --exclude set-
tings. By default, a directory is read as a normal file; in
some operating systems this gives an immediate end-of-file.
- This option is a shorthand for setting the -d option to
- "recurse".
+ This option is a shorthand for setting the -d option to "re-
+ curse".
--recursion-limit=number
See --match-limit above.
@@ -626,10 +626,10 @@ OPTIONS
ENVIRONMENT VARIABLES
- The environment variables LC_ALL and LC_CTYPE are examined, in that
- order, for a locale. The first one that is set is used. This can be
- overridden by the --locale option. If no locale is set, the PCRE
- library's default (usually the "C" locale) is used.
+ The environment variables LC_ALL and LC_CTYPE are examined, in that or-
+ der, for a locale. The first one that is set is used. This can be over-
+ ridden by the --locale option. If no locale is set, the PCRE library's
+ default (usually the "C" locale) is used.
NEWLINES
@@ -640,8 +640,8 @@ NEWLINES
ever newline sequences they have in the input. However, the setting of
this option does not affect the interpretation of files specified by
the -f, --exclude-from, or --include-from options, which are assumed to
- use the operating system's standard newline sequence, nor does it
- affect the way in which pcregrep writes informational messages to the
+ use the operating system's standard newline sequence, nor does it af-
+ fect the way in which pcregrep writes informational messages to the
standard error and output streams. For these it uses the string "\n" to
indicate newlines, relying on the C I/O library to convert this to an
appropriate sequence.
@@ -687,13 +687,13 @@ OPTIONS WITH DATA
--file /some/file
Note, however, that if you want to supply a file name beginning with ~
- as data in a shell command, and have the shell expand ~ to a home
- directory, you must separate the file name from the option, because the
+ as data in a shell command, and have the shell expand ~ to a home di-
+ rectory, you must separate the file name from the option, because the
shell does not treat ~ specially unless it is at the start of an item.
The exceptions to the above are the --colour (or --color) and --only-
- matching options, for which the data is optional. If one of these
- options does have data, it must be given in the first form, using an
+ matching options, for which the data is optional. If one of these op-
+ tions does have data, it must be given in the first form, using an
equals character. Otherwise pcregrep will assume that it has no data.
@@ -702,14 +702,14 @@ MATCHING ERRORS
It is possible to supply a regular expression that takes a very long
time to fail to match certain lines. Such patterns normally involve
nested indefinite repeats, for example: (a+)*\d when matched against a
- line of a's with no final digit. The PCRE matching function has a
- resource limit that causes it to abort in these circumstances. If this
+ line of a's with no final digit. The PCRE matching function has a re-
+ source limit that causes it to abort in these circumstances. If this
happens, pcregrep outputs an error message and the line that caused the
problem to the standard error stream. If there are more than 20 such
errors, pcregrep gives up.
- The --match-limit option of pcregrep can be used to set the overall
- resource limit; there is a second option called --recursion-limit that
+ The --match-limit option of pcregrep can be used to set the overall re-
+ source limit; there is a second option called --recursion-limit that
sets a limit on the amount of memory (usually stack) that is used (see
the discussion of these options above).
diff --git a/pcre/doc/pcretest.1 b/pcre/doc/pcretest.1
index ea7457c03d0..fec964d782a 100644
--- a/pcre/doc/pcretest.1
+++ b/pcre/doc/pcretest.1
@@ -1,4 +1,4 @@
-.TH PCRETEST 1 "23 February 2017" "PCRE 8.41"
+.TH PCRETEST 1 "10 February 2020" "PCRE 8.44"
.SH NAME
pcretest - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -78,21 +78,19 @@ the 16-bit library, or \fBpcre32_xx\fP when using the 32-bit library".
.rs
.TP 10
\fB-8\fP
-If both the 8-bit library has been built, this option causes the 8-bit library
-to be used (which is the default); if the 8-bit library has not been built,
-this option causes an error.
+If the 8-bit library has been built, this option causes it to be used (this is
+the default). If the 8-bit library has not been built, this option causes an
+error.
.TP 10
\fB-16\fP
-If both the 8-bit or the 32-bit, and the 16-bit libraries have been built, this
-option causes the 16-bit library to be used. If only the 16-bit library has been
-built, this is the default (so has no effect). If only the 8-bit or the 32-bit
-library has been built, this option causes an error.
+If the 16-bit library has been built, this option causes it to be used. If only
+the 16-bit library has been built, this is the default. If the 16-bit library
+has not been built, this option causes an error.
.TP 10
\fB-32\fP
-If both the 8-bit or the 16-bit, and the 32-bit libraries have been built, this
-option causes the 32-bit library to be used. If only the 32-bit library has been
-built, this is the default (so has no effect). If only the 8-bit or the 16-bit
-library has been built, this option causes an error.
+If the 32-bit library has been built, this option causes it to be used. If only
+the 32-bit library has been built, this is the default. If the 32-bit library
+has not been built, this option causes an error.
.TP 10
\fB-b\fP
Behave as if each pattern has the \fB/B\fP (show byte code) modifier; the
@@ -1155,6 +1153,6 @@ Cambridge CB2 3QH, England.
.rs
.sp
.nf
-Last updated: 23 February 2017
-Copyright (c) 1997-2017 University of Cambridge.
+Last updated: 10 February 2020
+Copyright (c) 1997-2020 University of Cambridge.
.fi
diff --git a/pcre/doc/pcretest.txt b/pcre/doc/pcretest.txt
index 6d7305cfe82..835ee58a46d 100644
--- a/pcre/doc/pcretest.txt
+++ b/pcre/doc/pcretest.txt
@@ -47,15 +47,15 @@ INPUT DATA FORMAT
PCRE's 8-BIT, 16-BIT AND 32-BIT LIBRARIES
From release 8.30, two separate PCRE libraries can be built. The origi-
- nal one supports 8-bit character strings, whereas the newer 16-bit
- library supports character strings encoded in 16-bit units. From
- release 8.32, a third library can be built, supporting character
- strings encoded in 32-bit units. The pcretest program can be used to
- test all three libraries. However, it is itself still an 8-bit program,
- reading 8-bit input and writing 8-bit output. When testing the 16-bit
- or 32-bit library, the patterns and data strings are converted to 16-
- or 32-bit format before being passed to the PCRE library functions.
- Results are converted to 8-bit for output.
+ nal one supports 8-bit character strings, whereas the newer 16-bit li-
+ brary supports character strings encoded in 16-bit units. From release
+ 8.32, a third library can be built, supporting character strings en-
+ coded in 32-bit units. The pcretest program can be used to test all
+ three libraries. However, it is itself still an 8-bit program, reading
+ 8-bit input and writing 8-bit output. When testing the 16-bit or
+ 32-bit library, the patterns and data strings are converted to 16- or
+ 32-bit format before being passed to the PCRE library functions. Re-
+ sults are converted to 8-bit for output.
References to functions and structures of the form pcre[16|32]_xx below
mean "pcre_xx when using the 8-bit library, pcre16_xx when using the
@@ -64,34 +64,31 @@ PCRE's 8-BIT, 16-BIT AND 32-BIT LIBRARIES
COMMAND LINE OPTIONS
- -8 If both the 8-bit library has been built, this option causes
- the 8-bit library to be used (which is the default); if the
- 8-bit library has not been built, this option causes an
- error.
+ -8 If the 8-bit library has been built, this option causes it to
+ be used (this is the default). If the 8-bit library has not
+ been built, this option causes an error.
- -16 If both the 8-bit or the 32-bit, and the 16-bit libraries
- have been built, this option causes the 16-bit library to be
- used. If only the 16-bit library has been built, this is the
- default (so has no effect). If only the 8-bit or the 32-bit
- library has been built, this option causes an error.
+ -16 If the 16-bit library has been built, this option causes it
+ to be used. If only the 16-bit library has been built, this
+ is the default. If the 16-bit library has not been built,
+ this option causes an error.
- -32 If both the 8-bit or the 16-bit, and the 32-bit libraries
- have been built, this option causes the 32-bit library to be
- used. If only the 32-bit library has been built, this is the
- default (so has no effect). If only the 8-bit or the 16-bit
- library has been built, this option causes an error.
+ -32 If the 32-bit library has been built, this option causes it
+ to be used. If only the 32-bit library has been built, this
+ is the default. If the 32-bit library has not been built,
+ this option causes an error.
- -b Behave as if each pattern has the /B (show byte code) modi-
+ -b Behave as if each pattern has the /B (show byte code) modi-
fier; the internal form is output after compilation.
-C Output the version number of the PCRE library, and all avail-
- able information about the optional features that are
- included, and then exit with zero exit code. All other
- options are ignored.
+ able information about the optional features that are in-
+ cluded, and then exit with zero exit code. All other options
+ are ignored.
- -C option Output information about a specific build-time option, then
- exit. This functionality is intended for use in scripts such
- as RunTest. The following options output the value and set
+ -C option Output information about a specific build-time option, then
+ exit. This functionality is intended for use in scripts such
+ as RunTest. The following options output the value and set
the exit code as indicated:
ebcdic-nl the code for LF (= NL) in an EBCDIC environment:
@@ -107,7 +104,7 @@ COMMAND LINE OPTIONS
ANYCRLF or ANY
exit code is always 0
- The following options output 1 for true or 0 for false, and
+ The following options output 1 for true or 0 for false, and
set the exit code to the same value:
ebcdic compiled for an EBCDIC environment
@@ -119,61 +116,61 @@ COMMAND LINE OPTIONS
utf UTF-8 and/or UTF-16 and/or UTF-32 support
is available
- If an unknown option is given, an error message is output;
+ If an unknown option is given, an error message is output;
the exit code is 0.
- -d Behave as if each pattern has the /D (debug) modifier; the
- internal form and information about the compiled pattern is
+ -d Behave as if each pattern has the /D (debug) modifier; the
+ internal form and information about the compiled pattern is
output after compilation; -d is equivalent to -b -i.
- -dfa Behave as if each data line contains the \D escape sequence;
+ -dfa Behave as if each data line contains the \D escape sequence;
this causes the alternative matching function,
- pcre[16|32]_dfa_exec(), to be used instead of the standard
+ pcre[16|32]_dfa_exec(), to be used instead of the standard
pcre[16|32]_exec() function (more detail is given below).
-help Output a brief summary these options and then exit.
- -i Behave as if each pattern has the /I modifier; information
+ -i Behave as if each pattern has the /I modifier; information
about the compiled pattern is given after compilation.
- -M Behave as if each data line contains the \M escape sequence;
- this causes PCRE to discover the minimum MATCH_LIMIT and
- MATCH_LIMIT_RECURSION settings by calling pcre[16|32]_exec()
+ -M Behave as if each data line contains the \M escape sequence;
+ this causes PCRE to discover the minimum MATCH_LIMIT and
+ MATCH_LIMIT_RECURSION settings by calling pcre[16|32]_exec()
repeatedly with different limits.
- -m Output the size of each compiled pattern after it has been
- compiled. This is equivalent to adding /M to each regular
- expression. The size is given in bytes for both libraries.
+ -m Output the size of each compiled pattern after it has been
+ compiled. This is equivalent to adding /M to each regular ex-
+ pression. The size is given in bytes for both libraries.
- -O Behave as if each pattern has the /O modifier, that is dis-
+ -O Behave as if each pattern has the /O modifier, that is dis-
able auto-possessification for all patterns.
- -o osize Set the number of elements in the output vector that is used
- when calling pcre[16|32]_exec() or pcre[16|32]_dfa_exec() to
- be osize. The default value is 45, which is enough for 14
+ -o osize Set the number of elements in the output vector that is used
+ when calling pcre[16|32]_exec() or pcre[16|32]_dfa_exec() to
+ be osize. The default value is 45, which is enough for 14
capturing subexpressions for pcre[16|32]_exec() or 22 differ-
- ent matches for pcre[16|32]_dfa_exec(). The vector size can
- be changed for individual matching calls by including \O in
+ ent matches for pcre[16|32]_dfa_exec(). The vector size can
+ be changed for individual matching calls by including \O in
the data line (see below).
- -p Behave as if each pattern has the /P modifier; the POSIX
- wrapper API is used to call PCRE. None of the other options
- has any effect when -p is set. This option can be used only
+ -p Behave as if each pattern has the /P modifier; the POSIX
+ wrapper API is used to call PCRE. None of the other options
+ has any effect when -p is set. This option can be used only
with the 8-bit library.
- -q Do not output the version number of pcretest at the start of
+ -q Do not output the version number of pcretest at the start of
execution.
- -S size On Unix-like systems, set the size of the run-time stack to
+ -S size On Unix-like systems, set the size of the run-time stack to
size megabytes.
- -s or -s+ Behave as if each pattern has the /S modifier; in other
- words, force each pattern to be studied. If -s+ is used, all
- the JIT compile options are passed to pcre[16|32]_study(),
- causing just-in-time optimization to be set up if it is
- available, for both full and partial matching. Specific JIT
+ -s or -s+ Behave as if each pattern has the /S modifier; in other
+ words, force each pattern to be studied. If -s+ is used, all
+ the JIT compile options are passed to pcre[16|32]_study(),
+ causing just-in-time optimization to be set up if it is
+ available, for both full and partial matching. Specific JIT
compile options can be selected by following -s+ with a digit
- in the range 1 to 7, which selects the JIT compile modes as
+ in the range 1 to 7, which selects the JIT compile modes as
follows:
1 normal match only
@@ -183,119 +180,119 @@ COMMAND LINE OPTIONS
6 soft and hard partial match
7 all three modes (default)
- If -s++ is used instead of -s+ (with or without a following
- digit), the text "(JIT)" is added to the first output line
+ If -s++ is used instead of -s+ (with or without a following
+ digit), the text "(JIT)" is added to the first output line
after a match or no match when JIT-compiled code was actually
used.
- Note that there are pattern options that can override -s,
- either specifying no studying at all, or suppressing JIT com-
- pilation.
-
- If the /I or /D option is present on a pattern (requesting
- output about the compiled pattern), information about the
- result of studying is not included when studying is caused
- only by -s and neither -i nor -d is present on the command
- line. This behaviour means that the output from tests that
- are run with and without -s should be identical, except when
- options that output information about the actual running of a
- match are set.
-
- The -M, -t, and -tm options, which give information about
- resources used, are likely to produce different output with
- and without -s. Output may also differ if the /C option is
+ Note that there are pattern options that can override -s, ei-
+ ther specifying no studying at all, or suppressing JIT compi-
+ lation.
+
+ If the /I or /D option is present on a pattern (requesting
+ output about the compiled pattern), information about the re-
+ sult of studying is not included when studying is caused only
+ by -s and neither -i nor -d is present on the command line.
+ This behaviour means that the output from tests that are run
+ with and without -s should be identical, except when options
+ that output information about the actual running of a match
+ are set.
+
+ The -M, -t, and -tm options, which give information about re-
+ sources used, are likely to produce different output with and
+ without -s. Output may also differ if the /C option is
present on an individual pattern. This uses callouts to trace
- the the matching process, and this may be different between
- studied and non-studied patterns. If the pattern contains
- (*MARK) items there may also be differences, for the same
+ the the matching process, and this may be different between
+ studied and non-studied patterns. If the pattern contains
+ (*MARK) items there may also be differences, for the same
reason. The -s command line option can be overridden for spe-
- cific patterns that should never be studied (see the /S pat-
+ cific patterns that should never be studied (see the /S pat-
tern modifier below).
- -t Run each compile, study, and match many times with a timer,
- and output the resulting times per compile, study, or match
- (in milliseconds). Do not set -m with -t, because you will
+ -t Run each compile, study, and match many times with a timer,
+ and output the resulting times per compile, study, or match
+ (in milliseconds). Do not set -m with -t, because you will
then get the size output a zillion times, and the timing will
- be distorted. You can control the number of iterations that
+ be distorted. You can control the number of iterations that
are used for timing by following -t with a number (as a sepa-
- rate item on the command line). For example, "-t 1000" iter-
+ rate item on the command line). For example, "-t 1000" iter-
ates 1000 times. The default is to iterate 500000 times.
-tm This is like -t except that it times only the matching phase,
not the compile or study phases.
- -T -TM These behave like -t and -tm, but in addition, at the end of
+ -T -TM These behave like -t and -tm, but in addition, at the end of
a run, the total times for all compiles, studies, and matches
are output.
DESCRIPTION
- If pcretest is given two filename arguments, it reads from the first
+ If pcretest is given two filename arguments, it reads from the first
and writes to the second. If it is given only one filename argument, it
- reads from that file and writes to stdout. Otherwise, it reads from
- stdin and writes to stdout, and prompts for each line of input, using
+ reads from that file and writes to stdout. Otherwise, it reads from
+ stdin and writes to stdout, and prompts for each line of input, using
"re>" to prompt for regular expressions, and "data>" to prompt for data
lines.
- When pcretest is built, a configuration option can specify that it
- should be linked with the libreadline library. When this is done, if
+ When pcretest is built, a configuration option can specify that it
+ should be linked with the libreadline library. When this is done, if
the input is from a terminal, it is read using the readline() function.
- This provides line-editing and history facilities. The output from the
+ This provides line-editing and history facilities. The output from the
-help option states whether or not readline() will be used.
The program handles any number of sets of input on a single input file.
- Each set starts with a regular expression, and continues with any num-
+ Each set starts with a regular expression, and continues with any num-
ber of data lines to be matched against that pattern.
- Each data line is matched separately and independently. If you want to
+ Each data line is matched separately and independently. If you want to
do multi-line matches, you have to use the \n escape sequence (or \r or
\r\n, etc., depending on the newline setting) in a single line of input
- to encode the newline sequences. There is no limit on the length of
- data lines; the input buffer is automatically extended if it is too
+ to encode the newline sequences. There is no limit on the length of
+ data lines; the input buffer is automatically extended if it is too
small.
- An empty line signals the end of the data lines, at which point a new
- regular expression is read. The regular expressions are given enclosed
+ An empty line signals the end of the data lines, at which point a new
+ regular expression is read. The regular expressions are given enclosed
in any non-alphanumeric delimiters other than backslash, for example:
/(a|bc)x+yz/
- White space before the initial delimiter is ignored. A regular expres-
- sion may be continued over several input lines, in which case the new-
- line characters are included within it. It is possible to include the
+ White space before the initial delimiter is ignored. A regular expres-
+ sion may be continued over several input lines, in which case the new-
+ line characters are included within it. It is possible to include the
delimiter within the pattern by escaping it, for example
/abc\/def/
- If you do so, the escape and the delimiter form part of the pattern,
- but since delimiters are always non-alphanumeric, this does not affect
- its interpretation. If the terminating delimiter is immediately fol-
+ If you do so, the escape and the delimiter form part of the pattern,
+ but since delimiters are always non-alphanumeric, this does not affect
+ its interpretation. If the terminating delimiter is immediately fol-
lowed by a backslash, for example,
/abc/\
- then a backslash is added to the end of the pattern. This is done to
- provide a way of testing the error condition that arises if a pattern
+ then a backslash is added to the end of the pattern. This is done to
+ provide a way of testing the error condition that arises if a pattern
finishes with a backslash, because
/abc\/
- is interpreted as the first line of a pattern that starts with "abc/",
+ is interpreted as the first line of a pattern that starts with "abc/",
causing pcretest to read the next line as a continuation of the regular
expression.
PATTERN MODIFIERS
- A pattern may be followed by any number of modifiers, which are mostly
- single characters, though some of these can be qualified by further
- characters. Following Perl usage, these are referred to below as, for
- example, "the /i modifier", even though the delimiter of the pattern
- need not always be a slash, and no slash is used when writing modi-
- fiers. White space may appear between the final pattern delimiter and
- the first modifier, and between the modifiers themselves. For refer-
- ence, here is a complete list of modifiers. They fall into several
+ A pattern may be followed by any number of modifiers, which are mostly
+ single characters, though some of these can be qualified by further
+ characters. Following Perl usage, these are referred to below as, for
+ example, "the /i modifier", even though the delimiter of the pattern
+ need not always be a slash, and no slash is used when writing modi-
+ fiers. White space may appear between the final pattern delimiter and
+ the first modifier, and between the modifiers themselves. For refer-
+ ence, here is a complete list of modifiers. They fall into several
groups that are described in detail in the following sections.
/8 set UTF mode
@@ -347,8 +344,8 @@ PATTERN MODIFIERS
Perl-compatible modifiers
The /i, /m, /s, and /x modifiers set the PCRE_CASELESS, PCRE_MULTILINE,
- PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when
- pcre[16|32]_compile() is called. These four modifier letters have the
+ PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when
+ pcre[16|32]_compile() is called. These four modifier letters have the
same effect as they do in Perl. For example:
/caseless/i
@@ -356,7 +353,7 @@ PATTERN MODIFIERS
Modifiers for other PCRE options
- The following table shows additional modifiers for setting PCRE com-
+ The following table shows additional modifiers for setting PCRE com-
pile-time options that do not correspond to anything in Perl:
/8 PCRE_UTF8 ) when using the 8-bit
@@ -389,145 +386,145 @@ PATTERN MODIFIERS
/<bsr_unicode> PCRE_BSR_UNICODE
/<JS> PCRE_JAVASCRIPT_COMPAT
- The modifiers that are enclosed in angle brackets are literal strings
- as shown, including the angle brackets, but the letters within can be
- in either case. This example sets multiline matching with CRLF as the
+ The modifiers that are enclosed in angle brackets are literal strings
+ as shown, including the angle brackets, but the letters within can be
+ in either case. This example sets multiline matching with CRLF as the
line ending sequence:
/^abc/m<CRLF>
- As well as turning on the PCRE_UTF8/16/32 option, the /8 modifier
- causes all non-printing characters in output strings to be printed
- using the \x{hh...} notation. Otherwise, those less than 0x100 are out-
- put in hex without the curly brackets.
+ As well as turning on the PCRE_UTF8/16/32 option, the /8 modifier
+ causes all non-printing characters in output strings to be printed us-
+ ing the \x{hh...} notation. Otherwise, those less than 0x100 are output
+ in hex without the curly brackets.
- Full details of the PCRE options are given in the pcreapi documenta-
+ Full details of the PCRE options are given in the pcreapi documenta-
tion.
Finding all matches in a string
- Searching for all possible matches within each subject string can be
- requested by the /g or /G modifier. After finding a match, PCRE is
+ Searching for all possible matches within each subject string can be
+ requested by the /g or /G modifier. After finding a match, PCRE is
called again to search the remainder of the subject string. The differ-
ence between /g and /G is that the former uses the startoffset argument
- to pcre[16|32]_exec() to start searching at a new point within the
- entire string (which is in effect what Perl does), whereas the latter
- passes over a shortened substring. This makes a difference to the
- matching process if the pattern begins with a lookbehind assertion
- (including \b or \B).
-
- If any call to pcre[16|32]_exec() in a /g or /G sequence matches an
- empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
- PCRE_ANCHORED flags set in order to search for another, non-empty,
- match at the same point. If this second match fails, the start offset
- is advanced, and the normal match is retried. This imitates the way
+ to pcre[16|32]_exec() to start searching at a new point within the en-
+ tire string (which is in effect what Perl does), whereas the latter
+ passes over a shortened substring. This makes a difference to the
+ matching process if the pattern begins with a lookbehind assertion (in-
+ cluding \b or \B).
+
+ If any call to pcre[16|32]_exec() in a /g or /G sequence matches an
+ empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
+ PCRE_ANCHORED flags set in order to search for another, non-empty,
+ match at the same point. If this second match fails, the start offset
+ is advanced, and the normal match is retried. This imitates the way
Perl handles such cases when using the /g modifier or the split() func-
- tion. Normally, the start offset is advanced by one character, but if
- the newline convention recognizes CRLF as a newline, and the current
+ tion. Normally, the start offset is advanced by one character, but if
+ the newline convention recognizes CRLF as a newline, and the current
character is CR followed by LF, an advance of two is used.
Other modifiers
There are yet more modifiers for controlling the way pcretest operates.
- The /+ modifier requests that as well as outputting the substring that
- matched the entire pattern, pcretest should in addition output the
- remainder of the subject string. This is useful for tests where the
- subject contains multiple copies of the same substring. If the + modi-
- fier appears twice, the same action is taken for captured substrings.
- In each case the remainder is output on the following line with a plus
- character following the capture number. Note that this modifier must
- not immediately follow the /S modifier because /S+ and /S++ have other
+ The /+ modifier requests that as well as outputting the substring that
+ matched the entire pattern, pcretest should in addition output the re-
+ mainder of the subject string. This is useful for tests where the sub-
+ ject contains multiple copies of the same substring. If the + modifier
+ appears twice, the same action is taken for captured substrings. In
+ each case the remainder is output on the following line with a plus
+ character following the capture number. Note that this modifier must
+ not immediately follow the /S modifier because /S+ and /S++ have other
meanings.
- The /= modifier requests that the values of all potential captured
- parentheses be output after a match. By default, only those up to the
+ The /= modifier requests that the values of all potential captured
+ parentheses be output after a match. By default, only those up to the
highest one actually used in the match are output (corresponding to the
return code from pcre[16|32]_exec()). Values in the offsets vector cor-
- responding to higher numbers should be set to -1, and these are output
- as "<unset>". This modifier gives a way of checking that this is hap-
+ responding to higher numbers should be set to -1, and these are output
+ as "<unset>". This modifier gives a way of checking that this is hap-
pening.
- The /B modifier is a debugging feature. It requests that pcretest out-
- put a representation of the compiled code after compilation. Normally
- this information contains length and offset values; however, if /Z is
- also present, this data is replaced by spaces. This is a special fea-
- ture for use in the automatic test scripts; it ensures that the same
+ The /B modifier is a debugging feature. It requests that pcretest out-
+ put a representation of the compiled code after compilation. Normally
+ this information contains length and offset values; however, if /Z is
+ also present, this data is replaced by spaces. This is a special fea-
+ ture for use in the automatic test scripts; it ensures that the same
output is generated for different internal link sizes.
- The /D modifier is a PCRE debugging feature, and is equivalent to /BI,
+ The /D modifier is a PCRE debugging feature, and is equivalent to /BI,
that is, both the /B and the /I modifiers.
- The /F modifier causes pcretest to flip the byte order of the 2-byte
+ The /F modifier causes pcretest to flip the byte order of the 2-byte
and 4-byte fields in the compiled pattern. This facility is for testing
- the feature in PCRE that allows it to execute patterns that were com-
+ the feature in PCRE that allows it to execute patterns that were com-
piled on a host with a different endianness. This feature is not avail-
- able when the POSIX interface to PCRE is being used, that is, when the
+ able when the POSIX interface to PCRE is being used, that is, when the
/P pattern modifier is specified. See also the section about saving and
reloading compiled patterns below.
- The /I modifier requests that pcretest output information about the
- compiled pattern (whether it is anchored, has a fixed first character,
- and so on). It does this by calling pcre[16|32]_fullinfo() after com-
- piling a pattern. If the pattern is studied, the results of that are
+ The /I modifier requests that pcretest output information about the
+ compiled pattern (whether it is anchored, has a fixed first character,
+ and so on). It does this by calling pcre[16|32]_fullinfo() after com-
+ piling a pattern. If the pattern is studied, the results of that are
also output. In this output, the word "char" means a non-UTF character,
- that is, the value of a single data item (8-bit, 16-bit, or 32-bit,
- depending on the library that is being tested).
-
- The /K modifier requests pcretest to show names from backtracking con-
- trol verbs that are returned from calls to pcre[16|32]_exec(). It
- causes pcretest to create a pcre[16|32]_extra block if one has not
- already been created by a call to pcre[16|32]_study(), and to set the
- PCRE_EXTRA_MARK flag and the mark field within it, every time that
- pcre[16|32]_exec() is called. If the variable that the mark field
- points to is non-NULL for a match, non-match, or partial match,
- pcretest prints the string to which it points. For a match, this is
- shown on a line by itself, tagged with "MK:". For a non-match it is
+ that is, the value of a single data item (8-bit, 16-bit, or 32-bit, de-
+ pending on the library that is being tested).
+
+ The /K modifier requests pcretest to show names from backtracking con-
+ trol verbs that are returned from calls to pcre[16|32]_exec(). It
+ causes pcretest to create a pcre[16|32]_extra block if one has not al-
+ ready been created by a call to pcre[16|32]_study(), and to set the
+ PCRE_EXTRA_MARK flag and the mark field within it, every time that
+ pcre[16|32]_exec() is called. If the variable that the mark field
+ points to is non-NULL for a match, non-match, or partial match,
+ pcretest prints the string to which it points. For a match, this is
+ shown on a line by itself, tagged with "MK:". For a non-match it is
added to the message.
- The /L modifier must be followed directly by the name of a locale, for
+ The /L modifier must be followed directly by the name of a locale, for
example,
/pattern/Lfr_FR
For this reason, it must be the last modifier. The given locale is set,
- pcre[16|32]_maketables() is called to build a set of character tables
- for the locale, and this is then passed to pcre[16|32]_compile() when
- compiling the regular expression. Without an /L (or /T) modifier, NULL
- is passed as the tables pointer; that is, /L applies only to the
- expression on which it appears.
-
- The /M modifier causes the size in bytes of the memory block used to
- hold the compiled pattern to be output. This does not include the size
- of the pcre[16|32] block; it is just the actual compiled data. If the
+ pcre[16|32]_maketables() is called to build a set of character tables
+ for the locale, and this is then passed to pcre[16|32]_compile() when
+ compiling the regular expression. Without an /L (or /T) modifier, NULL
+ is passed as the tables pointer; that is, /L applies only to the ex-
+ pression on which it appears.
+
+ The /M modifier causes the size in bytes of the memory block used to
+ hold the compiled pattern to be output. This does not include the size
+ of the pcre[16|32] block; it is just the actual compiled data. If the
pattern is successfully studied with the PCRE_STUDY_JIT_COMPILE option,
the size of the JIT compiled code is also output.
The /Q modifier is used to test the use of pcre_stack_guard. It must be
- followed by '0' or '1', specifying the return code to be given from an
- external function that is passed to PCRE and used for stack checking
+ followed by '0' or '1', specifying the return code to be given from an
+ external function that is passed to PCRE and used for stack checking
during compilation (see the pcreapi documentation for details).
- The /S modifier causes pcre[16|32]_study() to be called after the
- expression has been compiled, and the results used when the expression
- is matched. There are a number of qualifying characters that may follow
+ The /S modifier causes pcre[16|32]_study() to be called after the ex-
+ pression has been compiled, and the results used when the expression is
+ matched. There are a number of qualifying characters that may follow
/S. They may appear in any order.
If /S is followed by an exclamation mark, pcre[16|32]_study() is called
- with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a
+ with the PCRE_STUDY_EXTRA_NEEDED option, causing it always to return a
pcre_extra block, even when studying discovers no useful information.
If /S is followed by a second S character, it suppresses studying, even
- if it was requested externally by the -s command line option. This
- makes it possible to specify that certain patterns are always studied,
+ if it was requested externally by the -s command line option. This
+ makes it possible to specify that certain patterns are always studied,
and others are never studied, independently of -s. This feature is used
in the test files in a few cases where the output is different when the
pattern is studied.
- If the /S modifier is followed by a + character, the call to
- pcre[16|32]_study() is made with all the JIT study options, requesting
- just-in-time optimization support if it is available, for both normal
- and partial matching. If you want to restrict the JIT compiling modes,
+ If the /S modifier is followed by a + character, the call to
+ pcre[16|32]_study() is made with all the JIT study options, requesting
+ just-in-time optimization support if it is available, for both normal
+ and partial matching. If you want to restrict the JIT compiling modes,
you can follow /S+ with a digit in the range 1 to 7:
1 normal match only
@@ -538,40 +535,40 @@ PATTERN MODIFIERS
7 all three modes (default)
If /S++ is used instead of /S+ (with or without a following digit), the
- text "(JIT)" is added to the first output line after a match or no
+ text "(JIT)" is added to the first output line after a match or no
match when JIT-compiled code was actually used.
- Note that there is also an independent /+ modifier; it must not be
+ Note that there is also an independent /+ modifier; it must not be
given immediately after /S or /S+ because this will be misinterpreted.
If JIT studying is successful, the compiled JIT code will automatically
- be used when pcre[16|32]_exec() is run, except when incompatible run-
- time options are specified. For more details, see the pcrejit documen-
- tation. See also the \J escape sequence below for a way of setting the
+ be used when pcre[16|32]_exec() is run, except when incompatible run-
+ time options are specified. For more details, see the pcrejit documen-
+ tation. See also the \J escape sequence below for a way of setting the
size of the JIT stack.
- Finally, if /S is followed by a minus character, JIT compilation is
- suppressed, even if it was requested externally by the -s command line
- option. This makes it possible to specify that JIT is never to be used
+ Finally, if /S is followed by a minus character, JIT compilation is
+ suppressed, even if it was requested externally by the -s command line
+ option. This makes it possible to specify that JIT is never to be used
for certain patterns.
- The /T modifier must be followed by a single digit. It causes a spe-
+ The /T modifier must be followed by a single digit. It causes a spe-
cific set of built-in character tables to be passed to pcre[16|32]_com-
- pile(). It is used in the standard PCRE tests to check behaviour with
+ pile(). It is used in the standard PCRE tests to check behaviour with
different character tables. The digit specifies the tables as follows:
0 the default ASCII tables, as distributed in
pcre_chartables.c.dist
1 a set of tables defining ISO 8859 characters
- In table 1, some characters whose codes are greater than 128 are iden-
+ In table 1, some characters whose codes are greater than 128 are iden-
tified as letters, digits, spaces, etc.
Using the POSIX wrapper API
- The /P modifier causes pcretest to call PCRE via the POSIX wrapper API
- rather than its native API. This supports only the 8-bit library. When
- /P is set, the following modifiers set options for the regcomp() func-
+ The /P modifier causes pcretest to call PCRE via the POSIX wrapper API
+ rather than its native API. This supports only the 8-bit library. When
+ /P is set, the following modifiers set options for the regcomp() func-
tion:
/i REG_ICASE
@@ -582,48 +579,48 @@ PATTERN MODIFIERS
/W REG_UCP ) the POSIX standard
/8 REG_UTF8 )
- The /+ modifier works as described above. All other modifiers are
- ignored.
+ The /+ modifier works as described above. All other modifiers are ig-
+ nored.
Locking out certain modifiers
- PCRE can be compiled with or without support for certain features such
- as UTF-8/16/32 or Unicode properties. Accordingly, the standard tests
- are split up into a number of different files that are selected for
- running depending on which features are available. When updating the
+ PCRE can be compiled with or without support for certain features such
+ as UTF-8/16/32 or Unicode properties. Accordingly, the standard tests
+ are split up into a number of different files that are selected for
+ running depending on which features are available. When updating the
tests, it is all too easy to put a new test into the wrong file by mis-
- take; for example, to put a test that requires UTF support into a file
- that is used when it is not available. To help detect such mistakes as
- early as possible, there is a facility for locking out specific modi-
+ take; for example, to put a test that requires UTF support into a file
+ that is used when it is not available. To help detect such mistakes as
+ early as possible, there is a facility for locking out specific modi-
fiers. If an input line for pcretest starts with the string "< forbid "
- the following sequence of characters is taken as a list of forbidden
+ the following sequence of characters is taken as a list of forbidden
modifiers. For example, in the test files that must not use UTF or Uni-
code property support, this line appears:
< forbid 8W
- This locks out the /8 and /W modifiers. An immediate error is given if
- they are subsequently encountered. If the character string contains <
- but not >, all the multi-character modifiers that begin with < are
- locked out. Otherwise, such modifiers must be explicitly listed, for
+ This locks out the /8 and /W modifiers. An immediate error is given if
+ they are subsequently encountered. If the character string contains <
+ but not >, all the multi-character modifiers that begin with < are
+ locked out. Otherwise, such modifiers must be explicitly listed, for
example:
< forbid <JS><cr>
There must be a single space between < and "forbid" for this feature to
- be recognised. If there is not, the line is interpreted either as a
- request to re-load a pre-compiled pattern (see "SAVING AND RELOADING
- COMPILED PATTERNS" below) or, if there is a another < character, as a
- pattern that uses < as its delimiter.
+ be recognised. If there is not, the line is interpreted either as a re-
+ quest to re-load a pre-compiled pattern (see "SAVING AND RELOADING COM-
+ PILED PATTERNS" below) or, if there is a another < character, as a pat-
+ tern that uses < as its delimiter.
DATA LINES
- Before each data line is passed to pcre[16|32]_exec(), leading and
- trailing white space is removed, and it is then scanned for \ escapes.
- Some of these are pretty esoteric features, intended for checking out
- some of the more complicated features of PCRE. If you are just testing
- "ordinary" regular expressions, you probably don't need any of these.
+ Before each data line is passed to pcre[16|32]_exec(), leading and
+ trailing white space is removed, and it is then scanned for \ escapes.
+ Some of these are pretty esoteric features, intended for checking out
+ some of the more complicated features of PCRE. If you are just testing
+ "ordinary" regular expressions, you probably don't need any of these.
The following escapes are recognized:
\a alarm (BEL, \x07)
@@ -684,7 +681,7 @@ DATA LINES
(any number of digits)
\R pass the PCRE_DFA_RESTART option to pcre[16|32]_dfa_exec()
\S output details of memory get/free calls during matching
- \Y pass the PCRE_NO_START_OPTIMIZE option to
+ \Y pass the PCRE_NO_START_OPTIMIZE option to
pcre[16|32]_exec()
or pcre[16|32]_dfa_exec()
\Z pass the PCRE_NOTEOL option to pcre[16|32]_exec()
@@ -693,7 +690,7 @@ DATA LINES
pcre[16|32]_exec() or pcre[16|32]_dfa_exec()
\>dd start the match at offset dd (optional "-"; then
any number of digits); this sets the startoffset
- argument for pcre[16|32]_exec() or
+ argument for pcre[16|32]_exec() or
pcre[16|32]_dfa_exec()
\<cr> pass the PCRE_NEWLINE_CR option to pcre[16|32]_exec()
or pcre[16|32]_dfa_exec()
@@ -706,103 +703,102 @@ DATA LINES
\<any> pass the PCRE_NEWLINE_ANY option to pcre[16|32]_exec()
or pcre[16|32]_dfa_exec()
- The use of \x{hh...} is not dependent on the use of the /8 modifier on
- the pattern. It is recognized always. There may be any number of hexa-
- decimal digits inside the braces; invalid values provoke error mes-
+ The use of \x{hh...} is not dependent on the use of the /8 modifier on
+ the pattern. It is recognized always. There may be any number of hexa-
+ decimal digits inside the braces; invalid values provoke error mes-
sages.
- Note that \xhh specifies one byte rather than one character in UTF-8
- mode; this makes it possible to construct invalid UTF-8 sequences for
- testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
- character in UTF-8 mode, generating more than one byte if the value is
- greater than 127. When testing the 8-bit library not in UTF-8 mode,
+ Note that \xhh specifies one byte rather than one character in UTF-8
+ mode; this makes it possible to construct invalid UTF-8 sequences for
+ testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
+ character in UTF-8 mode, generating more than one byte if the value is
+ greater than 127. When testing the 8-bit library not in UTF-8 mode,
\x{hh} generates one byte for values less than 256, and causes an error
for greater values.
In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it
possible to construct invalid UTF-16 sequences for testing purposes.
- In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This
- makes it possible to construct invalid UTF-32 sequences for testing
+ In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This
+ makes it possible to construct invalid UTF-32 sequences for testing
purposes.
- The escapes that specify line ending sequences are literal strings,
- exactly as shown. No more than one newline setting should be present in
+ The escapes that specify line ending sequences are literal strings, ex-
+ actly as shown. No more than one newline setting should be present in
any data line.
- A backslash followed by anything else just escapes the anything else.
- If the very last character is a backslash, it is ignored. This gives a
- way of passing an empty line as data, since a real empty line termi-
+ A backslash followed by anything else just escapes the anything else.
+ If the very last character is a backslash, it is ignored. This gives a
+ way of passing an empty line as data, since a real empty line termi-
nates the data input.
- The \J escape provides a way of setting the maximum stack size that is
- used by the just-in-time optimization code. It is ignored if JIT opti-
- mization is not being used. Providing a stack that is larger than the
+ The \J escape provides a way of setting the maximum stack size that is
+ used by the just-in-time optimization code. It is ignored if JIT opti-
+ mization is not being used. Providing a stack that is larger than the
default 32K is necessary only for very complicated patterns.
If \M is present, pcretest calls pcre[16|32]_exec() several times, with
different values in the match_limit and match_limit_recursion fields of
- the pcre[16|32]_extra data structure, until it finds the minimum num-
+ the pcre[16|32]_extra data structure, until it finds the minimum num-
bers for each parameter that allow pcre[16|32]_exec() to complete with-
- out error. Because this is testing a specific feature of the normal
- interpretive pcre[16|32]_exec() execution, the use of any JIT optimiza-
- tion that might have been set up by the /S+ qualifier of -s+ option is
+ out error. Because this is testing a specific feature of the normal in-
+ terpretive pcre[16|32]_exec() execution, the use of any JIT optimiza-
+ tion that might have been set up by the /S+ qualifier of -s+ option is
disabled.
- The match_limit number is a measure of the amount of backtracking that
- takes place, and checking it out can be instructive. For most simple
- matches, the number is quite small, but for patterns with very large
- numbers of matching possibilities, it can become large very quickly
- with increasing length of subject string. The match_limit_recursion
- number is a measure of how much stack (or, if PCRE is compiled with
- NO_RECURSE, how much heap) memory is needed to complete the match
- attempt.
+ The match_limit number is a measure of the amount of backtracking that
+ takes place, and checking it out can be instructive. For most simple
+ matches, the number is quite small, but for patterns with very large
+ numbers of matching possibilities, it can become large very quickly
+ with increasing length of subject string. The match_limit_recursion
+ number is a measure of how much stack (or, if PCRE is compiled with
+ NO_RECURSE, how much heap) memory is needed to complete the match at-
+ tempt.
- When \O is used, the value specified may be higher or lower than the
+ When \O is used, the value specified may be higher or lower than the
size set by the -O command line option (or defaulted to 45); \O applies
- only to the call of pcre[16|32]_exec() for the line in which it
- appears.
+ only to the call of pcre[16|32]_exec() for the line in which it ap-
+ pears.
- If the /P modifier was present on the pattern, causing the POSIX wrap-
- per API to be used, the only option-setting sequences that have any
- effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and
- REG_NOTEOL, respectively, to be passed to regexec().
+ If the /P modifier was present on the pattern, causing the POSIX wrap-
+ per API to be used, the only option-setting sequences that have any ef-
+ fect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NO-
+ TEOL, respectively, to be passed to regexec().
THE ALTERNATIVE MATCHING FUNCTION
- By default, pcretest uses the standard PCRE matching function,
- pcre[16|32]_exec() to match each data line. PCRE also supports an
- alternative matching function, pcre[16|32]_dfa_test(), which operates
- in a different way, and has some restrictions. The differences between
- the two functions are described in the pcrematching documentation.
+ By default, pcretest uses the standard PCRE matching function,
+ pcre[16|32]_exec() to match each data line. PCRE also supports an al-
+ ternative matching function, pcre[16|32]_dfa_test(), which operates in
+ a different way, and has some restrictions. The differences between the
+ two functions are described in the pcrematching documentation.
- If a data line contains the \D escape sequence, or if the command line
- contains the -dfa option, the alternative matching function is used.
+ If a data line contains the \D escape sequence, or if the command line
+ contains the -dfa option, the alternative matching function is used.
This function finds all possible matches at a given point. If, however,
- the \F escape sequence is present in the data line, it stops after the
+ the \F escape sequence is present in the data line, it stops after the
first match is found. This is always the shortest possible match.
DEFAULT OUTPUT FROM PCRETEST
- This section describes the output when the normal matching function,
+ This section describes the output when the normal matching function,
pcre[16|32]_exec(), is being used.
When a match succeeds, pcretest outputs the list of captured substrings
- that pcre[16|32]_exec() returns, starting with number 0 for the string
- that matched the whole pattern. Otherwise, it outputs "No match" when
- the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the
- partially matching substring when pcre[16|32]_exec() returns
- PCRE_ERROR_PARTIAL. (Note that this is the entire substring that was
- inspected during the partial match; it may include characters before
- the actual match start if a lookbehind assertion, \K, \b, or \B was
- involved.) For any other return, pcretest outputs the PCRE negative
- error number and a short descriptive phrase. If the error is a failed
- UTF string check, the offset of the start of the failing character and
- the reason code are also output, provided that the size of the output
- vector is at least two. Here is an example of an interactive pcretest
- run.
+ that pcre[16|32]_exec() returns, starting with number 0 for the string
+ that matched the whole pattern. Otherwise, it outputs "No match" when
+ the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the
+ partially matching substring when pcre[16|32]_exec() returns PCRE_ER-
+ ROR_PARTIAL. (Note that this is the entire substring that was inspected
+ during the partial match; it may include characters before the actual
+ match start if a lookbehind assertion, \K, \b, or \B was involved.) For
+ any other return, pcretest outputs the PCRE negative error number and a
+ short descriptive phrase. If the error is a failed UTF string check,
+ the offset of the start of the failing character and the reason code
+ are also output, provided that the size of the output vector is at
+ least two. Here is an example of an interactive pcretest run.
$ pcretest
PCRE version 8.13 2011-04-30
@@ -892,9 +888,9 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
(Using the normal matching function on this data finds only "tang".)
The longest matching string is always given first (and numbered zero).
After a PCRE_ERROR_PARTIAL return, the output is "Partial match:", fol-
- lowed by the partially matching substring. (Note that this is the
- entire substring that was inspected during the partial match; it may
- include characters before the actual match start if a lookbehind asser-
+ lowed by the partially matching substring. (Note that this is the en-
+ tire substring that was inspected during the partial match; it may in-
+ clude characters before the actual match start if a lookbehind asser-
tion, \K, \b, or \B was involved.)
If /g is present on the pattern, the search for further matches resumes
@@ -909,9 +905,9 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
1: tan
0: tan
- Since the matching function does not support substring capture, the
- escape sequences that are concerned with captured substrings are not
- relevant.
+ Since the matching function does not support substring capture, the es-
+ cape sequences that are concerned with captured substrings are not rel-
+ evant.
RESTARTING AFTER A PARTIAL MATCH
@@ -942,9 +938,9 @@ CALLOUTS
--->pqrabcdef
0 ^ ^ \d
- This output indicates that callout number 0 occurred for a match
- attempt starting at the fourth character of the subject string, when
- the pointer was at the seventh character of the data, and when the next
+ This output indicates that callout number 0 occurred for a match at-
+ tempt starting at the fourth character of the subject string, when the
+ pointer was at the seventh character of the data, and when the next
pattern item was \d. Just one circumflex is output if the start and
current positions are the same.
@@ -963,8 +959,8 @@ CALLOUTS
0: E*
If a pattern contains (*MARK) items, an additional line is output when-
- ever a change of latest mark is passed to the callout function. For
- example:
+ ever a change of latest mark is passed to the callout function. For ex-
+ ample:
re> /a(*MARK:X)bc/C
data> abc
@@ -999,8 +995,8 @@ NON-PRINTING CHARACTERS
When pcretest is outputting text that is a matched part of a subject
string, it behaves in the same way, unless a different locale has been
- set for the pattern (using the /L modifier). In this case, the
- isprint() function to distinguish printing and non-printing characters.
+ set for the pattern (using the /L modifier). In this case, the is-
+ print() function to distinguish printing and non-printing characters.
SAVING AND RELOADING COMPILED PATTERNS
@@ -1020,14 +1016,14 @@ SAVING AND RELOADING COMPILED PATTERNS
studied with JIT optimization, the JIT data cannot be saved.
The data that is written is binary. The first eight bytes are the
- length of the compiled pattern data followed by the length of the
- optional study data, each written as four bytes in big-endian order
- (most significant byte first). If there is no study data (either the
- pattern was not studied, or studying did not return any data), the sec-
- ond length is zero. The lengths are followed by an exact copy of the
- compiled pattern. If there is additional study data, this (excluding
- any JIT data) follows immediately after the compiled pattern. After
- writing the file, pcretest expects to read a new pattern.
+ length of the compiled pattern data followed by the length of the op-
+ tional study data, each written as four bytes in big-endian order (most
+ significant byte first). If there is no study data (either the pattern
+ was not studied, or studying did not return any data), the second
+ length is zero. The lengths are followed by an exact copy of the com-
+ piled pattern. If there is additional study data, this (excluding any
+ JIT data) follows immediately after the compiled pattern. After writing
+ the file, pcretest expects to read a new pattern.
A saved pattern can be reloaded into pcretest by specifying < and a
file name instead of a pattern. There must be no space between < and
@@ -1066,10 +1062,10 @@ SAVING AND RELOADING COMPILED PATTERNS
ing and experimentation. It is not intended for production use because
only a single pattern can be written to a file. Furthermore, there is
no facility for supplying custom character tables for use with a
- reloaded pattern. If the original pattern was compiled with custom
- tables, an attempt to match a subject string using a reloaded pattern
- is likely to cause pcretest to crash. Finally, if you attempt to load
- a file that is not in the correct format, the result is undefined.
+ reloaded pattern. If the original pattern was compiled with custom ta-
+ bles, an attempt to match a subject string using a reloaded pattern is
+ likely to cause pcretest to crash. Finally, if you attempt to load a
+ file that is not in the correct format, the result is undefined.
SEE ALSO
@@ -1087,5 +1083,5 @@ AUTHOR
REVISION
- Last updated: 23 February 2017
- Copyright (c) 1997-2017 University of Cambridge.
+ Last updated: 10 February 2020
+ Copyright (c) 1997-2020 University of Cambridge.
diff --git a/pcre/pcre_compile.c b/pcre/pcre_compile.c
index 734875de2fb..cc174044545 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-2018 University of Cambridge
+ Copyright (c) 1997-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -68,7 +68,7 @@ COMPILE_PCREx macro will already be appropriately set. */
/* Macro for setting individual bits in class bitmaps. */
-#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7))
+#define SETBIT(a,b) a[(b)/8] |= (1U << ((b)&7))
/* Maximum length value to check against when making sure that the integer that
holds the compiled pattern length does not overflow. We make it a bit less than
@@ -129,8 +129,8 @@ overrun before it actually does run off the end of the data block. */
/* Private flags added to firstchar and reqchar. */
-#define REQ_CASELESS (1 << 0) /* Indicates caselessness */
-#define REQ_VARY (1 << 1) /* Reqchar followed non-literal item */
+#define REQ_CASELESS (1U << 0) /* Indicates caselessness */
+#define REQ_VARY (1U << 1) /* Reqchar followed non-literal item */
/* Negative values for the firstchar and reqchar flags */
#define REQ_UNSET (-2)
#define REQ_NONE (-1)
@@ -3612,7 +3612,7 @@ for(;;)
if (chr > 255) break;
class_bitset = (pcre_uint8 *)
((list_ptr == list ? code : base_end) - list_ptr[2]);
- if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE;
+ if ((class_bitset[chr >> 3] & (1U << (chr & 7))) != 0) return FALSE;
break;
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
@@ -7133,17 +7133,19 @@ for (;; ptr++)
int n = 0;
ptr++;
while(IS_DIGIT(*ptr))
+ {
n = n * 10 + *ptr++ - CHAR_0;
+ if (n > 255)
+ {
+ *errorcodeptr = ERR38;
+ goto FAILED;
+ }
+ }
if (*ptr != CHAR_RIGHT_PARENTHESIS)
{
*errorcodeptr = ERR39;
goto FAILED;
}
- if (n > 255)
- {
- *errorcodeptr = ERR38;
- goto FAILED;
- }
*code++ = n;
PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
PUT(code, LINK_SIZE, 0); /* Default length */
@@ -7459,7 +7461,7 @@ for (;; ptr++)
{
open_capitem *oc;
recno = GET2(slot, 0);
- cd->backref_map |= (recno < 32)? (1 << recno) : 1;
+ cd->backref_map |= (recno < 32)? (1U << recno) : 1;
if (recno > cd->top_backref) cd->top_backref = recno;
/* Check to see if this back reference is recursive, that it, it
@@ -8070,7 +8072,7 @@ for (;; ptr++)
item_hwm_offset = cd->hwm - cd->start_workspace;
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
PUT2INC(code, 0, recno);
- cd->backref_map |= (recno < 32)? (1 << recno) : 1;
+ cd->backref_map |= (recno < 32)? (1U << recno) : 1;
if (recno > cd->top_backref) cd->top_backref = recno;
/* Check to see if this back reference is recursive, that it, it
@@ -8683,7 +8685,7 @@ do {
op == OP_SCBRA || op == OP_SCBRAPOS)
{
int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+ int new_map = bracket_map | ((n < 32)? (1U << n) : 1);
if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE;
}
@@ -8811,7 +8813,7 @@ do {
op == OP_SCBRA || op == OP_SCBRAPOS)
{
int n = GET2(scode, 1+LINK_SIZE);
- int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+ int new_map = bracket_map | ((n < 32)? (1U << n) : 1);
if (!is_startline(scode, new_map, cd, atomcount, inassert)) return FALSE;
}
diff --git a/pcre/pcre_jit_compile.c b/pcre/pcre_jit_compile.c
index bc5f9c01433..4dcf8fc2189 100644
--- a/pcre/pcre_jit_compile.c
+++ b/pcre/pcre_jit_compile.c
@@ -3938,10 +3938,10 @@ 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;
+return ((unsigned int)value << 24) | ((unsigned int)value << 16) | ((unsigned int)value << 8) | (unsigned int)value;
#elif defined COMPILE_PCRE16
#define SSE2_COMPARE_TYPE_INDEX 1
-return (value << 16) | value;
+return ((unsigned int)value << 16) | value;
#elif defined COMPILE_PCRE32
#define SSE2_COMPARE_TYPE_INDEX 2
return value;
@@ -8507,7 +8507,7 @@ 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);
+ BACKTRACK_AS(bracket_backtrack)->u.framesize = ((unsigned int)BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
}
return cc + repeat_length;
}
diff --git a/pcre/pcrecpp.cc b/pcre/pcrecpp.cc
index 77a2fedc4be..ce289afafb8 100644
--- a/pcre/pcrecpp.cc
+++ b/pcre/pcrecpp.cc
@@ -66,7 +66,8 @@ 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__) && !defined(__INTEL_COMPILER)
+#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) \
+ && !defined(__INTEL_COMPILER) && !defined(__LCC__)
# 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__)
@@ -91,6 +92,7 @@ static const char *start_options[] = {
"(*LIMIT_RECURSION=",
"(*LIMIT_MATCH=",
"(*CRLF)",
+ "(*LF)",
"(*CR)",
"(*BSR_UNICODE)",
"(*BSR_ANYCRLF)",
diff --git a/pcre/pcreposix.c b/pcre/pcreposix.c
index a76d6bfca45..3042d763539 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-2018 University of Cambridge
+ Copyright (c) 1997-2020 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -298,6 +298,7 @@ if (preg->re_pcre == NULL)
(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT,
&re_nsub);
preg->re_nsub = (size_t)re_nsub;
+preg->re_erroffset = (size_t)(-1); /* No meaning after successful compile */
return 0;
}
@@ -335,8 +336,6 @@ if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE_NOTEMPTY;
-((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */
-
/* When no string data is being returned, or no vector has been passed in which
to put it, ensure that nmatch is zero. Otherwise, ensure the vector for holding
the return data is large enough. */
diff --git a/pcre/pcretest.c b/pcre/pcretest.c
index f1303037281..c1ee128b61f 100644
--- a/pcre/pcretest.c
+++ b/pcre/pcretest.c
@@ -500,7 +500,7 @@ enum {
#if (defined (SUPPORT_PCRE8) + defined (SUPPORT_PCRE16) + \
defined (SUPPORT_PCRE32)) >= 2
-#define CHAR_SIZE (1 << pcre_mode)
+#define CHAR_SIZE (1U << pcre_mode)
/* There doesn't seem to be an easy way of writing these macros that can cope
with the 3 pairs of bit sizes plus all three bit sizes. So just handle all the
@@ -4443,7 +4443,7 @@ while (!done)
/* If there is study data, write it. */
- if (extra != NULL)
+ if (extra != NULL && (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0)
{
if (fwrite(extra->study_data, 1, true_study_size, f) <
true_study_size)
@@ -4735,7 +4735,7 @@ while (!done)
if (isdigit(*p)) /* Set copy string */
{
while(isdigit(*p)) n = n * 10 + *p++ - '0';
- copystrings |= 1 << n;
+ copystrings |= 1U << n;
}
else if (isalnum(*p))
{
@@ -4798,7 +4798,7 @@ while (!done)
if (isdigit(*p))
{
while(isdigit(*p)) n = n * 10 + *p++ - '0';
- getstrings |= 1 << n;
+ getstrings |= 1U << n;
}
else if (isalnum(*p))
{
@@ -5335,7 +5335,7 @@ while (!done)
for (i = 0; i < 32; i++)
{
- if ((copystrings & (1 << i)) != 0)
+ if ((copystrings & (1U << i)) != 0)
{
int rc;
char copybuffer[256];
@@ -5400,7 +5400,7 @@ while (!done)
for (i = 0; i < 32; i++)
{
- if ((getstrings & (1 << i)) != 0)
+ if ((getstrings & (1U << i)) != 0)
{
int rc;
const char *substring;
diff --git a/pcre/testdata/testinput2 b/pcre/testdata/testinput2
index 3528de153eb..53c9825ae08 100644
--- a/pcre/testdata/testinput2
+++ b/pcre/testdata/testinput2
@@ -1380,7 +1380,7 @@
1X
123456\P
-//KF>testsavedregex
+//S-KF>testsavedregex
/abc/IS>testsavedregex
<testsavedregex
diff --git a/pcre/testdata/testoutput2 b/pcre/testdata/testoutput2
index 4ccda272010..f5d32d6ad0d 100644
--- a/pcre/testdata/testoutput2
+++ b/pcre/testdata/testoutput2
@@ -5614,9 +5614,8 @@ No match
123456\P
No match
-//KF>testsavedregex
+//S-KF>testsavedregex
Compiled pattern written to testsavedregex
-Study data written to testsavedregex
/abc/IS>testsavedregex
Capturing subpattern count = 0
diff --git a/plugin/auth_gssapi/CMakeLists.txt b/plugin/auth_gssapi/CMakeLists.txt
index 7d9e58e165f..c708606856d 100644
--- a/plugin/auth_gssapi/CMakeLists.txt
+++ b/plugin/auth_gssapi/CMakeLists.txt
@@ -21,9 +21,9 @@ ELSE()
SET(CMAKE_REQUIRED_INCLUDES ${GSSAPI_INCS})
SET(CMAKE_REQUIRED_LIBRARIES ${GSSAPI_LIBS})
INCLUDE(CheckCXXSymbolExists)
- CHECK_CXX_SYMBOL_EXISTS(krb5_free_unparsed_name "krb5.h" HAVE_KRB5_FREE_UNPARSED_NAME)
- IF(HAVE_KRB5_FREE_UNPARSED_NAME)
- ADD_DEFINITIONS(-DHAVE_KRB5_FREE_UNPARSED_NAME=1)
+ CHECK_CXX_SYMBOL_EXISTS(krb5_xfree "krb5.h" HAVE_KRB5_XFREE)
+ IF(HAVE_KRB5_XFREE)
+ ADD_DEFINITIONS(-DHAVE_KRB5_XFREE=1)
ENDIF()
ELSE()
diff --git a/plugin/auth_gssapi/gssapi_server.cc b/plugin/auth_gssapi/gssapi_server.cc
index 50c34ecc573..c1c4fa13e00 100644
--- a/plugin/auth_gssapi/gssapi_server.cc
+++ b/plugin/auth_gssapi/gssapi_server.cc
@@ -31,7 +31,7 @@ static void log_error( OM_uint32 major, OM_uint32 minor, const char *msg)
Generate default principal service name formatted as principal name "mariadb/server.fqdn@REALM"
*/
#include <krb5.h>
-#ifndef HAVE_KRB5_FREE_UNPARSED_NAME
+#ifdef HAVE_KRB5_XFREE
#define krb5_free_unparsed_name(a,b) krb5_xfree(b)
#endif
static char* get_default_principal_name()
diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc
index c4b558ba107..e3b0e96c2e7 100644
--- a/plugin/disks/information_schema_disks.cc
+++ b/plugin/disks/information_schema_disks.cc
@@ -32,9 +32,9 @@ ST_FIELD_INFO disks_table_fields[]=
{
{ "Disk", PATH_MAX, MYSQL_TYPE_STRING, 0, 0 ,0, 0 },
{ "Path", PATH_MAX, MYSQL_TYPE_STRING, 0, 0 ,0, 0 },
- { "Total", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Total amount available
- { "Used", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Amount of space used
- { "Available", 32, MYSQL_TYPE_LONG, 0, 0 ,0 ,0 }, // Amount available to users other than root.
+ { "Total", 32, MYSQL_TYPE_LONGLONG, 0, 0 ,0 ,0 }, // Total amount available
+ { "Used", 32, MYSQL_TYPE_LONGLONG, 0, 0 ,0 ,0 }, // Amount of space used
+ { "Available", 32, MYSQL_TYPE_LONGLONG, 0, 0 ,0 ,0 }, // Amount available to users other than root.
{ 0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0 }
};
@@ -51,9 +51,10 @@ int disks_table_add_row(THD* pThd,
// f_bfree Total number of free blocks.
// f_bavail Number of free blocks available to non-privileged process.
- size_t total = (info.f_frsize * info.f_blocks) / 1024;
- size_t used = (info.f_frsize * (info.f_blocks - info.f_bfree)) / 1024;
- size_t avail = (info.f_frsize * info.f_bavail) / 1024;
+ ulonglong total = ((ulonglong)info.f_frsize * info.f_blocks) / 1024;
+ ulonglong used = ((ulonglong)info.f_frsize *
+ (info.f_blocks - info.f_bfree)) / 1024;
+ ulonglong avail = ((ulonglong)info.f_frsize * info.f_bavail) / 1024;
pTable->field[0]->store(zDisk, strlen(zDisk), system_charset_info);
pTable->field[1]->store(zPath, strlen(zPath), system_charset_info);
diff --git a/plugin/disks/mysql-test/disks/disks.result b/plugin/disks/mysql-test/disks/disks.result
index bd6befc5e11..156eed29452 100644
--- a/plugin/disks/mysql-test/disks/disks.result
+++ b/plugin/disks/mysql-test/disks/disks.result
@@ -3,9 +3,9 @@ Table Create Table
DISKS CREATE TEMPORARY TABLE `DISKS` (
`Disk` varchar(4096) NOT NULL DEFAULT '',
`Path` varchar(4096) NOT NULL DEFAULT '',
- `Total` int(32) NOT NULL DEFAULT '0',
- `Used` int(32) NOT NULL DEFAULT '0',
- `Available` int(32) NOT NULL DEFAULT '0'
+ `Total` bigint(32) NOT NULL DEFAULT '0',
+ `Used` bigint(32) NOT NULL DEFAULT '0',
+ `Available` bigint(32) NOT NULL DEFAULT '0'
) ENGINE=MEMORY DEFAULT CHARSET=utf8
select sum(Total) > sum(Available), sum(Total)>sum(Used) from information_schema.disks;
sum(Total) > sum(Available) sum(Total)>sum(Used)
diff --git a/plugin/handler_socket/client/hspool_test.pl b/plugin/handler_socket/client/hspool_test.pl
index 7fe073301b1..973913d4ee9 100755
--- a/plugin/handler_socket/client/hspool_test.pl
+++ b/plugin/handler_socket/client/hspool_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
use strict;
use warnings;
diff --git a/plugin/handler_socket/client/hstest.pl b/plugin/handler_socket/client/hstest.pl
index 4d177b6cdc8..7651dddbc63 100755
--- a/plugin/handler_socket/client/hstest.pl
+++ b/plugin/handler_socket/client/hstest.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=8:ai:ts=8
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
index c51fe60d591..b6ea62651a3 100755
--- a/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/lib/Net/HandlerSocket/Pool.pm
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
package Net::HandlerSocket::HSPool;
diff --git a/plugin/handler_socket/regtest/test_01_lib/test01.pl b/plugin/handler_socket/regtest/test_01_lib/test01.pl
index d3a072fb3cc..0a3ad9e9b25 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test01.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test01.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test02.pl b/plugin/handler_socket/regtest/test_01_lib/test02.pl
index c69515d76e9..f9bdc8b6738 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test02.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test02.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test03.pl b/plugin/handler_socket/regtest/test_01_lib/test03.pl
index a081786c132..a51aaf3b257 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test03.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test03.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test04.pl b/plugin/handler_socket/regtest/test_01_lib/test04.pl
index 52fe11364c8..d922b713271 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test04.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test04.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test05.pl b/plugin/handler_socket/regtest/test_01_lib/test05.pl
index 10b1a0805a0..2993e7a9680 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test05.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test05.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test06.pl b/plugin/handler_socket/regtest/test_01_lib/test06.pl
index fb0549f2295..69dd107e1ff 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test06.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test06.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test07.pl b/plugin/handler_socket/regtest/test_01_lib/test07.pl
index fa9802366d8..2286aeba9fe 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test07.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test07.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test08.pl b/plugin/handler_socket/regtest/test_01_lib/test08.pl
index c33bf190d29..da736ef34c3 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test08.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test08.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test09.pl b/plugin/handler_socket/regtest/test_01_lib/test09.pl
index 14fd9c26641..7d6165ece1e 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test09.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test09.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test10.pl b/plugin/handler_socket/regtest/test_01_lib/test10.pl
index fd294fe8b78..560976ba9b2 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test10.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test10.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test11.pl b/plugin/handler_socket/regtest/test_01_lib/test11.pl
index 5cfe3e83614..cfaa940572c 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test11.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test11.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test12.pl b/plugin/handler_socket/regtest/test_01_lib/test12.pl
index 100a779de4e..0cae3798372 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test12.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test12.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test13.pl b/plugin/handler_socket/regtest/test_01_lib/test13.pl
index 1e1104d2a07..2068c4bc9b6 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test13.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test13.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test14.pl b/plugin/handler_socket/regtest/test_01_lib/test14.pl
index ff4e433ae8f..ab89073370b 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test14.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test14.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test15.pl b/plugin/handler_socket/regtest/test_01_lib/test15.pl
index 4c56d355708..2205be5b363 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test15.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test15.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test16.pl b/plugin/handler_socket/regtest/test_01_lib/test16.pl
index 6db8c576d7a..c0c3fc556ff 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test16.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test16.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test17.pl b/plugin/handler_socket/regtest/test_01_lib/test17.pl
index 1ffd7fa1242..7c150dab746 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test17.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test17.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test18.pl b/plugin/handler_socket/regtest/test_01_lib/test18.pl
index 87047bc9cba..7854642af15 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test18.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test18.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test19.pl b/plugin/handler_socket/regtest/test_01_lib/test19.pl
index 9870199c1a7..2e5363c8137 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test19.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test19.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test20.pl b/plugin/handler_socket/regtest/test_01_lib/test20.pl
index 139bbf9aba1..96307e0a5f0 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test20.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test20.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test21.pl b/plugin/handler_socket/regtest/test_01_lib/test21.pl
index 413ea636400..34e9d43972b 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test21.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test21.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test22.pl b/plugin/handler_socket/regtest/test_01_lib/test22.pl
index cf029944292..370d16d6027 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test22.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test22.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test23.pl b/plugin/handler_socket/regtest/test_01_lib/test23.pl
index 83c2194bfa6..d9bd0381251 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test23.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test23.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/plugin/handler_socket/regtest/test_01_lib/test24.pl b/plugin/handler_socket/regtest/test_01_lib/test24.pl
index 6cd95a995e5..f4e3bb3f10c 100644
--- a/plugin/handler_socket/regtest/test_01_lib/test24.pl
+++ b/plugin/handler_socket/regtest/test_01_lib/test24.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# vim:sw=2:ai
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index b139b51e296..536f586a17b 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -316,6 +316,36 @@ ELSE()
SET(WSREP_SOURCE
wsrep_sst_common
)
+
+ SET (wsrep_sst_rsync_wan ${CMAKE_CURRENT_BINARY_DIR}/wsrep_sst_rsync_wan)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${wsrep_sst_rsync_wan}
+ COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink
+ wsrep_sst_rsync
+ wsrep_sst_rsync_wan
+ )
+ ADD_CUSTOM_TARGET(symlink_wsrep_sst_rsync
+ ALL
+ DEPENDS ${wsrep_sst_rsync_wan}
+ )
+ INSTALL(
+ FILES ${wsrep_sst_rsync_wan}
+ DESTINATION ${INSTALL_BINDIR}
+ COMPONENT Server
+ )
+
+ FOREACH(file ${WSREP_SOURCE})
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+ ${CMAKE_CURRENT_BINARY_DIR}/${file} ESCAPE_QUOTES @ONLY)
+ IF(NOT ${file}_COMPONENT)
+ SET(${file}_COMPONENT Server)
+ ENDIF()
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${file}
+ DESTINATION ${INSTALL_BINDIR}
+ COMPONENT ${${file}_COMPONENT}
+ )
+ ENDFOREACH()
ENDIF()
IF (NOT WITHOUT_SERVER)
SET(SERVER_SCRIPTS
@@ -368,35 +398,6 @@ ELSE()
COMPONENT ${${file}_COMPONENT}
)
ENDFOREACH()
- SET (wsrep_sst_rsync_wan ${CMAKE_CURRENT_BINARY_DIR}/wsrep_sst_rsync_wan)
- ADD_CUSTOM_COMMAND(
- OUTPUT ${wsrep_sst_rsync_wan}
- COMMAND ${CMAKE_COMMAND} ARGS -E create_symlink
- wsrep_sst_rsync
- wsrep_sst_rsync_wan
- )
- ADD_CUSTOM_TARGET(symlink_wsrep_sst_rsync
- ALL
- DEPENDS ${wsrep_sst_rsync_wan}
- )
- INSTALL(
- FILES ${wsrep_sst_rsync_wan}
- DESTINATION ${INSTALL_BINDIR}
- COMPONENT Server
- )
-
- FOREACH(file ${WSREP_SOURCE})
- CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
- ${CMAKE_CURRENT_BINARY_DIR}/${file} ESCAPE_QUOTES @ONLY)
- IF(NOT ${file}_COMPONENT)
- SET(${file}_COMPONENT Server)
- ENDIF()
- INSTALL(FILES
- ${CMAKE_CURRENT_BINARY_DIR}/${file}
- DESTINATION ${INSTALL_BINDIR}
- COMPONENT ${${file}_COMPONENT}
- )
- ENDFOREACH()
ENDIF()
# Install libgcc as mylibgcc.a
diff --git a/scripts/galera_recovery.sh b/scripts/galera_recovery.sh
index 709c4b0eed5..8df2abc3fd5 100644
--- a/scripts/galera_recovery.sh
+++ b/scripts/galera_recovery.sh
@@ -101,8 +101,7 @@ wsrep_recover_position() {
# Safety checks
if [ -n "$log_file" -a -f "$log_file" ]; then
- [ "$euid" = "0" ] && chown $user $log_file
- chmod 600 $log_file
+ chmod 600 $log_file
else
log "WSREP: mktemp failed"
fi
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index adf521f89f6..67ec88c975c 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -67,6 +67,7 @@ Usage: $0 [OPTIONS]
--cross-bootstrap For internal use. Used when building the MariaDB system
tables on a different host than the target.
--datadir=path The path to the MariaDB data directory.
+ --no-defaults Don't read default options from any option file.
--defaults-extra-file=name
Read this file after the global files are read.
--defaults-file=name Only read default options from the given file name.
@@ -79,8 +80,6 @@ Usage: $0 [OPTIONS]
--help Display this help and exit.
--ldata=path The path to the MariaDB data directory. Same as
--datadir.
- --no-defaults Don't read default options from any option file.
- --defaults-file=path Read only this configuration file.
--rpm For internal use. This option is used by RPM files
during the MariaDB installation process.
--skip-auth-anonymous-user
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 5f359551f0d..3aad68ffb6e 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -308,9 +308,7 @@ sub report_mysqlds
sub start_mysqlds()
{
- my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $suffix_found, $info_sent);
-
- $suffix_found= 0;
+ my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $info_sent);
if (!$opt_no_log)
{
@@ -349,10 +347,6 @@ sub start_mysqlds()
$options[$j]= quote_shell_word($options[$j]);
$tmp.= " $options[$j]";
}
- elsif ("--defaults-group-suffix=" eq substr($options[$j], 0, 24))
- {
- $suffix_found= 1;
- }
else
{
$options[$j]= quote_shell_word($options[$j]);
@@ -369,12 +363,6 @@ sub start_mysqlds()
$info_sent= 1;
}
- if (!$suffix_found)
- {
- $com.= " --defaults-group-suffix=";
- $com.= substr($groups[$i],6);
- }
-
$com.= $tmp;
if ($opt_wsrep_new_cluster) {
diff --git a/scripts/mytop.sh b/scripts/mytop.sh
index 3ef0a59f27f..e7b9040c3a8 100644
--- a/scripts/mytop.sh
+++ b/scripts/mytop.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# $Id: mytop,v 1.91 2012/01/18 16:49:12 mgrennan Exp $
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index 59d2e12817b..2fce421e4eb 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -386,8 +386,8 @@ read_cnf()
get_stream()
{
- if [[ $sfmt == 'xbstream' ]];then
- wsrep_log_info "Streaming with xbstream"
+ if [[ $sfmt == 'mbstream' || $sfmt == 'xbstream' ]];then
+ wsrep_log_info "Streaming with ${sfmt}"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
strmcmd="${XBSTREAM_BIN} -x"
else
@@ -713,7 +713,8 @@ INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG
fi
-# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and INNODB_DATA_HOME_DIR environment variable
+# is not set, try to get it from my.cnf:
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
fi
@@ -961,17 +962,25 @@ then
ib_home_dir=$INNODB_DATA_HOME_DIR
- # Try to set ib_log_dir from the command line:
- ib_log_dir=$INNODB_LOG_GROUP_HOME_ARG
- if [ -z "$ib_log_dir" ]; then
- ib_log_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir "")
+ WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
+ # Try to set WSREP_LOG_DIR from the command line:
+ if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then
+ WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG
fi
- if [ -z "$ib_log_dir" ]; then
- ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "")
+ # if no command line arg and WSREP_LOG_DIR is not set,
+ # try to get it from my.cnf:
+ if [ -z "$WSREP_LOG_DIR" ]; then
+ WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '')
fi
+ if [ -z "$WSREP_LOG_DIR" ]; then
+ WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '')
+ fi
+
+ ib_log_dir=$WSREP_LOG_DIR
# Try to set ib_undo_dir from the command line:
- ib_undo_dir=$INNODB_UNDO_DIR_ARG
+ ib_undo_dir=${INNODB_UNDO_DIR_ARG:-""}
+ # if no command line arg then try to get it from my.cnf:
if [ -z "$ib_undo_dir" ]; then
ib_undo_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-undo-directory "")
fi
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 8fbb32135d7..890cd213b42 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -112,10 +112,11 @@ fi
WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
# Try to set WSREP_LOG_DIR from the command line:
-if [ -z "$WSREP_LOG_DIR" ]; then
+if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then
WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG
fi
-# if WSREP_LOG_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and WSREP_LOG_DIR is not set,
+# try to get it from my.cnf:
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '')
fi
@@ -136,7 +137,8 @@ INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG
fi
-# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and INNODB_DATA_HOME_DIR environment variable
+# is not set, try to get it from my.cnf:
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
fi
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index 75601e5c180..8fbbeda170c 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -904,7 +904,8 @@ INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG
fi
-# if INNODB_DATA_HOME_DIR env. variable is not set, try to get it from my.cnf
+# if no command line arg and INNODB_DATA_HOME_DIR environment variable
+# is not set, try to get it from my.cnf:
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
fi
diff --git a/sql-bench/as3ap.sh b/sql-bench/as3ap.sh
index fd2b6ba3b25..8e4b3167429 100644
--- a/sql-bench/as3ap.sh
+++ b/sql-bench/as3ap.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/bench-count-distinct.sh b/sql-bench/bench-count-distinct.sh
index 9ce9b2fb168..b6465d0635f 100644
--- a/sql-bench/bench-count-distinct.sh
+++ b/sql-bench/bench-count-distinct.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh
index 1b6509cebcc..eeff8665cba 100644
--- a/sql-bench/bench-init.pl.sh
+++ b/sql-bench/bench-init.pl.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000-2003, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/compare-results.sh b/sql-bench/compare-results.sh
index f0658160db2..06e247bae8a 100644
--- a/sql-bench/compare-results.sh
+++ b/sql-bench/compare-results.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/copy-db.sh b/sql-bench/copy-db.sh
index 38a010e52ab..d70472feaff 100644
--- a/sql-bench/copy-db.sh
+++ b/sql-bench/copy-db.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index a7298c5f9a1..26f66f94735 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- perl -*-
# Copyright (c) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/sql-bench/graph-compare-results.sh b/sql-bench/graph-compare-results.sh
index ddc9080acd6..d43f722cb14 100755
--- a/sql-bench/graph-compare-results.sh
+++ b/sql-bench/graph-compare-results.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
####
#### Hello ... this is a heavily hacked script by Luuk
#### instead of printing the result it makes a nice gif
diff --git a/sql-bench/innotest1.sh b/sql-bench/innotest1.sh
index 9e1ed32c273..1b99f601f42 100644
--- a/sql-bench/innotest1.sh
+++ b/sql-bench/innotest1.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest1a.sh b/sql-bench/innotest1a.sh
index 1e428e33dcf..7183c901831 100644
--- a/sql-bench/innotest1a.sh
+++ b/sql-bench/innotest1a.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest1b.sh b/sql-bench/innotest1b.sh
index 524a6e0e145..0a909d1a8f6 100644
--- a/sql-bench/innotest1b.sh
+++ b/sql-bench/innotest1b.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest2.sh b/sql-bench/innotest2.sh
index fa0fd418968..941b0ac8b59 100644
--- a/sql-bench/innotest2.sh
+++ b/sql-bench/innotest2.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/InnoDB combined database
# (c) 2002 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest2a.sh b/sql-bench/innotest2a.sh
index 4a6e4b20a9a..e873d2b458c 100644
--- a/sql-bench/innotest2a.sh
+++ b/sql-bench/innotest2a.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/Innobase combined database
# (c) 2000 Innobase Oy & MySQL AB
diff --git a/sql-bench/innotest2b.sh b/sql-bench/innotest2b.sh
index b94325ff39e..56b44eda561 100644
--- a/sql-bench/innotest2b.sh
+++ b/sql-bench/innotest2b.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
############################################################################
# Stress test for MySQL/Innobase combined database
# (c) 2000 Innobase Oy & MySQL AB
diff --git a/sql-bench/run-all-tests.sh b/sql-bench/run-all-tests.sh
index 5d77c8c388d..ecab48e88fe 100644
--- a/sql-bench/run-all-tests.sh
+++ b/sql-bench/run-all-tests.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/server-cfg.sh b/sql-bench/server-cfg.sh
index fcdfe0b678f..6cc58f527af 100644
--- a/sql-bench/server-cfg.sh
+++ b/sql-bench/server-cfg.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# -*- perl -*-
# Copyright (c) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/sql-bench/test-ATIS.sh b/sql-bench/test-ATIS.sh
index d3c242db256..2e082012a8f 100644
--- a/sql-bench/test-ATIS.sh
+++ b/sql-bench/test-ATIS.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-alter-table.sh b/sql-bench/test-alter-table.sh
index 3a7f325b604..0602bd1f7fc 100644
--- a/sql-bench/test-alter-table.sh
+++ b/sql-bench/test-alter-table.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-big-tables.sh b/sql-bench/test-big-tables.sh
index e2cf983de1c..6be907d0ee6 100644
--- a/sql-bench/test-big-tables.sh
+++ b/sql-bench/test-big-tables.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-connect.sh b/sql-bench/test-connect.sh
index 1226301df9b..e3acb453a30 100644
--- a/sql-bench/test-connect.sh
+++ b/sql-bench/test-connect.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-create.sh b/sql-bench/test-create.sh
index 7af6fa13562..09961f0d698 100644
--- a/sql-bench/test-create.sh
+++ b/sql-bench/test-create.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000-2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh
index be57b04471a..0cb951d86c8 100644
--- a/sql-bench/test-insert.sh
+++ b/sql-bench/test-insert.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000-2003, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-select.sh b/sql-bench/test-select.sh
index 4c7147b57a4..e3020698cb8 100644
--- a/sql-bench/test-select.sh
+++ b/sql-bench/test-select.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-table-elimination.sh b/sql-bench/test-table-elimination.sh
index de440fc0633..c3a264492a4 100755
--- a/sql-bench/test-table-elimination.sh
+++ b/sql-bench/test-table-elimination.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Test of table elimination feature
use Cwd;
diff --git a/sql-bench/test-transactions.sh b/sql-bench/test-transactions.sh
index 4732658c529..334a6f0a385 100644
--- a/sql-bench/test-transactions.sh
+++ b/sql-bench/test-transactions.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-bench/test-wisconsin.sh b/sql-bench/test-wisconsin.sh
index 47c9e050304..581db89712e 100644
--- a/sql-bench/test-wisconsin.sh
+++ b/sql-bench/test-wisconsin.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2001, 2003, 2006 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/sql-common/client.c b/sql-common/client.c
index fe73887106e..eee0ba8f2dd 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1403,9 +1403,23 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
{
if (field - result >= (my_ptrdiff_t)fields)
goto err;
+
+ /*
+ If any of the row->data[] below is NULL, it can result in a
+ crash. Error out early as it indicates a malformed packet.
+ For data[0], data[1] and data[5], strmake_root will handle
+ NULL values.
+ */
+ if (!row->data[2] || !row->data[3] || !row->data[4])
+ {
+ free_rows(data);
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ DBUG_RETURN(0);
+ }
+
cli_fetch_lengths(&lengths[0], row->data, default_value ? 6 : 5);
- field->org_table= field->table= strdup_root(alloc,(char*) row->data[0]);
- field->name= strdup_root(alloc,(char*) row->data[1]);
+ field->org_table= field->table= strmake_root(alloc,(char*) row->data[0], lengths[0]);
+ field->name= strmake_root(alloc,(char*) row->data[1], lengths[1]);
field->length= (uint) uint3korr(row->data[2]);
field->type= (enum enum_field_types) (uchar) row->data[3][0];
@@ -1430,7 +1444,7 @@ unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
field->flags|= NUM_FLAG;
if (default_value && row->data[5])
{
- field->def=strdup_root(alloc,(char*) row->data[5]);
+ field->def= strmake_root(alloc,(char*) row->data[5], lengths[5]);
field->def_length= lengths[5];
}
else
@@ -3588,7 +3602,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
scramble_data_len= pkt_scramble_len;
scramble_plugin= scramble_data + scramble_data_len;
if (scramble_data + scramble_data_len > pkt_end)
- scramble_data_len= pkt_end - scramble_data;
+ {
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ goto error;
+ }
}
else
{
diff --git a/sql/compat56.cc b/sql/compat56.cc
index 1ffc8fd762d..eb11de9479f 100644
--- a/sql/compat56.cc
+++ b/sql/compat56.cc
@@ -290,7 +290,7 @@ uint my_datetime_binary_length(uint dec)
/*
On disk we store as unsigned number with DATETIMEF_INT_OFS offset,
- for HA_KETYPE_BINARY compatibilty purposes.
+ for HA_KETYPE_BINARY compatibility purposes.
*/
#define DATETIMEF_INT_OFS 0x8000000000LL
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 105d868a175..79f3a241907 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1,4 +1,5 @@
/* Copyright (c) 2009, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2013, 2020, MariaDB
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
@@ -33,7 +34,7 @@
/*
Action to perform at a synchronization point.
NOTE: This structure is moved around in memory by realloc(), qsort(),
- and memmove(). Do not add objects with non-trivial constuctors
+ and memmove(). Do not add objects with non-trivial constructors
or destructors, which might prevent moving of this structure
with these functions.
*/
@@ -319,7 +320,8 @@ static char *debug_sync_bmove_len(char *to, char *to_end,
DBUG_ASSERT(to_end);
DBUG_ASSERT(!length || from);
set_if_smaller(length, (size_t) (to_end - to));
- memcpy(to, from, length);
+ if (length)
+ memcpy(to, from, length);
return (to + length);
}
@@ -542,7 +544,7 @@ static void debug_sync_reset(THD *thd)
@description
Removing an action mainly means to decrement the ds_active counter.
But if the action is between other active action in the array, then
- the array needs to be shrinked. The active actions above the one to
+ the array needs to be shrunk. The active actions above the one to
be removed have to be moved down by one slot.
*/
diff --git a/sql/derror.cc b/sql/derror.cc
index b976fff9d4f..f7abcda1854 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -166,7 +166,7 @@ bool read_texts(const char *file_name, const char *language,
MYF(0))) < 0)
{
/*
- Trying pre-5.4 sematics of the --language parameter.
+ Trying pre-5.4 semantics of the --language parameter.
It included the language-specific part, e.g.:
--language=/path/to/english/
diff --git a/sql/encryption.cc b/sql/encryption.cc
index ad23c80b8ab..4fac36dc97e 100644
--- a/sql/encryption.cc
+++ b/sql/encryption.cc
@@ -75,8 +75,8 @@ int initialize_encryption_plugin(st_plugin_int *plugin)
(struct st_mariadb_encryption*) plugin->plugin->info;
/*
- Copmiler on Spark doesn't like the '?' operator here as it
- belives the (uint (*)...) implies the C++ call model.
+ Compiler on Spark doesn't like the '?' operator here as it
+ believes the (uint (*)...) implies the C++ call model.
*/
if (handle->crypt_ctx_size)
encryption_handler.encryption_ctx_size_func= handle->crypt_ctx_size;
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index 759bca08eea..51ee921c689 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -159,7 +159,7 @@ Event_creation_ctx::load_from_db(THD *thd,
/*************************************************************************/
/*
- Initiliazes dbname and name of an Event_queue_element_for_exec
+ Initializes dbname and name of an Event_queue_element_for_exec
object
SYNOPSIS
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 2928a059a0e..c89efec82a0 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -668,7 +668,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
DBUG_PRINT("info", ("name: %.*s", (int) parse_data->name.length,
parse_data->name.str));
- DBUG_PRINT("info", ("check existance of an event with the same name"));
+ DBUG_PRINT("info", ("check existence of an event with the same name"));
if (!find_named_event(parse_data->dbname, parse_data->name, table))
{
if (thd->lex->create_info.or_replace())
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index 3dbcaba8bb0..92ba27a25a1 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -100,7 +100,7 @@ Event_parse_data::init_name(THD *thd, sp_name *spn)
ENDS or AT is in the past, we are trying to create an event that
will never be executed. If it has ON COMPLETION NOT PRESERVE
(default), then it would normally be dropped already, so on CREATE
- EVENT we give a warning, and do not create anyting. On ALTER EVENT
+ EVENT we give a warning, and do not create anything. On ALTER EVENT
we give a error, and do not change the event.
If the event has ON COMPLETION PRESERVE, then we see if the event is
@@ -359,7 +359,7 @@ wrong_value:
EVERY 5 MINUTE STARTS "2004-12-12 10:00:00" means that
the event will be executed every 5 minutes but this will
start at the date shown above. Expressions are possible :
- DATE_ADD(NOW(), INTERVAL 1 DAY) -- start tommorow at
+ DATE_ADD(NOW(), INTERVAL 1 DAY) -- start tomorrow at
same time.
RETURN VALUE
@@ -413,7 +413,7 @@ wrong_value:
EVERY 5 MINUTE ENDS "2004-12-12 10:00:00" means that
the event will be executed every 5 minutes but this will
end at the date shown above. Expressions are possible :
- DATE_ADD(NOW(), INTERVAL 1 DAY) -- end tommorow at
+ DATE_ADD(NOW(), INTERVAL 1 DAY) -- end tomorrow at
same time.
RETURN VALUE
diff --git a/sql/event_queue.cc b/sql/event_queue.cc
index 3a52da0241d..0e330bbdf03 100644
--- a/sql/event_queue.cc
+++ b/sql/event_queue.cc
@@ -357,7 +357,7 @@ Event_queue::drop_matching_events(THD *thd, LEX_STRING pattern,
We don't call mysql_cond_broadcast(&COND_queue_state);
If we remove the top event:
1. The queue is empty. The scheduler will wake up at some time and
- realize that the queue is empty. If create_event() comes inbetween
+ realize that the queue is empty. If create_event() comes in between
it will signal the scheduler
2. The queue is not empty, but the next event after the previous top,
won't be executed any time sooner than the element we removed. Hence,
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index 8c49e6f2746..96ea298fd11 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2013, Oracle and/or its affiliates.
+/* Copyright (c) 2006, 2019, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2020, MariaDB Corporation
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
@@ -507,6 +508,7 @@ Event_scheduler::run(THD *thd)
DBUG_PRINT("info", ("job_data is NULL, the thread was killed"));
}
DBUG_PRINT("info", ("state=%s", scheduler_states_names[state].str));
+ free_root(thd->mem_root, MYF(0));
}
LOCK_DATA();
diff --git a/sql/events.cc b/sql/events.cc
index 6f2f17a5017..42ce5bfcaa4 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -128,7 +128,7 @@ bool Events::check_if_system_tables_error()
/**
Reconstructs interval expression from interval type and expression
- value that is in form of a value of the smalles entity:
+ value that is in form of a value of the smallest entity:
For
YEAR_MONTH - expression is in months
DAY_MINUTE - expression is in minutes
diff --git a/sql/field.cc b/sql/field.cc
index 291e2134dcf..1ec5e8e5e41 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -47,7 +47,7 @@
#define MAX_EXPONENT 1024
/*****************************************************************************
- Instansiate templates and static variables
+ Instantiate templates and static variables
*****************************************************************************/
static const char *zero_timestamp="0000-00-00 00:00:00.000000";
@@ -78,7 +78,7 @@ const char field_separator=',';
/*
Rules for merging different types of fields in UNION
- NOTE: to avoid 256*256 table, gap in table types numeration is skiped
+ NOTE: to avoid 256*256 table, gap in table types numeration is skipped
following #defines describe that gap and how to canculate number of fields
and index of field in thia array.
*/
@@ -1374,7 +1374,7 @@ Item *Field_num::get_equal_zerofill_const_item(THD *thd, const Context &ctx,
/**
- Contruct warning parameters using thd->no_errors
+Construct warning parameters using thd->no_errors
to determine whether to generate or suppress warnings.
We can get here in a query like this:
SELECT COUNT(@@basedir);
@@ -1422,7 +1422,7 @@ Value_source::Converter_string_to_number::check_edom_and_truncation(THD *thd,
if (filter.want_warning_edom())
{
/*
- We can use err.ptr() here as ErrConvString is guranteed to put an
+ We can use err.ptr() here as ErrConvString is guaranteed to put an
end \0 here.
*/
THD *wthd= thd ? thd : current_thd;
@@ -1454,7 +1454,7 @@ Value_source::Converter_string_to_number::check_edom_and_truncation(THD *thd,
- found garbage at the end of the string.
@param type Data type name (e.g. "decimal", "integer", "double")
- @param edom Indicates that the string-to-number routine retuned
+ @param edom Indicates that the string-to-number routine returned
an error code equivalent to EDOM (value out of domain),
i.e. the string fully consisted of garbage and the
conversion routine could not get any digits from it.
@@ -1518,7 +1518,7 @@ int Field_num::check_edom_and_truncation(const char *type, bool edom,
/*
- Conver a string to an integer then check bounds.
+ Convert a string to an integer then check bounds.
SYNOPSIS
Field_num::get_int
@@ -2486,7 +2486,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
We only have to generate warnings if count_cuted_fields is set.
This is to avoid extra checks of the number when they are not needed.
Even if this flag is not set, it's OK to increment warnings, if
- it makes the code easer to read.
+ it makes the code easier to read.
*/
if (get_thd()->count_cuted_fields)
@@ -2569,7 +2569,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
}
/*
- Now write the formated number
+ Now write the formatted number
First the digits of the int_% parts.
Do we have enough room to write these digits ?
@@ -3129,7 +3129,7 @@ int Field_new_decimal::store(const char *from, uint length,
If check_decimal() failed because of EDOM-alike error,
(e.g. E_DEC_BAD_NUM), we have to initialize decimal_value to zero.
Note: if check_decimal() failed because of truncation,
- decimal_value is alreay properly initialized.
+ decimal_value is already properly initialized.
*/
my_decimal_set_zero(&decimal_value);
/*
@@ -3295,10 +3295,9 @@ int Field_new_decimal::cmp(const uchar *a,const uchar*b)
}
-void Field_new_decimal::sort_string(uchar *buff,
- uint length __attribute__((unused)))
+void Field_new_decimal::sort_string(uchar *buff, uint length)
{
- memcpy(buff, ptr, bin_size);
+ memcpy(buff, ptr, length);
}
@@ -4628,11 +4627,12 @@ int truncate_double(double *nr, uint field_length, uint dec,
{
uint order= field_length - dec;
uint step= array_elements(log_10) - 1;
- max_value= 1.0;
+ double max_value_by_dec= 1.0;
for (; order > step; order-= step)
- max_value*= log_10[step];
- max_value*= log_10[order];
- max_value-= 1.0 / log_10[dec];
+ max_value_by_dec*= log_10[step];
+ max_value_by_dec*= log_10[order];
+ max_value_by_dec-= 1.0 / log_10[dec];
+ set_if_smaller(max_value, max_value_by_dec);
/* Check for infinity so we don't get NaN in calculations */
if (!my_isinf(res))
@@ -4937,7 +4937,7 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
{
/*
We mark the flag with TIMESTAMP_FLAG to indicate to the client that
- this field will be automaticly updated on insert.
+ this field will be automatically updated on insert.
*/
flags|= TIMESTAMP_FLAG;
if (unireg_check != TIMESTAMP_DN_FIELD)
@@ -7346,7 +7346,7 @@ Field_string::unpack(uchar *to, const uchar *from, const uchar *from_end,
with the real type. Since all allowable types have 0xF as most
significant bits of the metadata word, lengths <256 will not affect
the real type at all, while all other values will result in a
- non-existant type in the range 17-244.
+ non-existent type in the range 17-244.
@see Field_string::unpack
@@ -7537,8 +7537,7 @@ my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
}
-int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
- uint max_len)
+int Field_varstring::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
uint a_length, b_length;
int diff;
@@ -7553,8 +7552,8 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
a_length= uint2korr(a_ptr);
b_length= uint2korr(b_ptr);
}
- set_if_smaller(a_length, max_len);
- set_if_smaller(b_length, max_len);
+ set_if_smaller(a_length, field_length);
+ set_if_smaller(b_length, field_length);
diff= field_charset->coll->strnncollsp(field_charset,
a_ptr+
length_bytes,
@@ -7566,6 +7565,43 @@ int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
}
+static int cmp_str_prefix(const uchar *ua, size_t alen, const uchar *ub,
+ size_t blen, size_t prefix, CHARSET_INFO *cs)
+{
+ const char *a= (char*)ua, *b= (char*)ub;
+ MY_STRCOPY_STATUS status;
+ prefix/= cs->mbmaxlen;
+ alen= cs->cset->well_formed_char_length(cs, a, a + alen, prefix, &status);
+ blen= cs->cset->well_formed_char_length(cs, b, b + blen, prefix, &status);
+ return cs->coll->strnncollsp(cs, ua, alen, ub, blen, 0);
+}
+
+
+
+int Field_varstring::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
+ size_t prefix_len)
+{
+ /* avoid expensive well_formed_char_length if possible */
+ if (prefix_len == table->field[field_index]->field_length)
+ return Field_varstring::cmp(a_ptr, b_ptr);
+
+ size_t a_length, b_length;
+
+ if (length_bytes == 1)
+ {
+ a_length= *a_ptr;
+ b_length= *b_ptr;
+ }
+ else
+ {
+ a_length= uint2korr(a_ptr);
+ b_length= uint2korr(b_ptr);
+ }
+ return cmp_str_prefix(a_ptr+length_bytes, a_length, b_ptr+length_bytes,
+ b_length, prefix_len, field_charset);
+}
+
+
/**
@note
varstring and blob keys are ALWAYS stored with a 2 byte length prefix
@@ -8114,16 +8150,24 @@ int Field_blob::cmp(const uchar *a,uint32 a_length, const uchar *b,
}
-int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
- uint max_length)
+int Field_blob::cmp(const uchar *a_ptr, const uchar *b_ptr)
+{
+ uchar *blob1,*blob2;
+ memcpy(&blob1, a_ptr+packlength, sizeof(char*));
+ memcpy(&blob2, b_ptr+packlength, sizeof(char*));
+ size_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
+ return cmp(blob1, a_len, blob2, b_len);
+}
+
+
+int Field_blob::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
+ size_t prefix_len)
{
uchar *blob1,*blob2;
memcpy(&blob1, a_ptr+packlength, sizeof(char*));
memcpy(&blob2, b_ptr+packlength, sizeof(char*));
- uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
- set_if_smaller(a_len, max_length);
- set_if_smaller(b_len, max_length);
- return Field_blob::cmp(blob1,a_len,blob2,b_len);
+ size_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
+ return cmp_str_prefix(blob1, a_len, blob2, b_len, prefix_len, field_charset);
}
@@ -9407,7 +9451,7 @@ my_decimal *Field_bit::val_decimal(my_decimal *deciaml_value)
The a and b pointer must be pointers to the field in a record
(not the table->record[0] necessarily)
*/
-int Field_bit::cmp_max(const uchar *a, const uchar *b, uint max_len)
+int Field_bit::cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len)
{
my_ptrdiff_t a_diff= a - ptr;
my_ptrdiff_t b_diff= b - ptr;
@@ -9872,7 +9916,7 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg,
/*
Set the pack flag correctly for the blob-like types. This sets the
packtype to something that make_field can use. If the pack type is
- not set correctly, the packlength will be reeeeally wierd (like
+ not set correctly, the packlength will be reeeeally weird (like
129 or so).
*/
switch (sql_type_arg)
@@ -10080,7 +10124,7 @@ bool Create_field::check(THD *thd)
break;
case MYSQL_TYPE_VARCHAR:
/*
- Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
+ Long VARCHAR's are automatically converted to blobs in mysql_prepare_table
if they don't have a default value
*/
max_field_charlength= MAX_FIELD_VARCHARLENGTH;
diff --git a/sql/field.h b/sql/field.h
index 60849ea8099..27a3f130aa7 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -241,7 +241,7 @@ protected:
};
- // String-to-number convertion methods for the old code compatibility
+ // String-to-number conversion methods for the old code compatibility
longlong longlong_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
const char *end) const
{
@@ -312,7 +312,7 @@ public:
/*
Item context attributes.
Comparison functions pass their attributes to propagate_equal_fields().
- For exmple, for string comparison, the collation of the comparison
+ For example, for string comparison, the collation of the comparison
operation is important inside propagate_equal_fields().
*/
class Context
@@ -460,7 +460,7 @@ inline bool is_timestamp_type(enum_field_types type)
/**
- Convert temporal real types as retuned by field->real_type()
+ Convert temporal real types as returned by field->real_type()
to field type as returned by field->type().
@param real_type Real type.
@@ -954,9 +954,13 @@ public:
return type();
}
inline int cmp(const uchar *str) { return cmp(ptr,str); }
- virtual int cmp_max(const uchar *a, const uchar *b, uint max_len)
- { return cmp(a, b); }
virtual int cmp(const uchar *,const uchar *)=0;
+ /*
+ The following method is used for comparing prefix keys.
+ Currently it's only used in partitioning.
+ */
+ virtual int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len)
+ { return cmp(a, b); }
virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L)
{ return memcmp(a,b,pack_length()); }
virtual int cmp_offset(uint row_offset)
@@ -1099,6 +1103,13 @@ public:
void make_sort_key(uchar *buff, uint length);
virtual void make_field(Send_field *);
+
+ /*
+ Some implementations actually may write up to 8 bytes regardless of what
+ size was requested. This is due to the minimum value of the system variable
+ max_sort_length.
+ */
+
virtual void sort_string(uchar *buff,uint length)=0;
virtual bool optimize_range(uint idx, uint part);
virtual void free() {}
@@ -2984,11 +2995,8 @@ public:
longlong val_int(void);
String *val_str(String*,String *);
my_decimal *val_decimal(my_decimal *);
- int cmp_max(const uchar *, const uchar *, uint max_length);
- int cmp(const uchar *a,const uchar *b)
- {
- return cmp_max(a, b, ~0L);
- }
+ int cmp(const uchar *a,const uchar *b);
+ int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len);
void sort_string(uchar *buff,uint length);
uint get_key_image(uchar *buff,uint length, imagetype type);
void set_key_image(const uchar *buff,uint length);
@@ -3070,9 +3078,8 @@ public:
longlong val_int(void);
String *val_str(String*,String *);
my_decimal *val_decimal(my_decimal *);
- int cmp_max(const uchar *, const uchar *, uint max_length);
- int cmp(const uchar *a,const uchar *b)
- { return cmp_max(a, b, ~0L); }
+ int cmp(const uchar *a,const uchar *b);
+ int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len);
int cmp(const uchar *a, uint32 a_length, const uchar *b, uint32 b_length);
int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L);
int key_cmp(const uchar *,const uchar*);
@@ -3345,7 +3352,7 @@ private:
This is the reason:
- Field_bit::cmp_binary() is only implemented in the base class
(Field::cmp_binary()).
- - Field::cmp_binary() currenly use pack_length() to calculate how
+ - Field::cmp_binary() currently uses pack_length() to calculate how
long the data is.
- pack_length() includes size of the bits stored in the NULL bytes
of the record.
@@ -3392,7 +3399,7 @@ public:
}
int cmp_binary_offset(uint row_offset)
{ return cmp_offset(row_offset); }
- int cmp_max(const uchar *a, const uchar *b, uint max_length);
+ int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_len);
int key_cmp(const uchar *a, const uchar *b)
{ return cmp_binary((uchar *) a, (uchar *) b); }
int key_cmp(const uchar *str, uint length);
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 8705e5e1e96..04e44db1c5c 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -236,7 +236,7 @@ static void do_skip(Copy_field *copy __attribute__((unused)))
note: if the record we're copying from is NULL-complemetned (i.e.
from_field->table->null_row==1), it will also have all NULLable columns to be
- set to NULLs, so we dont need to check table->null_row here.
+ set to NULLs, so we don't need to check table->null_row here.
*/
static void do_copy_null(Copy_field *copy)
diff --git a/sql/filesort.cc b/sql/filesort.cc
index bb3e73343ad..81ddc77a46b 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -256,7 +256,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
while (memory_available >= min_sort_memory)
{
ulonglong keys= memory_available / (param.rec_length + sizeof(char*));
- param.max_keys_per_buffer= (uint) MY_MIN(num_rows, keys);
+ param.max_keys_per_buffer= MY_MAX(MERGEBUFF2,
+ (uint) MY_MIN(num_rows, keys));
if (table_sort.get_sort_keys())
{
// If we have already allocated a buffer, it better have same size!
@@ -855,7 +856,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
}
if (!quick_select)
{
- (void) file->extra(HA_EXTRA_NO_CACHE); /* End cacheing of records */
+ (void) file->extra(HA_EXTRA_NO_CACHE); /* End caching of records */
if (!next_pos)
file->ha_rnd_end();
}
@@ -863,7 +864,7 @@ static ha_rows find_all_keys(THD *thd, Sort_param *param, SQL_SELECT *select,
if (thd->is_error())
DBUG_RETURN(HA_POS_ERROR);
- /* Signal we should use orignal column read and write maps */
+ /* Signal we should use original column read and write maps */
sort_form->column_bitmaps_set(save_read_set, save_write_set, save_vcol_set);
DBUG_PRINT("test",("error: %d indexpos: %d",error,indexpos));
@@ -1140,7 +1141,7 @@ static void make_sortkey(Sort_param *param,
}
case ROW_RESULT:
default:
- // This case should never be choosen
+ // This case should never be chosen
DBUG_ASSERT(0);
break;
}
@@ -1926,7 +1927,7 @@ sortlength(THD *thd, SORT_FIELD *sortorder, uint s_length,
break;
case ROW_RESULT:
default:
- // This case should never be choosen
+ // This case should never be chosen
DBUG_ASSERT(0);
break;
}
diff --git a/sql/filesort_utils.cc b/sql/filesort_utils.cc
index f1a164dd9fe..287edddf619 100644
--- a/sql/filesort_utils.cc
+++ b/sql/filesort_utils.cc
@@ -97,7 +97,6 @@ uchar **Filesort_buffer::alloc_sort_buffer(uint num_records, uint record_length)
if (m_idx_array.is_null())
{
sort_buff_sz= ((size_t)num_records) * (record_length + sizeof(uchar*));
- set_if_bigger(sort_buff_sz, record_length * MERGEBUFF2);
uchar **sort_keys=
(uchar**) my_malloc(sort_buff_sz, MYF(MY_THREAD_SPECIFIC));
m_idx_array= Idx_array(sort_keys, num_records);
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index 179807326f9..cc38bb96491 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -1866,7 +1866,7 @@ int Gcalc_scan_iterator::add_eq_node(Gcalc_heap::Info *node, point *sp)
if (!en)
GCALC_DBUG_RETURN(1);
- /* eq_node iserted after teh equal point. */
+ /* eq_node inserted after the equal point. */
en->next= node->get_next();
node->next= en;
diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h
index 7b7038812b2..1c0539e441f 100644
--- a/sql/gcalc_slicescan.h
+++ b/sql/gcalc_slicescan.h
@@ -355,9 +355,9 @@ enum Gcalc_scan_events
/*
- Gcalc_scan_iterator incapsulates the slisescan algorithm.
- It takes filled Gcalc_heap as an datasource. Then can be
- iterated trought the vertexes and intersection points with
+ Gcalc_scan_iterator incapsulates the slicescan algorithm.
+ It takes filled Gcalc_heap as a datasource. Then can be
+ iterated through the vertexes and intersection points with
the step() method. After the 'step()' one usually observes
the current 'slice' to do the necessary calculations, like
looking for intersections, calculating the area, whatever.
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
index acf51839e72..a8e380b691c 100644
--- a/sql/gcalc_tools.cc
+++ b/sql/gcalc_tools.cc
@@ -1173,14 +1173,14 @@ int Gcalc_operation_reducer::connect_threads(
{
rp0->outer_poly= prev_range->thread_start;
tb->thread_start= prev_range->thread_start;
- /* Chack if needed */
+ /* Check if needed */
ta->thread_start= prev_range->thread_start;
}
else
{
rp0->outer_poly= 0;
ta->thread_start= rp0;
- /* Chack if needed */
+ /* Check if needed */
tb->thread_start= rp0;
}
GCALC_DBUG_RETURN(0);
diff --git a/sql/gen_win_tzname_data.ps1 b/sql/gen_win_tzname_data.ps1
index 13b6ce6ffd0..c0a37d21895 100644
--- a/sql/gen_win_tzname_data.ps1
+++ b/sql/gen_win_tzname_data.ps1
@@ -4,7 +4,7 @@
write-output "/* This file was generated using gen_win_tzname_data.ps1 */"
$xdoc = new-object System.Xml.XmlDocument
-$xdoc.load("https://unicode.org/repos/cldr/trunk/common/supplemental/windowsZones.xml")
+$xdoc.load("https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml")
$nodes = $xdoc.SelectNodes("//mapZone[@territory='001']") # use default territory (001)
foreach ($node in $nodes) {
write-output ('{L"'+ $node.other + '","'+ $node.type+'"},')
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 4169e2b30d8..82aad243c16 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -542,7 +542,7 @@ bool ha_partition::initialize_partition(MEM_ROOT *mem_root)
point.
If you do not implement this, the default delete_table() is called from
- handler.cc and it will delete all files with the file extentions returned
+ handler.cc and it will delete all files with the file extensions returned
by bas_ext().
Called from handler.cc by delete_table and ha_create_table(). Only used
@@ -574,7 +574,7 @@ int ha_partition::delete_table(const char *name)
Renames a table from one name to another from alter table call.
If you do not implement this, the default rename_table() is called from
- handler.cc and it will rename all files with the file extentions returned
+ handler.cc and it will rename all files with the file extensions returned
by bas_ext().
Called from sql_table.cc by mysql_rename_table().
@@ -1428,7 +1428,7 @@ int ha_partition::handle_opt_partitions(THD *thd, HA_CHECK_OPT *check_opt,
/**
- @brief Check and repair the table if neccesary
+ @brief Check and repair the table if necessary
@param thd Thread object
@@ -2907,7 +2907,7 @@ error_end:
/**
Read the .par file to get the partitions engines and names
- @param name Name of table file (without extention)
+ @param name Name of table file (without extension)
@return Operation status
@retval true Failure
@@ -3135,7 +3135,7 @@ static uchar *get_part_name(PART_NAME_DEF *part, size_t *length,
@return Operation status
@retval true Failure
- @retval false Sucess
+ @retval false Success
*/
bool ha_partition::insert_partition_name_in_hash(const char *name, uint part_id,
@@ -3261,7 +3261,7 @@ err:
@return Operation status
@retval true Failure
- @retval false Sucess
+ @retval false Success
*/
bool ha_partition::set_ha_share_ref(Handler_share **ha_share_arg)
@@ -4141,7 +4141,7 @@ int ha_partition::write_row(uchar * buf)
/*
If we have failed to set the auto-increment value for this row,
it is highly likely that we will not be able to insert it into
- the correct partition. We must check and fail if neccessary.
+ the correct partition. We must check and fail if necessary.
*/
if (error)
goto exit;
@@ -4211,7 +4211,7 @@ exit:
have the previous row record in it, while new_data will have the newest
data in it.
Keep in mind that the server can do updates based on ordering if an
- ORDER BY clause was used. Consecutive ordering is not guarenteed.
+ ORDER BY clause was used. Consecutive ordering is not guaranteed.
Called from sql_select.cc, sql_acl.cc, sql_update.cc, and sql_insert.cc.
new_data is always record[0]
@@ -4353,7 +4353,7 @@ exit:
(from either a previous rnd_xxx() or index_xxx() call).
If you keep a pointer to the last row or can access a primary key it will
make doing the deletion quite a bit easier.
- Keep in mind that the server does no guarentee consecutive deletions.
+ Keep in mind that the server does no guarantee consecutive deletions.
ORDER BY clauses can be used.
Called in sql_acl.cc and sql_udf.cc to manage internal table information.
@@ -4737,7 +4737,7 @@ int ha_partition::end_bulk_insert()
When scan is used we will scan one handler partition at a time.
When preparing for rnd_pos we will init all handler partitions.
- No extra cache handling is needed when scannning is not performed.
+ No extra cache handling is needed when scanning is not performed.
Before initialising we will call rnd_end to ensure that we clean up from
any previous incarnation of a table scan.
@@ -5833,7 +5833,7 @@ int ha_partition::read_range_next()
SYNOPSIS
ha_partition::partition_scan_set_up()
buf Buffer to later return record in (this function
- needs it to calculcate partitioning function
+ needs it to calculate partitioning function
values)
idx_read_flag TRUE <=> m_start_key has range start endpoint which
@@ -6850,7 +6850,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
function after completing a query.
3) It is called when deleting the QUICK_RANGE_SELECT object if the
QUICK_RANGE_SELECT object had its own handler object. It is called
- immediatley before close of this local handler object.
+ immediately before close of this local handler object.
HA_EXTRA_KEYREAD:
HA_EXTRA_NO_KEYREAD:
These parameters are used to provide an optimisation hint to the handler.
@@ -6887,7 +6887,7 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
HA_EXTRA_IGNORE_DUP_KEY:
HA_EXTRA_NO_IGNORE_DUP_KEY:
Informs the handler to we will not stop the transaction if we get an
- duplicate key errors during insert/upate.
+ duplicate key errors during insert/update.
Always called in pair, triggered by INSERT IGNORE and other similar
SQL constructs.
Not used by MyISAM.
@@ -8286,7 +8286,7 @@ bool ha_partition::prepare_inplace_alter_table(TABLE *altered_table,
/*
Changing to similar partitioning, only update metadata.
- Non allowed changes would be catched in prep_alter_part_table().
+ Non allowed changes would be caught in prep_alter_part_table().
*/
if (ha_alter_info->alter_info->flags == Alter_info::ALTER_PARTITION)
DBUG_RETURN(false);
@@ -8319,7 +8319,7 @@ bool ha_partition::inplace_alter_table(TABLE *altered_table,
/*
Changing to similar partitioning, only update metadata.
- Non allowed changes would be catched in prep_alter_part_table().
+ Non allowed changes would be caught in prep_alter_part_table().
*/
if (ha_alter_info->alter_info->flags == Alter_info::ALTER_PARTITION)
DBUG_RETURN(false);
@@ -8364,7 +8364,7 @@ bool ha_partition::commit_inplace_alter_table(TABLE *altered_table,
/*
Changing to similar partitioning, only update metadata.
- Non allowed changes would be catched in prep_alter_part_table().
+ Non allowed changes would be caught in prep_alter_part_table().
*/
if (ha_alter_info->alter_info->flags == Alter_info::ALTER_PARTITION)
DBUG_RETURN(false);
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index c2c4ffcda40..e3e4d068568 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -292,7 +292,7 @@ public:
-------------------------------------------------------------------------
MODULE create/delete handler object
-------------------------------------------------------------------------
- Object create/delete methode. The normal called when a table object
+ Object create/delete method. Normally called when a table object
exists. There is also a method to create the handler object with only
partition information. This is used from mysql_create_table when the
table is to be created and the engine type is deduced to be the
@@ -590,7 +590,7 @@ public:
/**
@breif
- Positions an index cursor to the index specified in the hanlde. Fetches the
+ Positions an index cursor to the index specified in the handle. Fetches the
row if available. If the key value is null, begin at first key of the
index.
*/
@@ -805,7 +805,7 @@ public:
HA_REC_NOT_IN_SEQ:
This flag is set for handlers that cannot guarantee that the rows are
- returned accroding to incremental positions (0, 1, 2, 3...).
+ returned according to incremental positions (0, 1, 2, 3...).
This also means that rnd_next() should return HA_ERR_RECORD_DELETED
if it finds a deleted row.
(MyISAM (not fixed length row), HEAP, InnoDB)
diff --git a/sql/handler.cc b/sql/handler.cc
index 79f23c0d200..09ce175e967 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -725,7 +725,7 @@ int ha_end()
/*
- This should be eventualy based on the graceful shutdown flag.
+ This should be eventually based on the graceful shutdown flag.
So if flag is equal to HA_PANIC_CLOSE, the deallocate
the errors.
*/
@@ -1334,8 +1334,8 @@ int ha_commit_trans(THD *thd, bool all)
THD_TRANS *trans= all ? &thd->transaction.all : &thd->transaction.stmt;
/*
"real" is a nick name for a transaction for which a commit will
- make persistent changes. E.g. a 'stmt' transaction inside a 'all'
- transation is not 'real': even though it's possible to commit it,
+ make persistent changes. E.g. a 'stmt' transaction inside an 'all'
+ transaction is not 'real': even though it's possible to commit it,
the changes are not durable as they might be rolled back if the
enclosing 'all' transaction is rolled back.
*/
@@ -2472,7 +2472,7 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root)
/*
TODO: Implement a more efficient way to have more than one index open for
- the same table instance. The ha_open call is not cachable for clone.
+ the same table instance. The ha_open call is not cacheable for clone.
This is not critical as the engines already have the table open
and should be able to use the original instance of the table.
@@ -3254,7 +3254,7 @@ int handler::update_auto_increment()
index_init() or rnd_init() and in any column_bitmaps_signal() call after
this.
- The handler is allowd to do changes to the bitmap after a index_init or
+ The handler is allowed to do changes to the bitmap after a index_init or
rnd_init() call is made as after this, MySQL will not use the bitmap
for any program logic checking.
*/
@@ -3311,7 +3311,7 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
{ // Autoincrement at key-start
error= ha_index_last(table->record[1]);
/*
- MySQL implicitely assumes such method does locking (as MySQL decides to
+ MySQL implicitly assumes such method does locking (as MySQL decides to
use nr+increment without checking again with the handler, in
handler::update_auto_increment()), so reserves to infinite.
*/
@@ -5519,6 +5519,7 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg)
THD *thd= h->table->in_use;
enum icp_result res;
+ DEBUG_SYNC(thd, "handler_index_cond_check");
enum thd_kill_levels abort_at= h->has_transactions() ?
THD_ABORT_SOFTLY : THD_ABORT_ASAP;
if (thd_kill_level(thd) > abort_at)
diff --git a/sql/handler.h b/sql/handler.h
index 057a0e84125..c6cac5dfbbe 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -209,7 +209,7 @@ enum enum_alter_inplace_result {
this flag must implement start_read_removal() and end_read_removal().
The handler may return "fake" rows constructed from the key of the row
asked for. This is used to optimize UPDATE and DELETE by reducing the
- numer of roundtrips between handler and storage engine.
+ number of roundtrips between handler and storage engine.
Example:
UPDATE a=1 WHERE pk IN (<keys>)
@@ -489,7 +489,7 @@ enum enum_binlog_command {
/* Bits in used_fields */
#define HA_CREATE_USED_AUTO (1L << 0)
-#define HA_CREATE_USED_RAID (1L << 1) //RAID is no longer availble
+#define HA_CREATE_USED_RAID (1L << 1) //RAID is no longer available
#define HA_CREATE_USED_UNION (1L << 2)
#define HA_CREATE_USED_INSERT_METHOD (1L << 3)
#define HA_CREATE_USED_MIN_ROWS (1L << 4)
@@ -956,7 +956,7 @@ struct handler_iterator {
/*
Pointer to buffer for the iterator to use.
Should be allocated by function which created the iterator and
- destroied by freed by above "destroy" call
+ destroyed by freed by above "destroy" call
*/
void *buffer;
};
@@ -1172,7 +1172,7 @@ struct handlerton
"cookie".
The flush and call of commit_checkpoint_notify_ha() need not happen
- immediately - it can be scheduled and performed asynchroneously (ie. as
+ immediately - it can be scheduled and performed asynchronously (ie. as
part of next prepare(), or sync every second, or whatever), but should
not be postponed indefinitely. It is however also permissible to do it
immediately, before returning from commit_checkpoint_request().
@@ -1258,13 +1258,13 @@ struct handlerton
Used by open_table_error(), by the default rename_table and delete_table
handler methods, and by the default discovery implementation.
- For engines that have more than one file name extentions (separate
+ For engines that have more than one file name extensions (separate
metadata, index, and/or data files), the order of elements is relevant.
- First element of engine file name extentions array should be metadata
- file extention. This is implied by the open_table_error()
+ First element of engine file name extensions array should be metadata
+ file extension. This is implied by the open_table_error()
and the default discovery implementation.
- Second element - data file extention. This is implied
+ Second element - data file extension. This is implied
assumed by REPAIR TABLE ... USE_FRM implementation.
*/
const char **tablefile_extensions; // by default - empty list
@@ -1760,7 +1760,7 @@ struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
CONVERT TO CHARACTER SET DEFAULT
to
CONVERT TO CHARACTER SET <character-set-of-the-current-database>
- TODO: Should't we postpone resolution of DEFAULT until the
+ TODO: Shouldn't we postpone resolution of DEFAULT until the
character set of the table owner database is loaded from its db.opt?
*/
DBUG_ASSERT(cs);
@@ -2619,7 +2619,7 @@ public:
ha_statistics stats;
/** MultiRangeRead-related members: */
- range_seq_t mrr_iter; /* Interator to traverse the range sequence */
+ range_seq_t mrr_iter; /* Iterator to traverse the range sequence */
RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
@@ -3440,7 +3440,7 @@ public:
This method offers the storage engine, the possibility to store a reference
to a table name which is going to be used with query cache.
The method is called each time a statement is written to the cache and can
- be used to verify if a specific statement is cachable. It also offers
+ be used to verify if a specific statement is cacheable. It also offers
the possibility to register a generic (but static) call back function which
is called each time a statement is matched against the query cache.
diff --git a/sql/item.cc b/sql/item.cc
index a05fafae3b2..8792b1c3f32 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1342,7 +1342,7 @@ err:
bool Item::make_zero_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
/*
- if the item was not null and convertion failed, we return a zero date
+ if the item was not null and conversion failed, we return a zero date
if allowed, otherwise - null.
*/
bzero((char*) ltime,sizeof(*ltime));
@@ -2188,8 +2188,6 @@ bool Item_func_or_sum::agg_item_set_converter(const DTCollation &coll,
Item* conv= (*arg)->safe_charset_converter(thd, coll.collation);
if (conv == *arg)
continue;
- if (!conv && ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII))
- conv= new (thd->mem_root) Item_func_conv_charset(thd, *arg, coll.collation, 1);
if (!conv)
{
@@ -4247,7 +4245,7 @@ static bool mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
@note
We have to mark all items between current_sel (including) and
- last_select (excluding) as dependend (select before last_select should
+ last_select (excluding) as dependent (select before last_select should
be marked with actual table mask used by resolved item, all other with
OUTER_REF_TABLE_BIT) and also write dependence information to Item of
resolved identifier.
@@ -4620,7 +4618,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
bool upward_lookup= FALSE;
TABLE_LIST *table_list;
- /* Calulate the TABLE_LIST for the table */
+ /* Calculate the TABLE_LIST for the table */
table_list= (cached_table ? cached_table :
field_found && (*from_field) != view_ref_found ?
(*from_field)->table->pos_in_table_list : 0);
@@ -5334,7 +5332,7 @@ Item *Item_field::propagate_equal_fields(THD *thd,
but failed to create a valid DATE literal from the given string literal.
Do not do constant propagation in such cases and unlink
- "this" from the found Item_equal (as this equality not usefull).
+ "this" from the found Item_equal (as this equality not useful).
*/
item_equal= NULL;
return this;
@@ -6934,7 +6932,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
/*
Due to cache, find_field_in_tables() can return field which
doesn't belong to provided outer_context. In this case we have
- to find proper field context in order to fix field correcly.
+ to find proper field context in order to fix field correctly.
*/
do
{
@@ -7118,9 +7116,9 @@ Item* Item_ref::transform(THD *thd, Item_transformer transformer, uchar *arg)
callback functions.
First the function applies the analyzer to the Item_ref object. Then
- if the analizer succeeeds we first applies the compile method to the
+ if the analyzer succeeds we first apply the compile method to the
object the Item_ref object is referencing. If this returns a new
- item the old item is substituted for a new one. After this the
+ item the old item is substituted for a new one. After this the
transformer is applied to the Item_ref object itself.
The compile function is not called if the analyzer returns NULL
in the parameter arg_p.
@@ -9578,7 +9576,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
}
/**
- Calculate lenth for merging result for given Item type.
+ Calculate length for merging result for given Item type.
@param item Item for length detection
diff --git a/sql/item.h b/sql/item.h
index 8a90d99db9d..1bf7ad5b87e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -204,7 +204,7 @@ void dummy_error_processor(THD *thd, void *data);
void view_error_processor(THD *thd, void *data);
/*
- Instances of Name_resolution_context store the information necesary for
+ Instances of Name_resolution_context store the information necessary for
name resolution of Items and other context analysis of a query made in
fix_fields().
@@ -362,7 +362,7 @@ public:
Monotonicity is defined only for Item* trees that represent table
partitioning expressions (i.e. have no subselects/user vars/PS parameters
etc etc). An Item* tree is assumed to have the same monotonicity properties
- as its correspoinding function F:
+ as its corresponding function F:
[signed] longlong F(field1, field2, ...) {
put values of field_i into table record buffer;
@@ -701,7 +701,7 @@ protected:
return rc;
}
/*
- This method is used if the item was not null but convertion to
+ This method is used if the item was not null but conversion to
TIME/DATE/DATETIME failed. We return a zero date if allowed,
otherwise - null.
*/
@@ -822,7 +822,7 @@ public:
/*
real_type() is the type of base item. This is same as type() for
most items, except Item_ref() and Item_cache_wrapper() where it
- shows the type for the underlaying item.
+ shows the type for the underlying item.
*/
virtual enum Type real_type() const { return type(); }
@@ -915,7 +915,7 @@ public:
The caller can modify the returned String, if it's not marked
"const" (with the String::mark_as_const() method). That means that
if the item returns its own internal buffer (e.g. tmp_value), it
- *must* be marked "const" [1]. So normally it's preferrable to
+ *must* be marked "const" [1]. So normally it's preferable to
return the result value in the String, that was passed as an
argument. But, for example, SUBSTR() returns a String that simply
points into the buffer of SUBSTR()'s args[0]->val_str(). Such a
@@ -1128,6 +1128,13 @@ public:
a constant expression. Used in the optimizer to propagate basic constants.
*/
virtual bool basic_const_item() const { return 0; }
+ /*
+ Determines if the expression is allowed as
+ a virtual column assignment source:
+ INSERT INTO t1 (vcol) VALUES (10) -> error
+ INSERT INTO t1 (vcol) VALUES (NULL) -> ok
+ */
+ virtual bool vcol_assignment_allowed_value() const { return false; }
/* cloning of constant items (0 if it is not const) */
virtual Item *clone_item(THD *thd) { return 0; }
virtual cond_result eq_cmp_result() const { return COND_OK; }
@@ -1232,7 +1239,7 @@ public:
@param cond_ptr[OUT] Store a replacement item here if the condition
can be simplified, e.g.:
WHERE part1 OR part2 OR part3
- with one of the partN evalutating to SEL_TREE::ALWAYS.
+ with one of the partN evaluating to SEL_TREE::ALWAYS.
*/
virtual SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
/*
@@ -1826,7 +1833,7 @@ public:
virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; }
/**
- Checks if this item or any of its decendents contains a subquery.
+ Checks if this item or any of its descendents contains a subquery.
*/
virtual bool has_subquery() const { return with_subselect; }
@@ -2626,6 +2633,7 @@ public:
collation.set(cs, DERIVATION_IGNORABLE, MY_REPERTOIRE_ASCII);
}
enum Type type() const { return NULL_ITEM; }
+ bool vcol_assignment_allowed_value() const { return true; }
bool eq(const Item *item, bool binary_cmp) const { return null_eq(item); }
double val_real();
longlong val_int();
@@ -2699,6 +2707,8 @@ public:
DECIMAL_VALUE
} state;
+ bool vcol_assignment_allowed_value() const { return state == NULL_VALUE; }
+
/*
A buffer for string and long data values. Historically all allocated
values returned from val_str() were treated as eligible to
@@ -4682,7 +4692,7 @@ public:
This is the method that updates the cached value.
It must be explicitly called by the user of this class to store the value
- of the orginal item in the cache.
+ of the original item in the cache.
*/
virtual void copy() = 0;
@@ -4837,6 +4847,7 @@ public:
(const char *)NULL),
arg(a) {}
enum Type type() const { return DEFAULT_VALUE_ITEM; }
+ bool vcol_assignment_allowed_value() const { return arg == NULL; }
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
virtual void print(String *str, enum_query_type query_type);
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index 22e0680336f..9cf974a2c21 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -140,7 +140,7 @@ bool Cached_item_field::cmp(void)
/*
If value is not null and value changed (from null to not null or
- becasue of value change), then copy the new value to buffer.
+ because of value change), then copy the new value to buffer.
*/
if (! null_value && (tmp || (tmp= (field->cmp(buff) != 0))))
field->get_image(buff,length,field->charset());
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2e029f307fc..61c6b980551 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -745,7 +745,7 @@ Item** Arg_comparator::cache_converted_constant(THD *thd_arg, Item **value,
If the value should be compared as time (TIME_RESULT), it's retrieved as
MYSQL_TIME. Otherwise it's read as a number/string and converted to time.
- Constant items are cached, so the convertion is only done once for them.
+ Constant items are cached, so the conversion is only done once for them.
Note the f_type behavior: if the item can be compared as time, then
f_type is this item's field_type(). Otherwise it's field_type() of
@@ -1425,7 +1425,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
@note
Item_in_optimizer should work as pass-through for
- subqueries that were processed by ALL/ANY->MIN/MAX rewrite
- - subqueries taht were originally EXISTS subqueries (and were coverted by
+ - subqueries that were originally EXISTS subqueries (and were coinverted by
the EXISTS->IN rewrite)
When Item_in_optimizer is not not working as a pass-through, it
@@ -2013,8 +2013,8 @@ longlong Item_func_interval::val_int()
interval_range *range= intervals + mid;
my_bool cmp_result;
/*
- The values in the range intervall may have different types,
- Only do a decimal comparision of the first argument is a decimal
+ The values in the range interval may have different types,
+ Only do a decimal comparison if the first argument is a decimal
and we are comparing against a decimal
*/
if (dec && range->type == DECIMAL_RESULT)
@@ -2696,7 +2696,7 @@ Item_func_nullif::fix_length_and_dec()
Some examples of what NULLIF can end up with after argument
substitution (we don't mention args[1] in some cases for simplicity):
- 1. l_expr is not an aggragate function:
+ 1. l_expr is not an aggregate function:
a. No conversion happened.
args[0] and args[2] were not replaced to something else
@@ -2817,7 +2817,7 @@ Item_func_nullif::fix_length_and_dec()
In this case we remember and reuse m_arg0 during EXECUTE time as args[2].
QQ: How to make sure that m_args0 does not point
- to something temporary which will be destoyed between PREPARE and EXECUTE.
+ to something temporary which will be destroyed between PREPARE and EXECUTE.
The condition below should probably be more strict and somehow check that:
- change_item_tree() was called for the new args[0]
- m_args0 is referenced from inside args[0], e.g. as a function argument,
@@ -3279,7 +3279,7 @@ void Item_func_case::fix_length_and_dec()
If we'll do string comparison, we also need to aggregate
character set and collation for first/WHEN items and
install converters for some of them to cmp_collation when necessary.
- This is done because cmp_item compatators cannot compare
+ This is done because cmp_item comparators cannot compare
strings in two different character sets.
Some examples when we install converters:
@@ -4402,7 +4402,7 @@ void Item_func_in::fix_length_and_dec()
else
{
/*
- We don't put NULL values in array, to avoid erronous matches in
+ We don't put NULL values in array, to avoid erroneous matches in
bisection.
*/
have_null= 1;
@@ -6887,7 +6887,7 @@ Item* Item_equal::get_first(JOIN_TAB *context, Item *field_item)
and not ot2.col.
eliminate_item_equal() also has code that deals with equality substitution
- in presense of SJM nests.
+ in presence of SJM nests.
*/
TABLE_LIST *emb_nest;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index e47b88bdcbb..0ea7fd9d2b0 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -150,7 +150,7 @@ protected:
/*
Return the full select tree for "field_item" and "value":
- a single SEL_TREE if the field is not in a multiple equality, or
- - a conjuction of all SEL_TREEs for all fields from
+ - a conjunction of all SEL_TREEs for all fields from
the same multiple equality with "field_item".
*/
SEL_TREE *get_full_func_mm_tree(RANGE_OPT_PARAM *param,
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 702d8a1a2ee..b4cffc84b80 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
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,7 +109,8 @@ Item_args::Item_args(THD *thd, const Item_args *other)
arg_count= 0;
return;
}
- memcpy(args, other->args, sizeof(Item*) * arg_count);
+ if (arg_count)
+ memcpy(args, other->args, sizeof(Item*) * arg_count);
}
@@ -362,7 +363,7 @@ Item *Item_func::transform(THD *thd, Item_transformer transformer, uchar *argume
callback functions.
First the function applies the analyzer to the root node of
- the Item_func object. Then if the analizer succeeeds (returns TRUE)
+ the Item_func object. Then if the analyzer succeeds (returns TRUE)
the function recursively applies the compile method to each argument
of the Item_func node.
If the call of the method for an argument item returns a new item
@@ -1718,6 +1719,8 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
null_value= 1;
return 0;
}
+ my_decimal_round(E_DEC_FATAL_ERROR, decimal_value,
+ decimals, FALSE, decimal_value);
return decimal_value;
}
@@ -1785,7 +1788,7 @@ void Item_func_div::fix_length_and_dec()
case TIME_RESULT:
DBUG_ASSERT(0);
}
- maybe_null= 1; // devision by zero
+ maybe_null= 1; // division by zero
DBUG_VOID_RETURN;
}
@@ -1833,11 +1836,9 @@ longlong Item_func_int_div::val_int()
raise_integer_overflow();
return res;
}
-
- longlong val0=args[0]->val_int();
- longlong val1=args[1]->val_int();
- bool val0_negative, val1_negative, res_negative;
- ulonglong uval0, uval1, res;
+
+ Longlong_hybrid val0= args[0]->to_longlong_hybrid();
+ Longlong_hybrid val1= args[1]->to_longlong_hybrid();
if ((null_value= (args[0]->null_value || args[1]->null_value)))
return 0;
if (val1 == 0)
@@ -1846,12 +1847,8 @@ longlong Item_func_int_div::val_int()
return 0;
}
- val0_negative= !args[0]->unsigned_flag && val0 < 0;
- val1_negative= !args[1]->unsigned_flag && val1 < 0;
- res_negative= val0_negative != val1_negative;
- uval0= (ulonglong) (val0_negative ? -val0 : val0);
- uval1= (ulonglong) (val1_negative ? -val1 : val1);
- res= uval0 / uval1;
+ bool res_negative= val0.neg() != val1.neg();
+ ulonglong res= val0.abs() / val1.abs();
if (res_negative)
{
if (res > (ulonglong) LONGLONG_MAX)
@@ -1865,7 +1862,7 @@ longlong Item_func_int_div::val_int()
void Item_func_int_div::fix_length_and_dec()
{
Item_result argtype= args[0]->result_type();
- /* use precision ony for the data type it is applicable for and valid */
+ /* use precision only for the data type it is applicable for and valid */
uint32 char_length= args[0]->max_char_length() -
(argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
args[0]->decimals : 0);
@@ -1879,11 +1876,8 @@ void Item_func_int_div::fix_length_and_dec()
longlong Item_func_mod::int_op()
{
DBUG_ASSERT(fixed == 1);
- longlong val0= args[0]->val_int();
- longlong val1= args[1]->val_int();
- bool val0_negative, val1_negative;
- ulonglong uval0, uval1;
- ulonglong res;
+ Longlong_hybrid val0= args[0]->to_longlong_hybrid();
+ Longlong_hybrid val1= args[1]->to_longlong_hybrid();
if ((null_value= args[0]->null_value || args[1]->null_value))
return 0; /* purecov: inspected */
@@ -1898,13 +1892,9 @@ longlong Item_func_mod::int_op()
LONGLONG_MIN by -1 generates SIGFPE, we calculate using unsigned values and
then adjust the sign appropriately.
*/
- val0_negative= !args[0]->unsigned_flag && val0 < 0;
- val1_negative= !args[1]->unsigned_flag && val1 < 0;
- uval0= (ulonglong) (val0_negative ? -val0 : val0);
- uval1= (ulonglong) (val1_negative ? -val1 : val1);
- res= uval0 % uval1;
- return check_integer_overflow(val0_negative ? -(longlong) res : res,
- !val0_negative);
+ ulonglong res= val0.abs() % val1.abs();
+ return check_integer_overflow(val0.neg() ? -(longlong) res : res,
+ !val0.neg());
}
double Item_func_mod::real_op()
@@ -2349,6 +2339,9 @@ void Item_func_int_val::fix_length_and_dec()
if ((args[0]->max_length - args[0]->decimals) >=
(DECIMAL_LONGLONG_DIGITS - 2))
{
+ fix_char_length(
+ my_decimal_precision_to_length_no_truncation(
+ args[0]->decimal_int_part(), 0, false));
set_handler_by_result_type(DECIMAL_RESULT);
}
else
@@ -2532,6 +2525,8 @@ void Item_func_round::fix_length_and_dec()
precision-= decimals_delta - length_increase;
decimals= MY_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ if (!precision)
+ precision= 1; // DECIMAL(0,0) -> DECIMAL(1,0)
max_length= my_decimal_precision_to_length_no_truncation(precision,
decimals,
unsigned_flag);
@@ -2662,19 +2657,20 @@ void Item_func_rand::seed_random(Item *arg)
TODO: do not do reinit 'rand' for every execute of PS/SP if
args[0] is a constant.
*/
- uint32 tmp;
+ uint32 tmp= (uint32) arg->val_int();
#ifdef WITH_WSREP
- THD *thd= current_thd;
- if (WSREP(thd))
+ if (WSREP_ON)
{
- if (thd->wsrep_exec_mode==REPL_RECV)
- tmp= thd->wsrep_rand;
- else
- tmp= thd->wsrep_rand= (uint32) arg->val_int();
- }
- else
+ THD *thd= current_thd;
+ if (thd->variables.wsrep_on)
+ {
+ if (thd->wsrep_exec_mode==REPL_RECV)
+ tmp= thd->wsrep_rand;
+ else
+ thd->wsrep_rand= tmp;
+ }
+ }
#endif /* WITH_WSREP */
- tmp= (uint32) arg->val_int();
my_rnd_init(rand, (uint32) (tmp*0x10001L+55555555L),
(uint32) (tmp*0x10000001L));
@@ -4820,7 +4816,7 @@ bool Item_func_set_user_var::register_field_in_bitmap(uchar *arg)
@param type type of new value
@param cs charset info for new value
@param dv derivation for new value
- @param unsigned_arg indiates if a value of type INT_RESULT is unsigned
+ @param unsigned_arg indicates if a value of type INT_RESULT is unsigned
@note Sets error and fatal error if allocation fails.
@@ -4898,7 +4894,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length,
bool unsigned_arg)
{
/*
- If we set a variable explicitely to NULL then keep the old
+ If we set a variable explicitly to NULL then keep the old
result type of the variable
*/
if ((null_value= args[0]->null_value) && null_item)
@@ -6538,7 +6534,7 @@ void my_missing_function_error(const LEX_STRING &token, const char *func_name)
@brief Initialize the result field by creating a temporary dummy table
and assign it to a newly created field object. Meta data used to
create the field is fetched from the sp_head belonging to the stored
- proceedure found in the stored procedure functon cache.
+ procedure found in the stored procedure function cache.
@note This function should be called from fix_fields to init the result
field. It is some what related to Item_field.
@@ -6842,7 +6838,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
/*
Here we check privileges of the stored routine only during view
creation, in order to validate the view. A runtime check is
- perfomed in Item_func_sp::execute(), and this method is not
+ performed in Item_func_sp::execute(), and this method is not
called during context analysis. Notice, that during view
creation we do not infer into stored routine bodies and do not
check privileges of its statements, which would probably be a
diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc
index 4cf43e075a5..061811b0799 100644
--- a/sql/item_inetfunc.cc
+++ b/sql/item_inetfunc.cc
@@ -206,7 +206,7 @@ String *Item_func_inet_str_base::val_str_ascii(String *buffer)
@return Completion status.
@retval false Given string does not represent an IPv4-address.
- @retval true The string has been converted sucessfully.
+ @retval true The string has been converted successfully.
@note The problem with inet_pton() is that it treats leading zeros in
IPv4-part differently on different platforms.
@@ -331,7 +331,7 @@ static bool str_to_ipv4(const char *str, int str_length, in_addr *ipv4_address)
@return Completion status.
@retval false Given string does not represent an IPv6-address.
- @retval true The string has been converted sucessfully.
+ @retval true The string has been converted successfully.
@note The problem with inet_pton() is that it treats leading zeros in
IPv4-part differently on different platforms.
@@ -677,7 +677,7 @@ static void ipv6_to_str(const in6_addr *ipv6, char *str)
@return Completion status.
@retval false Given string does not represent an IP-address.
- @retval true The string has been converted sucessfully.
+ @retval true The string has been converted successfully.
*/
bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
@@ -717,7 +717,7 @@ bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
@return Completion status.
@retval false The argument does not correspond to IP-address.
- @retval true The string has been converted sucessfully.
+ @retval true The string has been converted successfully.
*/
bool Item_func_inet6_ntoa::calc_value(const String *arg, String *buffer)
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f3e19a19b3c..640242bbcff 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -923,7 +923,7 @@ String *Item_func_concat_ws::val_str(String *str)
goto null; // Must be a blob
}
else if (res2 == &tmp_value)
- { // This can happend only 1 time
+ { // This can happen only 1 time
if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
goto null;
res= &tmp_value;
@@ -1071,7 +1071,7 @@ void Item_func_reverse::fix_length_and_dec()
}
/**
- Replace all occurences of string2 in string1 with string3.
+ Replace all occurrences of string2 in string1 with string3.
Don't reallocate val_str() if not needed.
@@ -3839,7 +3839,7 @@ void Item_func_export_set::fix_length_and_dec()
using in a SQL statement.
Adds a \\ before all characters that needs to be escaped in a SQL string.
- We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
+ We also escape '^Z' (END-OF-FILE in windows) to avoid problems when
running commands from a file in windows.
This function is very useful when you want to generate SQL statements.
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 9ea9ff97016..6989639ae67 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1053,11 +1053,19 @@ public:
/*
Conversion from and to "binary" is safe.
Conversion to Unicode is safe.
+ Conversion from an expression with the ASCII repertoire
+ to any character set that can store characters U+0000..U+007F
+ is safe:
+ - All supported multibyte character sets can store U+0000..U+007F
+ - All supported 7bit character sets can store U+0000..U+007F
+ except those marked with MY_CS_NONASCII (e.g. swe7).
Other kind of conversions are potentially lossy.
*/
safe= (args[0]->collation.collation == &my_charset_bin ||
cs == &my_charset_bin ||
- (cs->state & MY_CS_UNICODE));
+ (cs->state & MY_CS_UNICODE) ||
+ (args[0]->collation.repertoire == MY_REPERTOIRE_ASCII &&
+ (cs->mbmaxlen > 1 || !(cs->state & MY_CS_NONASCII))));
}
}
String *val_str(String *);
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index e3cb82df170..0b28c15027d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1096,12 +1096,12 @@ void Item_singlerow_subselect::reset()
/**
@todo
- - We cant change name of Item_field or Item_ref, because it will
- prevent it's correct resolving, but we should save name of
+ - We can't change name of Item_field or Item_ref, because it will
+ prevent its correct resolving, but we should save name of
removed item => we do not make optimization if top item of
list is field or reference.
- switch off this optimization for prepare statement,
- because we do not rollback this changes.
+ because we do not rollback these changes.
Make rollback for it, or special name resolving mode in 5.0.
@param join Join object of the subquery (i.e. 'child' join).
@@ -1124,8 +1124,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
select_lex->item_list.elements == 1 &&
!select_lex->item_list.head()->with_sum_func &&
/*
- We cant change name of Item_field or Item_ref, because it will
- prevent it's correct resolving, but we should save name of
+ We can't change name of Item_field or Item_ref, because it will
+ prevent its correct resolving, but we should save name of
removed item => we do not make optimization if top item of
list is field or reference.
TODO: solve above problem
@@ -1610,7 +1610,7 @@ longlong Item_exists_subselect::val_int()
Return the result of EXISTS as a string value
Converts the true/false result into a string value.
- Note that currently this cannot be NULL, so if the query exection fails
+ Note that currently this cannot be NULL, so if the query execution fails
it will return 0.
@param decimal_value[out] buffer to hold the resulting string value
@@ -1633,7 +1633,7 @@ String *Item_exists_subselect::val_str(String *str)
Return the result of EXISTS as a decimal value
Converts the true/false result into a decimal value.
- Note that currently this cannot be NULL, so if the query exection fails
+ Note that currently this cannot be NULL, so if the query execution fails
it will return 0.
@param decimal_value[out] Buffer to hold the resulting decimal value
@@ -2015,7 +2015,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
where we want to evaluate the sub query even if f1 would be null.
*/
- subs= func->create_swap(thd, *(optimizer->get_cache()), subs);
+ subs= func->create_swap(thd, expr, subs);
thd->change_item_tree(place, subs);
if (subs->fix_fields(thd, &subs))
DBUG_RETURN(true);
@@ -2135,10 +2135,13 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
}
else
{
+ /*
+ No need to use real_item for the item, as the ref items that are possible
+ in the subquery either belong to views or to the parent select.
+ For such case we need to refer to the reference and not to the original
+ item.
+ */
Item *item= (Item*) select_lex->item_list.head();
- if (item->type() != REF_ITEM ||
- ((Item_ref*)item)->ref_type() != Item_ref::VIEW_REF)
- item= item->real_item();
if (select_lex->table_list.elements)
{
@@ -2277,7 +2280,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
/*
The uncacheable property controls a number of actions, e.g. whether to
save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
- plans with a temp table where the original JOIN was overriden by
+ plans with a temp table where the original JOIN was overridden by
make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
non-correlated subqueries will not appear as such to EXPLAIN.
*/
@@ -2324,7 +2327,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
is_not_null_test(v3))
where is_not_null_test registers NULLs values but reject rows.
- in case when we do not need correct NULL, we have simplier construction:
+ in case when we do not need correct NULL, we have simpler construction:
EXISTS (SELECT ... WHERE where and
(l1 = v1) and
(l2 = v2) and
@@ -2577,7 +2580,7 @@ bool Item_in_subselect::create_in_to_exists_cond(JOIN *join_arg)
/*
The uncacheable property controls a number of actions, e.g. whether to
save/restore (via init_save_join_tab/restore_tmp) the original JOIN for
- plans with a temp table where the original JOIN was overriden by
+ plans with a temp table where the original JOIN was overridden by
make_simple_join. The UNCACHEABLE_EXPLAIN is ignored by EXPLAIN, thus
non-correlated subqueries will not appear as such to EXPLAIN.
*/
@@ -2724,6 +2727,8 @@ bool Item_exists_subselect::select_prepare_to_be_in()
Check if 'func' is an equality in form "inner_table.column = outer_expr"
@param func Expression to check
+ @param allow_subselect If true, the outer_expr part can have a subquery
+ If false, it cannot.
@param local_field OUT Return "inner_table.column" here
@param outer_expr OUT Return outer_expr here
@@ -2731,6 +2736,7 @@ bool Item_exists_subselect::select_prepare_to_be_in()
*/
static bool check_equality_for_exist2in(Item_func *func,
+ bool allow_subselect,
Item_ident **local_field,
Item **outer_exp)
{
@@ -2741,7 +2747,8 @@ static bool check_equality_for_exist2in(Item_func *func,
args= func->arguments();
if (args[0]->real_type() == Item::FIELD_ITEM &&
args[0]->all_used_tables() != OUTER_REF_TABLE_BIT &&
- args[1]->all_used_tables() == OUTER_REF_TABLE_BIT)
+ args[1]->all_used_tables() == OUTER_REF_TABLE_BIT &&
+ (allow_subselect || !args[1]->has_subquery()))
{
/* It is Item_field or Item_direct_view_ref) */
DBUG_ASSERT(args[0]->type() == Item::FIELD_ITEM ||
@@ -2752,7 +2759,8 @@ static bool check_equality_for_exist2in(Item_func *func,
}
else if (args[1]->real_type() == Item::FIELD_ITEM &&
args[1]->all_used_tables() != OUTER_REF_TABLE_BIT &&
- args[0]->all_used_tables() == OUTER_REF_TABLE_BIT)
+ args[0]->all_used_tables() == OUTER_REF_TABLE_BIT &&
+ (allow_subselect || !args[0]->has_subquery()))
{
/* It is Item_field or Item_direct_view_ref) */
DBUG_ASSERT(args[1]->type() == Item::FIELD_ITEM ||
@@ -2781,6 +2789,13 @@ typedef struct st_eq_field_outer
outer1=inner_tbl1.col1 AND ... AND outer2=inner_tbl1.col2 AND remainder_cond
+ if there is just one outer_expr=inner_expr pair, then outer_expr can have a
+ subselect in it. If there are many such pairs, then none of outer_expr can
+ have a subselect in it. If we allow this, the query will fail with an error:
+
+ This version of MariaDB doesn't yet support 'SUBQUERY in ROW in left
+ expression of IN/ALL/ANY'
+
@param conds Condition to be checked
@parm result Array to collect EQ_FIELD_OUTER elements describing
inner-vs-outer equalities the function has found.
@@ -2798,14 +2813,17 @@ static bool find_inner_outer_equalities(Item **conds,
{
List_iterator<Item> li(*((Item_cond*)*conds)->argument_list());
Item *item;
+ bool allow_subselect= true;
while ((item= li++))
{
if (item->type() == Item::FUNC_ITEM &&
check_equality_for_exist2in((Item_func *)item,
+ allow_subselect,
&element.local_field,
&element.outer_exp))
{
found= TRUE;
+ allow_subselect= false;
element.eq_ref= li.ref();
if (result.append(element))
goto alloc_err;
@@ -2814,6 +2832,7 @@ static bool find_inner_outer_equalities(Item **conds,
}
else if ((*conds)->type() == Item::FUNC_ITEM &&
check_equality_for_exist2in((Item_func *)*conds,
+ true,
&element.local_field,
&element.outer_exp))
{
@@ -3175,7 +3194,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join)
/*
In some optimisation cases we will not need this Item_in_optimizer
object, but we can't know it here, but here we need address correct
- reference on left expresion.
+ reference on left expression.
note: we won't need Item_in_optimizer when handling degenerate cases
like "... IN (SELECT 1)"
@@ -3207,7 +3226,7 @@ Item_in_subselect::select_in_like_transformer(JOIN *join)
and all that items do not make permanent changes in current item arena
which allow to us call them with changed arena (if we do not know nature
of Item, we have to call fix_fields() for it only with original arena to
- avoid memory leack)
+ avoid memory leak)
*/
if (left_expr->cols() == 1)
trans_res= single_value_transformer(join);
@@ -3370,7 +3389,7 @@ bool Item_in_subselect::setup_mat_engine()
/*
The select_engine (that executes transformed IN=>EXISTS subselects) is
- pre-created at parse time, and is stored in statment memory (preserved
+ pre-created at parse time, and is stored in statement memory (preserved
across PS executions).
*/
DBUG_ASSERT(engine->engine_type() == subselect_engine::SINGLE_SELECT_ENGINE);
@@ -3830,7 +3849,7 @@ int subselect_single_select_engine::exec()
For at least one of the pushed predicates the following is true:
We should not apply optimizations based on the condition that was
pushed down into the subquery. Those optimizations are ref[_or_null]
- acceses. Change them to be full table scans.
+ accesses. Change them to be full table scans.
*/
JOIN_TAB *tab;
for (tab= first_linear_tab(join, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
@@ -4739,7 +4758,7 @@ subselect_hash_sj_engine::choose_partial_match_strategy(
/*
Choose according to global optimizer switch. If only one of the switches is
'ON', then the remaining strategy is the only possible one. The only cases
- when this will be overriden is when the total size of all buffers for the
+ when this will be overridden is when the total size of all buffers for the
merge strategy is bigger than the 'rowid_merge_buff_size' system variable,
or if there isn't enough physical memory to allocate the buffers.
*/
@@ -6058,7 +6077,7 @@ int subselect_partial_match_engine::exec()
if (has_covering_null_row)
{
/*
- If there is a NULL-only row that coveres all columns the result of IN
+ If there is a NULL-only row that covers all columns the result of IN
is UNKNOWN.
*/
item_in->value= 0;
@@ -6258,7 +6277,7 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
for (uint i= (non_null_key ? 1 : 0); i < merge_keys_count; i++)
{
/*
- Check if the first and only indexed column contains NULL in the curent
+ Check if the first and only indexed column contains NULL in the current
row, and add the row number to the corresponding key.
*/
if (tmp_table->field[merge_keys[i]->get_field_idx(0)]->is_null())
@@ -6469,7 +6488,7 @@ bool subselect_rowid_merge_engine::partial_match()
}
/*
- If all nullable columns contain only NULLs, then there is a guranteed
+ If all nullable columns contain only NULLs, then there is a guaranteed
partial match, and we don't need to search for a matching row.
*/
if (has_covering_null_columns)
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 3be1013e4e3..9771b067ac4 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -131,6 +131,10 @@ public:
Item_subselect(THD *thd);
virtual subs_type substype() { return UNKNOWN_SUBS; }
+ bool is_exists_predicate()
+ {
+ return substype() == Item_subselect::EXISTS_SUBS;
+ }
bool is_in_predicate()
{
return (substype() == Item_subselect::IN_SUBS ||
@@ -541,7 +545,7 @@ public:
bool jtbm_const_row_found;
/*
- TRUE<=>this is a flattenable semi-join, false overwise.
+ TRUE<=>this is a flattenable semi-join, false otherwise.
*/
bool is_flattenable_semijoin;
@@ -964,7 +968,7 @@ class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
bool check_null;
/*
- The "having" clause. This clause (further reffered to as "artificial
+ The "having" clause. This clause (further referred to as "artificial
having") was inserted by subquery transformation code. It contains
Item(s) that have a side-effect: they record whether the subquery has
produced a row with NULL certain components. We need to use it for cases
@@ -985,7 +989,7 @@ class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
However, subqueries like the above are currently not handled by index
lookup-based subquery engines, the engine applicability check misses
them: it doesn't switch the engine for case of artificial having and
- [eq_]ref access (only for artifical having + ref_or_null or no having).
+ [eq_]ref access (only for artificial having + ref_or_null or no having).
The above example subquery is handled as a full-blown SELECT with eq_ref
access to one table.
@@ -1056,7 +1060,7 @@ public:
*/
JOIN *materialize_join;
/*
- A conjunction of all the equality condtions between all pairs of expressions
+ A conjunction of all the equality conditions between all pairs of expressions
that are arguments of an IN predicate. We need these to post-filter some
IN results because index lookups sometimes match values that are actually
not equal to the search key in SQL terms.
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index f5bcd082824..36bb39f14d8 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -527,7 +527,7 @@ Field *Item_sum::create_tmp_field(bool group, TABLE *table)
break;
case ROW_RESULT:
case TIME_RESULT:
- // This case should never be choosen
+ // This case should never be chosen
DBUG_ASSERT(0);
return 0;
}
@@ -717,7 +717,7 @@ calc_tmp_field_type(enum enum_field_types table_field_type,
C_MODE_START
-/* Declarations for auxilary C-callbacks */
+/* Declarations for auxiliary C-callbacks */
int simple_raw_key_cmp(void* arg, const void* key1, const void* key2)
{
@@ -749,7 +749,7 @@ C_MODE_END
@param thd Thread descriptor
@return status
@retval FALSE success
- @retval TRUE faliure
+ @retval TRUE failure
Prepares Aggregator_distinct to process the incoming stream.
Creates the temporary table and the Unique class if needed.
@@ -1215,7 +1215,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
DBUG_ASSERT(0);
};
setup_hybrid(thd, args[0], NULL);
- /* MIN/MAX can return NULL for empty set indepedent of the used column */
+ /* MIN/MAX can return NULL for empty set independent of the used column */
maybe_null= 1;
result_field=0;
null_value=1;
@@ -1630,7 +1630,7 @@ void Item_sum_count::cleanup()
/*
- Avgerage
+ Average
*/
void Item_sum_avg::fix_length_and_dec()
{
@@ -1863,7 +1863,7 @@ void Item_sum_variance::fix_length_and_dec()
/*
According to the SQL2003 standard (Part 2, Foundations; sec 10.9,
aggregate function; paragraph 7h of Syntax Rules), "the declared
- type of the result is an implementation-defined aproximate numeric
+ type of the result is an implementation-defined approximate numeric
type.
*/
@@ -1953,7 +1953,7 @@ double Item_sum_variance::val_real()
is one or zero. If it's zero, i.e. a population variance, then we only
set nullness when the count is zero.
- Another way to read it is that 'sample' is the numerical threshhold, at and
+ Another way to read it is that 'sample' is the numerical threshold, at and
below which a 'count' number of items is called NULL.
*/
DBUG_ASSERT((sample == 0) || (sample == 1));
@@ -3567,7 +3567,7 @@ bool Item_func_group_concat::setup(THD *thd)
{
/*
Force the create_tmp_table() to convert BIT columns to INT
- as we cannot compare two table records containg BIT fields
+ as we cannot compare two table records containing BIT fields
stored in the the tree used for distinct/order by.
Moreover we don't even save in the tree record null bits
where BIT fields store parts of their data.
diff --git a/sql/item_sum.h b/sql/item_sum.h
index cbca701e5b0..6bfa7a39486 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -250,7 +250,7 @@ class st_select_lex;
The field 'aggr_level' is to contain the nest level of the subquery
where the set function is aggregated.
- The field 'max_arg_level' is for the maximun of the nest levels of the
+ The field 'max_arg_level' is for the maximum of the nest levels of the
unbound column references occurred in the set function. A column reference
is unbound within a set function if it is not bound by any subquery
used as a subexpression in this function. A column reference is bound by
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 93889f75f83..de973832402 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -452,7 +452,7 @@ err:
/**
- Create a formated date/time value in a string.
+ Create a formatted date/time value in a string.
*/
static bool make_date_time(const LEX_CSTRING &format, MYSQL_TIME *l_time,
@@ -1028,7 +1028,7 @@ uint week_mode(uint mode)
a date at start of january) In this case one can get 53 for the
first week of next year. This flag ensures that the week is
relevant for the given year. Note that this flag is only
- releveant if WEEK_JANUARY is not set.
+ relevant if WEEK_JANUARY is not set.
If set Week is in range 1-53.
@@ -1337,7 +1337,7 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
if (!(res= args->val_str_ascii(&str_value)))
return (1);
- /* record negative intervalls in interval->neg */
+ /* record negative intervals in interval->neg */
str=res->ptr();
cs= res->charset();
const char *end=str+res->length();
@@ -1599,7 +1599,7 @@ void Item_func_curdate::fix_length_and_dec()
}
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole CURDATE function.
*/
void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -1611,7 +1611,7 @@ void Item_func_curdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME representation for UTC
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
*/
void Item_func_curdate_utc::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -1664,7 +1664,7 @@ static void set_sec_part(ulong sec_part, MYSQL_TIME *ltime, Item *item)
}
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole CURTIME function.
*/
void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -1679,7 +1679,7 @@ void Item_func_curtime_local::store_now_in_TIME(MYSQL_TIME *now_time)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME representation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
*/
void Item_func_curtime_utc::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -1707,7 +1707,7 @@ bool Item_func_now::fix_fields(THD *thd, Item **items)
}
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole NOW function.
*/
void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -1720,7 +1720,7 @@ void Item_func_now_local::store_now_in_TIME(MYSQL_TIME *now_time)
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for UTC
+ Converts current time in my_time_t to MYSQL_TIME representation for UTC
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
*/
void Item_func_now_utc::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -1744,7 +1744,7 @@ bool Item_func_now::get_date(MYSQL_TIME *res,
/**
- Converts current time in my_time_t to MYSQL_TIME represenatation for local
+ Converts current time in my_time_t to MYSQL_TIME representation for local
time zone. Defines time zone (local) used for whole SYSDATE function.
*/
void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
@@ -2055,7 +2055,7 @@ bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
uint not_used;
my_time_tmp= from_tz->TIME_to_gmt_sec(ltime, &not_used);
ulong sec_part= ltime->second_part;
- /* my_time_tmp is guranteed to be in the allowed range */
+ /* my_time_tmp is guaranteed to be in the allowed range */
if (my_time_tmp)
to_tz->gmt_sec_to_TIME(ltime, my_time_tmp);
/* we rely on the fact that no timezone conversion can change sec_part */
@@ -2497,7 +2497,7 @@ void Item_char_typecast::fix_length_and_dec()
uint32 char_length;
/*
We always force character set conversion if cast_cs
- is a multi-byte character set. It garantees that the
+ is a multi-byte character set. It guarantees that the
result of CAST is a well-formed string.
For single-byte character sets we allow just to copy
from the argument. A single-byte character sets string
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index d33cd30a928..caa0415bcac 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -68,7 +68,7 @@ typedef struct my_xml_node_st
} MY_XML_NODE;
-/* Lexical analizer token */
+/* Lexical analyzer token */
typedef struct my_xpath_lex_st
{
int term; /* token type, see MY_XPATH_LEX_XXXXX below */
@@ -797,7 +797,6 @@ String *Item_nodeset_func_attributebyname::val_nodeset(String *nodeset)
String *Item_nodeset_func_predicate::val_nodeset(String *str)
{
Item_nodeset_func *nodeset_func= (Item_nodeset_func*) args[0];
- Item_func *comp_func= (Item_func*)args[1];
uint pos= 0, size;
prepare(str);
size= fltend - fltbeg;
@@ -807,7 +806,7 @@ String *Item_nodeset_func_predicate::val_nodeset(String *str)
((XPathFilter*)(&nodeset_func->context_cache))->append_element(flt->num,
flt->pos,
size);
- if (comp_func->val_int())
+ if (args[1]->val_int())
((XPathFilter*)str)->append_element(flt->num, pos++);
}
return str;
@@ -1079,7 +1078,7 @@ static Item* nametestfunc(MY_XPATH *xpath,
/*
- Tokens consisting of one character, for faster lexical analizer.
+ Tokens consisting of one character, for faster lexical analyzer.
*/
static char simpletok[128]=
{
@@ -1399,7 +1398,7 @@ my_xpath_function(const char *beg, const char *end)
}
-/* Initialize a lex analizer token */
+/* Initialize a lex analyzer token */
static void
my_xpath_lex_init(MY_XPATH_LEX *lex,
const char *str, const char *strend)
@@ -1430,7 +1429,7 @@ my_xdigit(int c)
SYNOPSYS
Scan the next token from the input.
lex->term is set to the scanned token type.
- lex->beg and lex->end are set to the beginnig
+ lex->beg and lex->end are set to the beginning
and to the end of the token.
RETURN
N/A
@@ -1456,7 +1455,7 @@ my_xpath_lex_scan(MY_XPATH *xpath,
(const uchar*) end)) > 0 &&
((ctype & (_MY_L | _MY_U)) || *beg == '_'))
{
- // scan untill the end of the idenfitier
+ // scan until the end of the identifier
for (beg+= length;
(length= xpath->cs->cset->ctype(xpath->cs, &ctype,
(const uchar*) beg,
@@ -1585,7 +1584,7 @@ static int my_xpath_parse_AxisName(MY_XPATH *xpath)
** Grammar rules, according to http://www.w3.org/TR/xpath
** Implemented using recursive descendant method.
** All the following grammar processing functions accept
-** a signle "xpath" argument and return 1 on success and 0 on error.
+** a single "xpath" argument and return 1 on success and 0 on error.
** They also modify "xpath" argument by creating new items.
*/
@@ -2465,7 +2464,7 @@ static int my_xpath_parse_UnaryExpr(MY_XPATH *xpath)
as it is in conflict with abbreviated step.
1 + .123 does not work,
1 + 0.123 does.
- Perhaps it is better to move this code into lex analizer.
+ Perhaps it is better to move this code into lex analyzer.
RETURN
1 - success
@@ -2810,7 +2809,7 @@ append_node(String *str, MY_XML_NODE *node)
SYNOPSYS
A call-back function executed when XML parser
- is entering a tag or an attribue.
+ is entering a tag or an attribute.
Appends the new node into data->pxml.
Increments data->level.
@@ -2846,7 +2845,7 @@ int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len)
SYNOPSYS
A call-back function executed when XML parser
- is entering into a tag or an attribue textual value.
+ is entering into a tag or an attribute textual value.
The value is appended into data->pxml.
RETURN
@@ -2874,7 +2873,7 @@ int xml_value(MY_XML_PARSER *st,const char *attr, size_t len)
SYNOPSYS
A call-back function executed when XML parser
- is leaving a tag or an attribue.
+ is leaving a tag or an attribute.
Decrements data->level.
RETURN
diff --git a/sql/key.cc b/sql/key.cc
index 9c59bdf020a..9b09387885b 100644
--- a/sql/key.cc
+++ b/sql/key.cc
@@ -230,7 +230,7 @@ void key_restore(uchar *to_record, uchar *from_key, KEY *key_info,
{
/*
This in fact never happens, as we have only partial BLOB
- keys yet anyway, so it's difficult to find any sence to
+ keys yet anyway, so it's difficult to find any sense to
restore the part of a record.
Maybe this branch is to be removed, but now we
have to ignore GCov compaining.
@@ -623,8 +623,8 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec)
max length. The exceptions are the BLOB and VARCHAR field types
that take the max length into account.
*/
- if ((result= field->cmp_max(field->ptr+first_diff, field->ptr+sec_diff,
- key_part->length)))
+ if ((result= field->cmp_prefix(field->ptr+first_diff, field->ptr+sec_diff,
+ key_part->length)))
DBUG_RETURN(result);
next_loop:
key_part++;
diff --git a/sql/lex.h b/sql/lex.h
index 3386dbf3de6..e54c0260090 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -23,7 +23,7 @@
#include "lex_symbol.h"
SYM_GROUP sym_group_common= {"", ""};
-SYM_GROUP sym_group_geom= {"Spatial extentions", "HAVE_SPATIAL"};
+SYM_GROUP sym_group_geom= {"Spatial extensions", "HAVE_SPATIAL"};
SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"};
/* We don't want to include sql_yacc.h into gen_lex_hash */
diff --git a/sql/lock.cc b/sql/lock.cc
index 07021bae9ca..43d8b0ce535 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1069,7 +1069,7 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
MDL_request mdl_request;
DBUG_ENTER("make_global_read_lock_block_commit");
/*
- If we didn't succeed lock_global_read_lock(), or if we already suceeded
+ If we didn't succeed lock_global_read_lock(), or if we already succeeded
make_global_read_lock_block_commit(), do nothing.
*/
diff --git a/sql/log.cc b/sql/log.cc
index acf1f8f8a9c..f2fe0d852d1 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2018, Oracle and/or its affiliates.
+/* Copyright (c) 2000, 2012, 2018, Oracle and/or its affiliates.
Copyright (c) 2009, 2019, MariaDB Corporation
This program is free software; you can redistribute it and/or modify
@@ -141,7 +141,7 @@ static rpl_binlog_state rpl_global_gtid_binlog_state;
/**
purge logs, master and slave sides both, related error code
- convertor.
+ converter.
Called from @c purge_error_message(), @c MYSQL_BIN_LOG::reset_logs()
@param res an internal to purging routines error code
@@ -350,7 +350,7 @@ public:
never zero.
This is done while calling the constructor binlog_cache_mngr.
- We cannot set informaton in the constructor binlog_cache_data
+ We cannot set information in the constructor binlog_cache_data
because the space for binlog_cache_mngr is allocated through
a placement new.
@@ -534,9 +534,11 @@ bool LOGGER::is_log_table_enabled(uint log_table_type)
{
switch (log_table_type) {
case QUERY_LOG_SLOW:
- return (table_log_handler != NULL) && global_system_variables.sql_log_slow;
+ return (table_log_handler != NULL) && global_system_variables.sql_log_slow
+ && (log_output_options & LOG_TABLE);
case QUERY_LOG_GENERAL:
- return (table_log_handler != NULL) && opt_log ;
+ return (table_log_handler != NULL) && opt_log
+ && (log_output_options & LOG_TABLE);
default:
DBUG_ASSERT(0);
return FALSE; /* make compiler happy */
@@ -1791,7 +1793,7 @@ binlog_commit_flush_stmt_cache(THD *thd, bool all,
#ifdef WITH_WSREP
if (thd->wsrep_mysql_replicated > 0)
{
- DBUG_ASSERT(WSREP_ON);
+ DBUG_ASSERT(WSREP(thd));
WSREP_DEBUG("avoiding binlog_commit_flush_trx_cache: %d",
thd->wsrep_mysql_replicated);
return 0;
@@ -2431,7 +2433,7 @@ static int find_uniq_filename(char *name, ulong next_log_number)
char buff[FN_REFLEN], ext_buf[FN_REFLEN];
struct st_my_dir *dir_info;
struct fileinfo *file_info;
- ulong max_found, next, number;
+ ulong max_found= 0, next= 0, number= 0;
size_t buf_length, length;
char *start, *end;
int error= 0;
@@ -2457,7 +2459,7 @@ static int find_uniq_filename(char *name, ulong next_log_number)
if (strncmp(file_info->name, start, length) == 0 &&
test_if_number(file_info->name+length, &number,0))
{
- set_if_bigger(max_found,(ulong) number);
+ set_if_bigger(max_found, number);
}
}
my_dirend(dir_info);
@@ -2958,7 +2960,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
mysql_mutex_lock(&LOCK_log);
if (is_open())
- { // Safety agains reopen
+ { // Safety against reopen
int tmp_errno= 0;
char buff[80], *end;
char query_time_buff[22+7], lock_time_buff[22+7];
@@ -3216,7 +3218,7 @@ void MYSQL_BIN_LOG::cleanup()
DBUG_ASSERT(!binlog_xid_count_list.head());
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::cleanup(): Removing xid_list_entry "
"for %s (%lu)", b);
- my_free(b);
+ delete b;
}
mysql_mutex_destroy(&LOCK_log);
@@ -3233,7 +3235,7 @@ void MYSQL_BIN_LOG::cleanup()
/*
Free data for global binlog state.
- We can't do that automaticly as we need to do this before
+ We can't do that automatically as we need to do this before
safemalloc is shut down
*/
if (!is_relay_log)
@@ -3390,6 +3392,8 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
log_type_arg, io_cache_type_arg))
{
sql_print_error("MYSQL_BIN_LOG::open failed to generate new file name.");
+ if (!is_relay_log)
+ goto err;
DBUG_RETURN(1);
}
@@ -3580,17 +3584,9 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
*/
uint off= dirname_length(log_file_name);
uint len= strlen(log_file_name) - off;
- char *entry_mem, *name_mem;
- if (!(new_xid_list_entry = (xid_count_per_binlog *)
- my_multi_malloc(MYF(MY_WME),
- &entry_mem, sizeof(xid_count_per_binlog),
- &name_mem, len,
- NULL)))
+ new_xid_list_entry= new xid_count_per_binlog(log_file_name+off, (int)len);
+ if (!new_xid_list_entry)
goto err;
- memcpy(name_mem, log_file_name+off, len);
- new_xid_list_entry->binlog_name= name_mem;
- new_xid_list_entry->binlog_name_len= len;
- new_xid_list_entry->xid_count= 0;
/*
Find the name for the Initial binlog checkpoint.
@@ -3607,7 +3603,10 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
mysql_mutex_unlock(&LOCK_xid_list);
if (!b)
b= new_xid_list_entry;
- strmake(buf, b->binlog_name, b->binlog_name_len);
+ if (b->binlog_name)
+ strmake(buf, b->binlog_name, b->binlog_name_len);
+ else
+ goto err;
Binlog_checkpoint_log_event ev(buf, len);
DBUG_EXECUTE_IF("crash_before_write_checkpoint_event",
flush_io_cache(&log_file);
@@ -3711,7 +3710,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
{
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Removing xid_list_entry for "
"%s (%lu)", b);
- my_free(binlog_xid_count_list.get());
+ delete binlog_xid_count_list.get();
}
mysql_cond_broadcast(&COND_xid_list);
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::open(): Adding new xid_list_entry for "
@@ -3756,9 +3755,9 @@ err:
sql_print_error("Could not use %s for logging (error %d). \
Turning logging off for the whole duration of the MySQL server process. \
To turn it on again: fix the cause, \
-shutdown the MySQL server and restart it.", name, errno);
+shutdown the MySQL server and restart it.", (name) ? name : log_name, errno);
if (new_xid_list_entry)
- my_free(new_xid_list_entry);
+ delete new_xid_list_entry;
if (file >= 0)
mysql_file_close(file, MYF(0));
close(LOG_CLOSE_INDEX);
@@ -4007,7 +4006,7 @@ err:
/**
- Delete all logs refered to in the index file.
+ Delete all logs referred to in the index file.
The new index file will only contain this file.
@@ -4252,7 +4251,7 @@ err:
DBUG_ASSERT(b->xid_count == 0);
WSREP_XID_LIST_ENTRY("MYSQL_BIN_LOG::reset_logs(): Removing "
"xid_list_entry for %s (%lu)", b);
- my_free(binlog_xid_count_list.get());
+ delete binlog_xid_count_list.get();
}
mysql_cond_broadcast(&COND_xid_list);
reset_master_pending--;
@@ -4409,7 +4408,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
/*
* Need to update the log pos because purge logs has been called
- * after fetching initially the log pos at the begining of the method.
+ * after fetching initially the log pos at the beginning of the method.
*/
if ((errcode= find_log_pos(&rli->linfo, rli->event_relay_log_name, 0)))
{
@@ -5566,7 +5565,7 @@ binlog_cache_mngr *THD::binlog_setup_trx_data()
- Start a statement transaction to allow us to truncate the cache.
- - Save the currrent binlog position so that we can roll back the
+ - Save the current binlog position so that we can roll back the
statement by truncating the cache.
We only update the saved position if the old one was undefined,
@@ -6617,14 +6616,15 @@ int MYSQL_BIN_LOG::rotate(bool force_rotate, bool* check_purge)
int error= 0;
DBUG_ENTER("MYSQL_BIN_LOG::rotate");
- if (wsrep_to_isolation)
+#ifdef WITH_WSREP
+ if (WSREP_ON && wsrep_to_isolation)
{
- DBUG_ASSERT(WSREP_ON);
*check_purge= false;
- WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d",
+ WSREP_DEBUG("avoiding binlog rotate due to TO isolation: %d",
wsrep_to_isolation);
DBUG_RETURN(0);
}
+#endif /* WITH_WSREP */
//todo: fix the macro def and restore safe_mutex_assert_owner(&LOCK_log);
*check_purge= false;
@@ -6745,7 +6745,7 @@ static const char* get_first_binlog(char* buf_arg)
}
if (normalize_binlog_name(buf_arg, fname, false))
{
- errmsg= "cound not normalize the first file name in the binlog index";
+ errmsg= "could not normalize the first file name in the binlog index";
goto end;
}
end:
@@ -9708,7 +9708,7 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
than compare all found against each other to find the one pointing to the
most recent binlog.
- Note also that we need to first release LOCK_xid_list, then aquire
+ Note also that we need to first release LOCK_xid_list, then acquire
LOCK_log, then re-aquire LOCK_xid_list. If we were to take LOCK_log while
holding LOCK_xid_list, we might deadlock with other threads that take the
locks in the opposite order.
@@ -9736,7 +9736,7 @@ TC_LOG_BINLOG::mark_xid_done(ulong binlog_id, bool write_checkpoint)
break;
WSREP_XID_LIST_ENTRY("TC_LOG_BINLOG::mark_xid_done(): Removing "
"xid_list_entry for %s (%lu)", b);
- my_free(binlog_xid_count_list.get());
+ delete binlog_xid_count_list.get();
}
mysql_mutex_unlock(&LOCK_xid_list);
@@ -9782,7 +9782,7 @@ TC_LOG_BINLOG::commit_checkpoint_notify(void *cookie)
necessary stuff.
In the future, this thread could also be used to do log rotation in the
- background, which could elimiate all stalls around binlog rotations.
+ background, which could eliminate all stalls around binlog rotations.
*/
pthread_handler_t
binlog_background_thread(void *arg __attribute__((unused)))
diff --git a/sql/log.h b/sql/log.h
index b4c9b24a3a9..277e5c6f69c 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -587,7 +587,18 @@ public:
long xid_count;
/* For linking in requests to the binlog background thread. */
xid_count_per_binlog *next_in_queue;
- xid_count_per_binlog(); /* Give link error if constructor used. */
+ xid_count_per_binlog(char *log_file_name, uint log_file_name_len)
+ :binlog_id(0), xid_count(0)
+ {
+ binlog_name_len= log_file_name_len;
+ binlog_name= (char *) my_malloc(binlog_name_len, MYF(MY_ZEROFILL));
+ if (binlog_name)
+ memcpy(binlog_name, log_file_name, binlog_name_len);
+ }
+ ~xid_count_per_binlog()
+ {
+ my_free(binlog_name);
+ }
};
I_List<xid_count_per_binlog> binlog_xid_count_list;
mysql_mutex_t LOCK_binlog_background_thread;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index e8881c77f2b..146d8bd5dbe 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2019, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
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
@@ -1632,7 +1632,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
else
DBUG_RETURN(NULL);
#else
- *error= ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
+ *error= ER_THD_OR_DEFAULT(current_thd, ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
sql_print_error("%s", *error);
DBUG_RETURN(NULL);
#endif
@@ -2575,13 +2575,20 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
"Not enough metadata to display the value. ");
break;
+ case MYSQL_TYPE_GEOMETRY:
+ strmake(typestr, "GEOMETRY", typestr_length);
+ if (!ptr)
+ goto return_null;
+
+ length= uint4korr(ptr);
+ my_b_write_quoted(file, ptr + meta, length);
+ return length + meta;
+
default:
{
- char tmp[5];
- my_snprintf(tmp, sizeof(tmp), "%04x", meta);
- my_b_printf(file,
- "!! Don't know how to handle column type=%d meta=%d (%s)",
- type, meta, tmp);
+ fprintf(stderr,
+ "\nError: Don't know how to handle column type: %d meta: %d (%04x)\n",
+ type, meta, meta);
}
break;
}
@@ -2865,10 +2872,10 @@ void Log_event::print_base64(IO_CACHE* file,
default:
break;
}
-
+
if (ev)
{
- ev->print_verbose(file, print_event_info);
+ ev->print_verbose(&print_event_info->tail_cache, print_event_info);
delete ev;
}
}
@@ -3444,7 +3451,7 @@ get_str_len_and_pointer(const Log_event::Byte **src,
const Log_event::Byte *end)
{
if (*src >= end)
- return -1; // Will be UINT_MAX in two-complement arithmetics
+ return -1; // Will be UINT_MAX in two-complement arithmetic
uint length= **src;
if (length > 0)
{
@@ -3810,7 +3817,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
/* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
- start[data_len]= '\0'; // End query with \0 (For safetly)
+ start[data_len]= '\0'; // End query with \0 (For safety)
db= (char *)start;
query= (char *)(start + db_len + 1);
q_len= data_len - db_len -1;
@@ -4770,7 +4777,7 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
}
}
#ifdef WITH_WSREP
- else if (WSREP_ON && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
+ else if (WSREP(thd) && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
thd->wsrep_mysql_replicated > 0 &&
(is_begin() || is_commit()))
{
@@ -4784,7 +4791,7 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
thd->wsrep_mysql_replicated = 0;
}
}
-#endif
+#endif /* WITH_WSREP */
DBUG_RETURN(Log_event::do_shall_skip(rgi));
}
@@ -5403,7 +5410,7 @@ int Format_description_log_event::do_update_pos(rpl_group_info *rgi)
If we do not skip stepping the group log position (and the
server id was changed when restarting the server), it might well
be that we start executing at a position that is invalid, e.g.,
- at a Rows_log_event or a Query_log_event preceeded by a
+ at a Rows_log_event or a Query_log_event preceded by a
Intvar_log_event instead of starting at a Table_map_log_event or
the Intvar_log_event respectively.
*/
@@ -5515,7 +5522,7 @@ Format_description_log_event::is_version_before_checksum(const master_version_sp
@return the version-safe checksum alg descriptor where zero
designates no checksum, 255 - the orginator is
- checksum-unaware (effectively no checksum) and the actuall
+ checksum-unaware (effectively no checksum) and the actual
[1-254] range alg descriptor.
*/
enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len)
@@ -5902,7 +5909,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
{
DBUG_ENTER("Load_log_event::copy_log_event");
uint data_len;
- if ((int) event_len < body_offset)
+ if ((int) event_len <= body_offset)
DBUG_RETURN(1);
char* buf_end = (char*)buf + event_len;
/* this is the beginning of the post-header */
@@ -6221,7 +6228,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
/*
When replication is running fine, if it was DUP_ERROR on the
master then we could choose IGNORE here, because if DUP_ERROR
- suceeded on master, and data is identical on the master and slave,
+ succeeded on master, and data is identical on the master and slave,
then there should be no uniqueness errors on slave, so IGNORE is
the same as DUP_ERROR. But in the unlikely case of uniqueness errors
(because the data on the master and slave happen to be different
@@ -6754,7 +6761,7 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg,
/*
Used to record GTID while sending binlog to slave, without having to
- fully contruct every Gtid_log_event() needlessly.
+ fully construct every Gtid_log_event() needlessly.
*/
bool
Gtid_log_event::peek(const char *event_start, size_t event_len,
@@ -7276,7 +7283,7 @@ Gtid_list_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
/*
Used to record gtid_list event while sending binlog to slave, without having to
- fully contruct the event object.
+ fully construct the event object.
*/
bool
Gtid_list_log_event::peek(const char *event_start, uint32 event_len,
@@ -7356,7 +7363,7 @@ Intvar_log_event::Intvar_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- /* The Post-Header is empty. The Varible Data part begins immediately. */
+ /* The Post-Header is empty. The Variable Data part begins immediately. */
buf+= description_event->common_header_len +
description_event->post_header_len[INTVAR_EVENT-1];
type= buf[I_TYPE_OFFSET];
@@ -7755,7 +7762,7 @@ Xid_log_event::do_shall_skip(rpl_group_info *rgi)
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
}
#ifdef WITH_WSREP
- else if (wsrep_mysql_replication_bundle && WSREP_ON &&
+ else if (WSREP(thd) && wsrep_mysql_replication_bundle &&
opt_slave_domain_parallel_threads == 0)
{
if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
@@ -8135,7 +8142,7 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
return;
str_to_hex(hex_str, val, val_len);
/*
- For proper behaviour when mysqlbinlog|mysql, we need to explicitely
+ For proper behaviour when mysqlbinlog|mysql, we need to explicitly
specify the variable's collation. It will however cause problems when
people want to mysqlbinlog|mysql into another server not supporting the
character set. But there's not much to do about this and it's unlikely.
@@ -8584,7 +8591,7 @@ void Create_file_log_event::pack_info(Protocol *protocol)
/**
Create_file_log_event::do_apply_event()
- Constructor for Create_file_log_event to intantiate an event
+ Constructor for Create_file_log_event to instantiate an event
from the relay log on the slave.
@retval
@@ -9535,6 +9542,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
uint8 const post_header_len= description_event->post_header_len[event_type-1];
+ if (event_len < (uint)(common_header_len + post_header_len))
+ {
+ m_cols.bitmap= 0;
+ DBUG_VOID_RETURN;
+ }
+
DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
"post_header_len: %d",
event_len, common_header_len,
@@ -9623,7 +9636,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
DBUG_VOID_RETURN;
}
- /* if my_bitmap_init fails, catched in is_valid() */
+ /* if my_bitmap_init fails, caught in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
m_width,
@@ -10004,7 +10017,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
*/
{
- DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
+ DBUG_PRINT("debug", ("Checking compatibility of tables to lock - tables_to_lock: %p",
rgi->tables_to_lock));
/**
@@ -10059,7 +10072,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
ptr->table->s->table_name.str));
/*
We should not honour --slave-skip-errors at this point as we are
- having severe errors which should not be skiped.
+ having severe errors which should not be skipped.
*/
thd->is_slave_error= 1;
/* remove trigger's tables */
@@ -10440,7 +10453,7 @@ static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD * thd)
/**
The method either increments the relay log position or
commits the current statement and increments the master group
- possition if the event is STMT_END_F flagged and
+ position if the event is STMT_END_F flagged and
the statement corresponds to the autocommit query (i.e replicated
without wrapping in BEGIN/COMMIT)
@@ -10549,7 +10562,7 @@ void Rows_log_event::pack_info(Protocol *protocol)
#ifdef MYSQL_CLIENT
/**
Print an event "body" cache to @c file possibly in two fragments.
- Each fragement is optionally per @c do_wrap to produce an SQL statement.
+ Each fragment is optionally per @c do_wrap to produce an SQL statement.
@param file a file to print to
@param body the "body" IO_CACHE of event
@@ -10665,6 +10678,7 @@ void Rows_log_event::print_helper(FILE *file,
{
IO_CACHE *const head= &print_event_info->head_cache;
IO_CACHE *const body= &print_event_info->body_cache;
+ IO_CACHE *const tail= &print_event_info->tail_cache;
bool do_print_encoded=
print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
!print_event_info->short_form;
@@ -10688,6 +10702,11 @@ void Rows_log_event::print_helper(FILE *file,
}
copy_cache_to_file_wrapped(file, body, do_print_encoded,
print_event_info->delimiter);
+ if (copy_event_cache_to_file_and_reinit(tail, file))
+ {
+ tail->error= -1;
+ return;
+ }
}
}
#endif
@@ -11043,6 +11062,7 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
const char *post_start= buf + common_header_len;
post_start+= TM_MAPID_OFFSET;
+ VALIDATE_BYTES_READ(post_start, buf, event_len);
if (post_header_len == 6)
{
/* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
@@ -12170,7 +12190,7 @@ record_compare_exit:
Find the best key to use when locating the row in @c find_row().
A primary key is preferred if it exists; otherwise a unique index is
- preferred. Else we pick the index with the smalles rec_per_key value.
+ preferred. Else we pick the index with the smallest rec_per_key value.
If a suitable key is found, set @c m_key, @c m_key_nr and @c m_key_info
member fields appropriately.
@@ -12303,7 +12323,7 @@ static int row_not_found_error(rpl_group_info *rgi)
Locate the current row in event's table.
The current row is pointed by @c m_curr_row. Member @c m_width tells
- how many columns are there in the row (this can be differnet from
+ how many columns are there in the row (this can be different from
the number of columns in the table). It is assumed that event's
table is already open and pointed by @c m_table.
@@ -12344,7 +12364,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
rpl_row_tabledefs.test specifies that
if the extra field on the slave does not have a default value
and this is okay with Delete or Update events.
- Todo: fix wl3228 hld that requires defauls for all types of events
+ Todo: fix wl3228 hld that requires defaults for all types of events
*/
prepare_record(table, m_width, FALSE);
@@ -12588,7 +12608,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
while (record_compare(table));
/*
- Note: above record_compare will take into accout all record fields
+ Note: above record_compare will take into account all record fields
which might be incorrect in case a partial row was given in the event
*/
@@ -13213,6 +13233,7 @@ st_print_event_info::st_print_event_info()
myf const flags = MYF(MY_WME | MY_NABP);
open_cached_file(&head_cache, NULL, NULL, 0, flags);
open_cached_file(&body_cache, NULL, NULL, 0, flags);
+ open_cached_file(&tail_cache, NULL, NULL, 0, flags);
}
#endif
diff --git a/sql/log_event.h b/sql/log_event.h
index 2c8dc3d7353..58e1281c179 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -452,7 +452,7 @@ class String;
/**
@def LOG_EVENT_ARTIFICIAL_F
- Artificial events are created arbitarily and not written to binary
+ Artificial events are created arbitrarily and not written to binary
log
These events should not update the master log position when slave
@@ -781,9 +781,12 @@ typedef struct st_print_event_info
~st_print_event_info() {
close_cached_file(&head_cache);
close_cached_file(&body_cache);
+ close_cached_file(&tail_cache);
}
bool init_ok() /* tells if construction was successful */
- { return my_b_inited(&head_cache) && my_b_inited(&body_cache); }
+ { return my_b_inited(&head_cache) &&
+ my_b_inited(&body_cache) &&
+ my_b_inited(&tail_cache); }
/* Settings on how to print the events */
@@ -811,6 +814,7 @@ typedef struct st_print_event_info
*/
IO_CACHE head_cache;
IO_CACHE body_cache;
+ IO_CACHE tail_cache;
} PRINT_EVENT_INFO;
#endif
@@ -854,13 +858,13 @@ private:
};
/**
- the struct aggregates two paramenters that identify an event
+ the struct aggregates two parameters that identify an event
uniquely in scope of communication of a particular master and slave couple.
I.e there can not be 2 events from the same staying connected master which
have the same coordinates.
@note
Such identifier is not yet unique generally as the event originating master
- is resetable. Also the crashed master can be replaced with some other.
+ is resettable. Also the crashed master can be replaced with some other.
*/
typedef struct event_coordinates
{
@@ -2057,7 +2061,15 @@ public: /* !!! Public in this patch to allow old usage */
****************************************************************************/
struct sql_ex_info
{
- sql_ex_info() {} /* Remove gcc warning */
+ sql_ex_info():
+ cached_new_format(-1),
+ field_term_len(0),
+ enclosed_len(0),
+ line_term_len(0),
+ line_start_len(0),
+ escaped_len(0),
+ empty_flags(0)
+ {} /* Remove gcc warning */
const char* field_term;
const char* enclosed;
const char* line_term;
@@ -2586,7 +2598,7 @@ public:
uint8 number_of_event_types;
/*
The list of post-headers' lengths followed
- by the checksum alg decription byte
+ by the checksum alg description byte
*/
uint8 *post_header_len;
struct master_version_split {
@@ -2926,7 +2938,7 @@ public:
*/
bool is_deferred() { return deferred; }
/*
- In case of the deffered applying the variable instance is flagged
+ In case of the deferred applying the variable instance is flagged
and the parsing time query id is stored to be used at applying time.
*/
void set_deferred(query_id_t qid) { deferred= true; query_id= qid; }
@@ -3420,7 +3432,7 @@ public:
bool write_data_header();
bool write_data_body();
/*
- Cut out Create_file extentions and
+ Cut out Create_file extensions and
write it as Load event - used on the slave
*/
bool write_base();
@@ -4730,7 +4742,7 @@ protected:
/**
@class Incident_log_event
- Class representing an incident, an occurance out of the ordinary,
+ Class representing an incident, an occurence out of the ordinary,
that happened on the master.
The event is used to inform the slave that something out of the
@@ -4774,7 +4786,7 @@ public:
m_message.str= NULL; /* Just as a precaution */
m_message.length= 0;
set_direct_logging();
- /* Replicate the incident irregardless of @@skip_replication. */
+ /* Replicate the incident regardless of @@skip_replication. */
flags&= ~LOG_EVENT_SKIP_REPLICATION_F;
DBUG_VOID_RETURN;
}
@@ -4795,7 +4807,7 @@ public:
strmake(m_message.str, msg.str, msg.length);
m_message.length= msg.length;
set_direct_logging();
- /* Replicate the incident irregardless of @@skip_replication. */
+ /* Replicate the incident regardless of @@skip_replication. */
flags&= ~LOG_EVENT_SKIP_REPLICATION_F;
DBUG_VOID_RETURN;
}
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index f70fa3605d6..8f4f6c296c4 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -846,7 +846,7 @@ int Write_rows_log_event_old::do_after_row_operations(TABLE *table, int error)
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
/*
- reseting the extra with
+ resetting the extra with
table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
fires bug#27077
todo: explain or fix
@@ -1238,7 +1238,7 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len,
DBUG_VOID_RETURN;
}
- /* if my_bitmap_init fails, catched in is_valid() */
+ /* if my_bitmap_init fails, caught in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
m_width,
@@ -1856,6 +1856,7 @@ void Old_rows_log_event::print_helper(FILE *file,
{
IO_CACHE *const head= &print_event_info->head_cache;
IO_CACHE *const body= &print_event_info->body_cache;
+ IO_CACHE *const tail= &print_event_info->tail_cache;
bool do_print_encoded=
print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
!print_event_info->short_form;
@@ -1879,6 +1880,11 @@ void Old_rows_log_event::print_helper(FILE *file,
}
copy_cache_to_file_wrapped(file, body, do_print_encoded,
print_event_info->delimiter);
+ if (copy_event_cache_to_file_and_reinit(tail, file))
+ {
+ tail->error= -1;
+ return;
+ }
}
}
#endif
diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc
index c6912e41f6e..022ba18a3e3 100644
--- a/sql/mysql_install_db.cc
+++ b/sql/mysql_install_db.cc
@@ -399,8 +399,8 @@ static int register_service()
static void clean_directory(const char *dir)
{
- char dir2[MAX_PATH+2];
- *(strmake_buf(dir2, dir)+1)= 0;
+ char dir2[MAX_PATH + 4]= {};
+ snprintf(dir2, MAX_PATH+2, "%s\\*", dir);
SHFILEOPSTRUCT fileop;
fileop.hwnd= NULL; /* no status display */
@@ -551,7 +551,7 @@ static int create_db_instance()
DWORD cwd_len= MAX_PATH;
char cmdline[3*MAX_PATH];
FILE *in;
- bool cleanup_datadir= true;
+ bool created_datadir= false;
DWORD last_error;
verbose("Running bootstrap");
@@ -560,7 +560,11 @@ static int create_db_instance()
/* Create datadir and datadir/mysql, if they do not already exist. */
- if (!CreateDirectory(opt_datadir, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
+ if (CreateDirectory(opt_datadir, NULL))
+ {
+ created_datadir= true;
+ }
+ else if (GetLastError() != ERROR_ALREADY_EXISTS)
{
last_error = GetLastError();
switch(last_error)
@@ -597,9 +601,11 @@ static int create_db_instance()
}
}
- if (PathIsDirectoryEmpty(opt_datadir))
+ if (!PathIsDirectoryEmpty(opt_datadir))
{
- cleanup_datadir= false;
+ fprintf(stderr,"ERROR : Data directory %s is not empty."
+ " Only new or empty existing directories are accepted for --datadir\n",opt_datadir);
+ exit(1);
}
if (!CreateDirectory("mysql",NULL))
@@ -735,10 +741,12 @@ static int create_db_instance()
}
end:
- if (ret && cleanup_datadir)
+ if (ret)
{
SetCurrentDirectory(cwd);
clean_directory(opt_datadir);
+ if (created_datadir)
+ RemoveDirectory(opt_datadir);
}
return ret;
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 9a6aa2676d7..8d00b5af948 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2008, 2018, MariaDB
+ Copyright (c) 2008, 2020, MariaDB
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
@@ -3974,7 +3974,8 @@ rpl_make_log_name(const char *opt,
const char *ext)
{
DBUG_ENTER("rpl_make_log_name");
- DBUG_PRINT("enter", ("opt: %s, def: %s, ext: %s", opt, def, ext));
+ DBUG_PRINT("enter", ("opt: %s, def: %s, ext: %s", opt ? opt : "(null)",
+ def, ext));
char buff[FN_REFLEN];
const char *base= opt ? opt : def;
unsigned int options=
@@ -4538,8 +4539,10 @@ static int init_common_variables()
get corrupted if accesses with names of different case.
*/
DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
+ if(mysql_real_data_home_ptr == NULL || *mysql_real_data_home_ptr == 0)
+ mysql_real_data_home_ptr= mysql_real_data_home;
SYSVAR_AUTOSIZE(lower_case_file_system,
- test_if_case_insensitive(mysql_real_data_home));
+ test_if_case_insensitive(mysql_real_data_home_ptr));
if (!lower_case_table_names && lower_case_file_system == 1)
{
if (lower_case_table_names_used)
@@ -4556,7 +4559,7 @@ static int init_common_variables()
{
if (global_system_variables.log_warnings)
sql_print_warning("Setting lower_case_table_names=2 because file "
- "system for %s is case insensitive", mysql_real_data_home);
+ "system for %s is case insensitive", mysql_real_data_home_ptr);
SYSVAR_AUTOSIZE(lower_case_table_names, 2);
}
}
@@ -4567,7 +4570,7 @@ static int init_common_variables()
sql_print_warning("lower_case_table_names was set to 2, even though your "
"the file system '%s' is case sensitive. Now setting "
"lower_case_table_names to 0 to avoid future problems.",
- mysql_real_data_home);
+ mysql_real_data_home_ptr);
SYSVAR_AUTOSIZE(lower_case_table_names, 0);
}
else
@@ -5772,8 +5775,10 @@ int mysqld_main(int argc, char **argv)
set_user(mysqld_user, user_info);
}
+#ifdef WITH_WSREP
if (WSREP_ON && wsrep_check_opts())
global_system_variables.wsrep_on= 0;
+#endif
if (opt_bin_log && !global_system_variables.server_id)
{
@@ -8415,9 +8420,9 @@ SHOW_VAR status_vars[]= {
{"Key", (char*) &show_default_keycache, SHOW_FUNC},
{"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
{"Max_statement_time_exceeded", (char*) offsetof(STATUS_VAR, max_statement_time_exceeded), SHOW_LONG_STATUS},
- {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONGLONG_STATUS},
- {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONGLONG_STATUS},
- {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONGLONG_STATUS},
+ {"Master_gtid_wait_count", (char*) offsetof(STATUS_VAR, master_gtid_wait_count), SHOW_LONG_STATUS},
+ {"Master_gtid_wait_timeouts", (char*) offsetof(STATUS_VAR, master_gtid_wait_timeouts), SHOW_LONG_STATUS},
+ {"Master_gtid_wait_time", (char*) offsetof(STATUS_VAR, master_gtid_wait_time), SHOW_LONG_STATUS},
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
{"Memory_used", (char*) &show_memory_used, SHOW_SIMPLE_FUNC},
{"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH},
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index ea5e4353c83..22eee6297c9 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2012, 2017, MariaDB Corporation
+ Copyright (c) 2012, 2020, MariaDB Corporation.
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
@@ -577,7 +577,8 @@ net_write_buff(NET *net, const uchar *packet, ulong len)
return net_real_write(net, packet, len) ? 1 : 0;
/* Send out rest of the blocks as full sized blocks */
}
- memcpy((char*) net->write_pos,packet,len);
+ if (len)
+ memcpy((char*) net->write_pos,packet,len);
net->write_pos+= len;
return 0;
}
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 7e987c3cfba..e0eefe167ce 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -358,7 +358,7 @@ QUICK_RANGE_SELECT *get_quick_select(PARAM *param,uint index,
uint mrr_buf_size, MEM_ROOT *alloc);
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
- bool update_tbl_stats,
+ bool for_range_access,
double read_time);
static
TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree,
@@ -4710,6 +4710,7 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
sizeof(TRP_RANGE*)*
n_child_scans)))
DBUG_RETURN(NULL);
+
/*
Collect best 'range' scan for each of disjuncts, and, while doing so,
analyze possibility of ROR scans. Also calculate some values needed by
@@ -4721,7 +4722,8 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
{
DBUG_EXECUTE("info", print_sel_tree(param, *ptree, &(*ptree)->keys_map,
"tree in SEL_IMERGE"););
- if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE, read_time)))
+ if (!(*cur_child= get_key_scans_params(param, *ptree, TRUE, FALSE,
+ read_time)))
{
/*
One of index scans in this index_merge is more expensive than entire
@@ -5041,9 +5043,12 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge,
a random order
2. the functions that estimate the cost of a range scan and an
index merge retrievals are not well calibrated
+
+ As the best range access has been already chosen it does not
+ make sense to evaluate the one obtained from a degenerated
+ index merge.
*/
- trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE,
- read_time);
+ trp= 0;
}
DBUG_RETURN(trp);
@@ -6770,6 +6775,8 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
tree make range select for this SEL_TREE
index_read_must_be_used if TRUE, assume 'index only' option will be set
(except for clustered PK indexes)
+ for_range_access if TRUE the function is called to get the best range
+ plan for range access, not for index merge access
read_time don't create read plans with cost > read_time.
RETURN
Best range read plan
@@ -6778,7 +6785,7 @@ TRP_ROR_INTERSECT *get_best_covering_ror_intersect(PARAM *param,
static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
bool index_read_must_be_used,
- bool update_tbl_stats,
+ bool for_range_access,
double read_time)
{
uint idx, best_idx;
@@ -6824,9 +6831,16 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
(bool) param->table->covering_keys.is_set(keynr);
found_records= check_quick_select(param, idx, read_index_only, key,
- update_tbl_stats, &mrr_flags,
+ for_range_access, &mrr_flags,
&buf_size, &cost);
+ if (!for_range_access && !param->is_ror_scan &&
+ !optimizer_flag(param->thd,OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION))
+ {
+ /* The scan is not a ROR-scan, just skip it */
+ continue;
+ }
+
if (found_records != HA_POS_ERROR && tree->index_scans &&
(index_scan= (INDEX_SCAN_INFO *)alloc_root(param->mem_root,
sizeof(INDEX_SCAN_INFO))))
@@ -8865,7 +8879,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag)
if (key2->next_key_part)
{
key1->use_count--; // Incremented in and_all_keys
- return and_all_keys(param, key1, key2, clone_flag);
+ return and_all_keys(param, key1, key2->next_key_part, clone_flag);
}
key2->use_count--; // Key2 doesn't have a tree
}
diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc
index 5d62ceda7d4..b1894f4b6c4 100644
--- a/sql/opt_range_mrr.cc
+++ b/sql/opt_range_mrr.cc
@@ -73,6 +73,7 @@ range_seq_t sel_arg_range_seq_init(void *init_param, uint n_ranges, uint flags)
{
SEL_ARG_RANGE_SEQ *seq= (SEL_ARG_RANGE_SEQ*)init_param;
seq->at_start= TRUE;
+ seq->param->max_key_part= 0;
seq->stack[0].key_tree= NULL;
seq->stack[0].min_key= seq->param->min_key;
seq->stack[0].min_key_flag= 0;
diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc
index 366902c1f26..0d5d9ffeea8 100644
--- a/sql/rpl_filter.cc
+++ b/sql/rpl_filter.cc
@@ -349,14 +349,20 @@ Rpl_filter::set_do_table(const char* table_spec)
int status;
if (do_table_inited)
- my_hash_reset(&do_table);
+ {
+ my_hash_free(&do_table);
+ do_table_inited= 0;
+ }
status= parse_filter_rule(table_spec, &Rpl_filter::add_do_table);
- if (!do_table.records)
+ if (do_table_inited && status)
{
- my_hash_free(&do_table);
- do_table_inited= 0;
+ if (!do_table.records)
+ {
+ my_hash_free(&do_table);
+ do_table_inited= 0;
+ }
}
return status;
@@ -369,14 +375,20 @@ Rpl_filter::set_ignore_table(const char* table_spec)
int status;
if (ignore_table_inited)
- my_hash_reset(&ignore_table);
+ {
+ my_hash_free(&ignore_table);
+ ignore_table_inited= 0;
+ }
status= parse_filter_rule(table_spec, &Rpl_filter::add_ignore_table);
- if (!ignore_table.records)
+ if (ignore_table_inited && status)
{
- my_hash_free(&ignore_table);
- ignore_table_inited= 0;
+ if (!ignore_table.records)
+ {
+ my_hash_free(&ignore_table);
+ ignore_table_inited= 0;
+ }
}
return status;
@@ -411,14 +423,20 @@ Rpl_filter::set_wild_do_table(const char* table_spec)
int status;
if (wild_do_table_inited)
+ {
free_string_array(&wild_do_table);
+ wild_do_table_inited= 0;
+ }
status= parse_filter_rule(table_spec, &Rpl_filter::add_wild_do_table);
- if (!wild_do_table.elements)
+ if (wild_do_table_inited && status)
{
- delete_dynamic(&wild_do_table);
- wild_do_table_inited= 0;
+ if (!wild_do_table.elements)
+ {
+ delete_dynamic(&wild_do_table);
+ wild_do_table_inited= 0;
+ }
}
return status;
@@ -431,14 +449,20 @@ Rpl_filter::set_wild_ignore_table(const char* table_spec)
int status;
if (wild_ignore_table_inited)
+ {
free_string_array(&wild_ignore_table);
+ wild_ignore_table_inited= 0;
+ }
status= parse_filter_rule(table_spec, &Rpl_filter::add_wild_ignore_table);
- if (!wild_ignore_table.elements)
+ if (wild_ignore_table_inited && status)
{
- delete_dynamic(&wild_ignore_table);
- wild_ignore_table_inited= 0;
+ if (!wild_ignore_table.elements)
+ {
+ delete_dynamic(&wild_ignore_table);
+ wild_ignore_table_inited= 0;
+ }
}
return status;
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 574730b96c1..e58729ebbf3 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -75,18 +75,18 @@ handle_queued_pos_update(THD *thd, rpl_parallel_thread::queued_event *qev)
/* Do not update position if an earlier event group caused an error abort. */
DBUG_ASSERT(qev->typ == rpl_parallel_thread::queued_event::QUEUED_POS_UPDATE);
+ rli= qev->rgi->rli;
e= qev->entry_for_queued;
- if (e->stop_on_error_sub_id < (uint64)ULONGLONG_MAX || e->force_abort)
+ if (e->stop_on_error_sub_id < (uint64)ULONGLONG_MAX ||
+ (e->force_abort && !rli->stop_for_until))
return;
- rli= qev->rgi->rli;
mysql_mutex_lock(&rli->data_lock);
cmp= strcmp(rli->group_relay_log_name, qev->event_relay_log_name);
if (cmp < 0)
{
rli->group_relay_log_pos= qev->future_event_relay_log_pos;
strmake_buf(rli->group_relay_log_name, qev->event_relay_log_name);
- rli->notify_group_relay_log_name_update();
} else if (cmp == 0 &&
rli->group_relay_log_pos < qev->future_event_relay_log_pos)
rli->group_relay_log_pos= qev->future_event_relay_log_pos;
@@ -369,13 +369,14 @@ do_gco_wait(rpl_group_info *rgi, group_commit_orderer *gco,
}
-static void
+static bool
do_ftwrl_wait(rpl_group_info *rgi,
bool *did_enter_cond, PSI_stage_info *old_stage)
{
THD *thd= rgi->thd;
rpl_parallel_entry *entry= rgi->parallel_entry;
uint64 sub_id= rgi->gtid_sub_id;
+ bool aborted= false;
DBUG_ENTER("do_ftwrl_wait");
mysql_mutex_assert_owner(&entry->LOCK_parallel_entry);
@@ -397,7 +398,10 @@ do_ftwrl_wait(rpl_group_info *rgi,
do
{
if (entry->force_abort || rgi->worker_error)
+ {
+ aborted= true;
break;
+ }
if (thd->check_killed())
{
thd->send_kill_message();
@@ -417,7 +421,7 @@ do_ftwrl_wait(rpl_group_info *rgi,
if (sub_id > entry->largest_started_sub_id)
entry->largest_started_sub_id= sub_id;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(aborted);
}
@@ -500,7 +504,22 @@ rpl_unpause_after_ftwrl(THD *thd)
mysql_mutex_lock(&e->LOCK_parallel_entry);
rpt->pause_for_ftwrl = false;
mysql_mutex_unlock(&rpt->LOCK_rpl_thread);
- e->pause_sub_id= (uint64)ULONGLONG_MAX;
+ /*
+ Do not change pause_sub_id if force_abort is set.
+ force_abort is set in case of STOP SLAVE.
+
+ Reason: If pause_sub_id is not changed and force_abort_is set,
+ any parallel slave thread waiting in do_ftwrl_wait() will
+ on wakeup return from do_ftwrl_wait() with 1. This will set
+ skip_event_group to 1 in handle_rpl_parallel_thread() and the
+ parallel thread will abort at once.
+
+ If pause_sub_id is changed, the code in handle_rpl_parallel_thread()
+ would continue to execute the transaction in the queue, which would
+ cause some transactions to be lost.
+ */
+ if (!e->force_abort)
+ e->pause_sub_id= (uint64)ULONGLONG_MAX;
mysql_cond_broadcast(&e->COND_parallel_entry);
mysql_mutex_unlock(&e->LOCK_parallel_entry);
}
@@ -1155,7 +1174,7 @@ handle_rpl_parallel_thread(void *arg)
rgi->worker_error= 1;
}
if (likely(!skip_event_group))
- do_ftwrl_wait(rgi, &did_enter_cond, &old_stage);
+ skip_event_group= do_ftwrl_wait(rgi, &did_enter_cond, &old_stage);
/*
Register ourself to wait for the previous commit, if we need to do
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index f3514253874..c196a65809a 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -65,6 +65,7 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery)
gtid_skip_flag(GTID_SKIP_NOT), inited(0), abort_slave(0), stop_for_until(0),
slave_running(MYSQL_SLAVE_NOT_RUN), until_condition(UNTIL_NONE),
until_log_pos(0), retried_trans(0), executed_entries(0),
+ until_relay_log_names_defer(false),
m_flags(0)
{
DBUG_ENTER("Relay_log_info::Relay_log_info");
@@ -512,6 +513,8 @@ void Relay_log_info::clear_until_condition()
until_condition= Relay_log_info::UNTIL_NONE;
until_log_name[0]= 0;
until_log_pos= 0;
+ until_relay_log_names_defer= false;
+
DBUG_VOID_RETURN;
}
@@ -997,7 +1000,6 @@ void Relay_log_info::inc_group_relay_log_pos(ulonglong log_pos,
{
group_relay_log_pos= rgi->future_event_relay_log_pos;
strmake_buf(group_relay_log_name, rgi->event_relay_log_name);
- notify_group_relay_log_name_update();
} else if (cmp == 0 && group_relay_log_pos < rgi->future_event_relay_log_pos)
group_relay_log_pos= rgi->future_event_relay_log_pos;
@@ -1258,29 +1260,78 @@ err:
autoincrement or if we have transactions).
Should be called ONLY if until_condition != UNTIL_NONE !
+
+ In the parallel execution mode and UNTIL_MASTER_POS the file name is
+ presented by future_event_master_log_name which may be ahead of
+ group_master_log_name. Log_event::log_pos does relate to it nevertheless
+ so the pair comprises a correct binlog coordinate.
+ Internal group events and events that have zero log_pos also
+ produce the zero for the local log_pos which may not lead to the
+ function falsely return true.
+ In UNTIL_RELAY_POS the original caching and notification are simplified
+ to straightforward files comparison when the current event can't be
+ a part of an event group.
+
RETURN VALUE
true - condition met or error happened (condition seems to have
bad log file name)
false - condition not met
*/
-bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
+bool Relay_log_info::is_until_satisfied(Log_event *ev)
{
const char *log_name;
ulonglong log_pos;
+ /* Prevents stopping within transaction; needed solely for Relay UNTIL. */
+ bool in_trans= false;
+
DBUG_ENTER("Relay_log_info::is_until_satisfied");
if (until_condition == UNTIL_MASTER_POS)
{
log_name= (mi->using_parallel() ? future_event_master_log_name
: group_master_log_name);
- log_pos= master_beg_pos;
+ log_pos= (get_flag(Relay_log_info::IN_TRANSACTION) || !ev || !ev->log_pos) ?
+ (mi->using_parallel() ? 0 : group_master_log_pos) :
+ ev->log_pos - ev->data_written;
}
else
{
DBUG_ASSERT(until_condition == UNTIL_RELAY_POS);
- log_name= group_relay_log_name;
- log_pos= group_relay_log_pos;
+ if (!mi->using_parallel())
+ {
+ log_name= group_relay_log_name;
+ log_pos= group_relay_log_pos;
+ }
+ else
+ {
+ log_name= event_relay_log_name;
+ log_pos= event_relay_log_pos;
+ in_trans= get_flag(Relay_log_info::IN_TRANSACTION);
+ /*
+ until_log_names_cmp_result is set to UNKNOWN either
+ - by a non-group event *and* only when it is in the middle of a group
+ - or by a group event when the preceding group made the above
+ non-group event to defer the resetting.
+ */
+ if ((ev && !Log_event::is_group_event(ev->get_type_code())))
+ {
+ if (in_trans)
+ {
+ until_relay_log_names_defer= true;
+ }
+ else
+ {
+ until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
+ until_relay_log_names_defer= false;
+ }
+ }
+ else if (!in_trans && until_relay_log_names_defer)
+ {
+ until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
+ until_relay_log_names_defer= false;
+ }
+ }
}
DBUG_PRINT("info", ("group_master_log_name='%s', group_master_log_pos=%llu",
@@ -1334,8 +1385,8 @@ bool Relay_log_info::is_until_satisfied(my_off_t master_beg_pos)
}
DBUG_RETURN(((until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_EQUAL &&
- log_pos >= until_log_pos) ||
- until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
+ (log_pos >= until_log_pos && !in_trans)) ||
+ until_log_names_cmp_result == UNTIL_LOG_NAMES_CMP_GREATER));
}
@@ -1394,8 +1445,14 @@ bool Relay_log_info::stmt_done(my_off_t event_master_log_pos, THD *thd,
}
DBUG_EXECUTE_IF("inject_crash_before_flush_rli", DBUG_SUICIDE(););
if (mi->using_gtid == Master_info::USE_GTID_NO)
+ {
+ if (rgi->is_parallel_exec)
+ mysql_mutex_lock(&data_lock);
if (flush_relay_log_info(this))
error= 1;
+ if (rgi->is_parallel_exec)
+ mysql_mutex_unlock(&data_lock);
+ }
DBUG_EXECUTE_IF("inject_crash_after_flush_rli", DBUG_SUICIDE(););
}
DBUG_RETURN(error);
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 3dec5b0f044..29e47d302bc 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -402,7 +402,7 @@ public:
void close_temporary_tables();
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
- bool is_until_satisfied(my_off_t);
+ bool is_until_satisfied(Log_event *ev);
inline ulonglong until_pos()
{
DBUG_ASSERT(until_condition == UNTIL_MASTER_POS ||
@@ -410,7 +410,13 @@ public:
return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
group_relay_log_pos);
}
-
+ inline char *until_name()
+ {
+ DBUG_ASSERT(until_condition == UNTIL_MASTER_POS ||
+ until_condition == UNTIL_RELAY_POS);
+ return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_name :
+ group_relay_log_name);
+ }
/**
Helper function to do after statement completion.
@@ -483,6 +489,15 @@ public:
}
private:
+ /*
+ Hint for when to stop event distribution by sql driver thread.
+ The flag is set ON by a non-group event when this event is in the middle
+ of a group (e.g a transaction group) so it's too early
+ to refresh the current-relay-log vs until-log cached comparison result.
+ And it is checked and to decide whether it's a right time to do so
+ when the being processed group has been fully scheduled.
+ */
+ bool until_relay_log_names_defer;
/*
Holds the state of the data in the relay log.
diff --git a/sql/set_var.cc b/sql/set_var.cc
index b5f017eb85e..4b1ef63c5f3 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -923,8 +923,17 @@ int set_var_default_role::check(THD *thd)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
real_user= get_current_user(thd, user);
- int status= acl_check_set_default_role(thd, real_user->host.str, real_user->user.str);
- return status;
+ real_role= role.str;
+ if (role.str == current_role.str)
+ {
+ if (!thd->security_ctx->priv_role[0])
+ real_role= "NONE";
+ else
+ real_role= thd->security_ctx->priv_role;
+ }
+
+ return acl_check_set_default_role(thd, real_user->host.str,
+ real_user->user.str, real_role);
#else
return 0;
#endif
@@ -935,7 +944,8 @@ int set_var_default_role::update(THD *thd)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
thd->m_reprepare_observer= 0;
- int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str, role.str);
+ int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str,
+ real_role);
thd->m_reprepare_observer= save_reprepare_observer;
return res;
#else
diff --git a/sql/set_var.h b/sql/set_var.h
index fc79e906270..572ff9fe60a 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -339,6 +339,7 @@ class set_var_default_role: public set_var_base
{
LEX_USER *user, *real_user;
LEX_STRING role;
+ const char *real_role;
public:
set_var_default_role(LEX_USER *user_arg, LEX_STRING role_arg) :
user(user_arg), role(role_arg) {}
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
index d9b3fece854..05e1d2176f9 100644
--- a/sql/signal_handler.cc
+++ b/sql/signal_handler.cc
@@ -229,7 +229,7 @@ extern "C" sig_handler handle_fatal_signal(int sig)
}
my_safe_printf_stderr("%s",
"The manual page at "
- "http://dev.mysql.com/doc/mysql/en/crashing.html contains\n"
+ "https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains\n"
"information that should help you find out what is causing the crash.\n");
#endif /* HAVE_STACKTRACE */
diff --git a/sql/slave.cc b/sql/slave.cc
index c877a1e2c2c..06f2b0d955a 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB Corporation
+ Copyright (c) 2009, 2020, MariaDB Corporation
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
@@ -3784,12 +3784,8 @@ static int exec_relay_log_event(THD* thd, Relay_log_info* rli,
rli->until_condition == Relay_log_info::UNTIL_RELAY_POS) &&
(ev->server_id != global_system_variables.server_id ||
rli->replicate_same_server_id) &&
- rli->is_until_satisfied((rli->get_flag(Relay_log_info::IN_TRANSACTION) || !ev->log_pos)
- ? rli->group_master_log_pos
- : ev->log_pos - ev->data_written))
+ rli->is_until_satisfied(ev))
{
- sql_print_information("Slave SQL thread stopped because it reached its"
- " UNTIL position %llu", rli->until_pos());
/*
Setting abort_slave flag because we do not want additional
message about error in query execution to be printed.
@@ -4304,6 +4300,7 @@ connected:
goto err;
goto connected;
}
+ DBUG_EXECUTE_IF("fail_com_register_slave", goto err;);
}
DBUG_PRINT("info",("Starting reading binary log from master"));
@@ -4942,10 +4939,14 @@ pthread_handler_t handle_slave_sql(void *arg)
}
if ((rli->until_condition == Relay_log_info::UNTIL_MASTER_POS ||
rli->until_condition == Relay_log_info::UNTIL_RELAY_POS) &&
- rli->is_until_satisfied(rli->group_master_log_pos))
+ rli->is_until_satisfied(NULL))
{
sql_print_information("Slave SQL thread stopped because it reached its"
- " UNTIL position %llu", rli->until_pos());
+ " UNTIL position %llu in %s %s file",
+ rli->until_pos(), rli->until_name(),
+ rli->until_condition ==
+ Relay_log_info::UNTIL_MASTER_POS ?
+ "binlog" : "relaylog");
mysql_mutex_unlock(&rli->data_lock);
goto err;
}
@@ -4998,8 +4999,10 @@ pthread_handler_t handle_slave_sql(void *arg)
if (!sql_slave_killed(serial_rgi))
{
slave_output_error_info(serial_rgi, thd);
- if (WSREP_ON && rli->last_error().number == ER_UNKNOWN_COM_ERROR)
+ if (WSREP(thd) && rli->last_error().number == ER_UNKNOWN_COM_ERROR)
+ {
wsrep_node_dropped= TRUE;
+ }
}
goto err;
}
@@ -5008,7 +5011,24 @@ pthread_handler_t handle_slave_sql(void *arg)
err:
if (mi->using_parallel())
rli->parallel.wait_for_done(thd, rli);
+ /* Gtid_list_log_event::do_apply_event has already reported the GTID until */
+ if (rli->stop_for_until && rli->until_condition != Relay_log_info::UNTIL_GTID)
+ {
+ if (global_system_variables.log_warnings > 2)
+ sql_print_information("Slave SQL thread UNTIL stop was requested at position "
+ "%llu in %s %s file",
+ rli->until_log_pos, rli->until_log_name,
+ rli->until_condition ==
+ Relay_log_info::UNTIL_MASTER_POS ?
+ "binlog" : "relaylog");
+ sql_print_information("Slave SQL thread stopped because it reached its"
+ " UNTIL position %llu in %s %s file",
+ rli->until_pos(), rli->until_name(),
+ rli->until_condition ==
+ Relay_log_info::UNTIL_MASTER_POS ?
+ "binlog" : "relaylog");
+ };
/* Thread stopped. Print the current replication position to the log */
{
StringBuffer<100> tmp;
@@ -5131,7 +5151,7 @@ err_during_init:
If slave stopped due to node going non primary, we set global flag to
trigger automatic restart of slave when node joins back to cluster.
*/
- if (WSREP_ON && wsrep_node_dropped && wsrep_restart_slave)
+ if (WSREP(thd) && wsrep_node_dropped && wsrep_restart_slave)
{
if (wsrep_ready_get())
{
@@ -5920,7 +5940,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
error= ER_SLAVE_HEARTBEAT_FAILURE;
error_msg.append(STRING_WITH_LEN("inconsistent heartbeat event content;"));
error_msg.append(STRING_WITH_LEN("the event's data: log_file_name "));
- error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident()));
+ error_msg.append(hb.get_log_ident(), (uint) hb.get_ident_len());
error_msg.append(STRING_WITH_LEN(" log_pos "));
error_msg.append_ulonglong(hb.log_pos);
goto err;
@@ -5947,7 +5967,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
error= ER_SLAVE_HEARTBEAT_FAILURE;
error_msg.append(STRING_WITH_LEN("heartbeat is not compatible with local info;"));
error_msg.append(STRING_WITH_LEN("the event's data: log_file_name "));
- error_msg.append(hb.get_log_ident(), (uint) strlen(hb.get_log_ident()));
+ error_msg.append(hb.get_log_ident(), (uint) hb.get_ident_len());
error_msg.append(STRING_WITH_LEN(" log_pos "));
error_msg.append_ulonglong(hb.log_pos);
goto err;
diff --git a/sql/sp.cc b/sql/sp.cc
index 966ea0280b4..b783ff3b583 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -754,7 +754,7 @@ static sp_head *sp_compile(THD *thd, String *defstr, ulonglong sql_mode,
if (parse_sql(thd, & parser_state, creation_ctx) || thd->lex == NULL)
{
sp= thd->lex->sphead;
- delete sp;
+ sp_head::destroy(sp);
sp= 0;
}
else
@@ -1080,7 +1080,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
{
if (lex->create_info.or_replace())
{
- if ((ret= sp_drop_routine_internal(thd, type, lex->spname, table)))
+ if (sp_drop_routine_internal(thd, type, lex->spname, table))
goto done;
}
else if (lex->create_info.if_not_exists())
diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc
index f99c0bd0b6e..bc91634eb32 100644
--- a/sql/sp_cache.cc
+++ b/sql/sp_cache.cc
@@ -284,7 +284,7 @@ uchar *hash_get_key_for_sp_head(const uchar *ptr, size_t *plen,
void hash_free_sp_head(void *p)
{
sp_head *sp= (sp_head *)p;
- delete sp;
+ sp_head::destroy(sp);
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 5c5688be4a3..0428c0198a1 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -44,6 +44,9 @@
#include "transaction.h" // trans_commit_stmt
#include "sql_audit.h"
#include "debug_sync.h"
+#ifdef WITH_WSREP
+#include "wsrep_thd.h"
+#endif /* WITH_WSREP */
/*
Sufficient max length of printed destinations and frame offsets (all uints).
@@ -550,51 +553,41 @@ check_routine_name(LEX_STRING *ident)
}
-/*
- *
- * sp_head
- *
- */
-
-void *
-sp_head::operator new(size_t size) throw()
+sp_head* sp_head::create()
{
- DBUG_ENTER("sp_head::operator new");
MEM_ROOT own_root;
+ init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0));
sp_head *sp;
+ if (!(sp= new (&own_root) sp_head(&own_root)))
+ free_root(&own_root, MYF(0));
- init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0));
- sp= (sp_head *) alloc_root(&own_root, size);
- if (sp == NULL)
- DBUG_RETURN(NULL);
- sp->main_mem_root= own_root;
- DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
- DBUG_RETURN(sp);
+ return sp;
}
-void
-sp_head::operator delete(void *ptr, size_t size) throw()
-{
- DBUG_ENTER("sp_head::operator delete");
- MEM_ROOT own_root;
-
- if (ptr == NULL)
- DBUG_VOID_RETURN;
-
- sp_head *sp= (sp_head *) ptr;
- /* Make a copy of main_mem_root as free_root will free the sp */
- own_root= sp->main_mem_root;
- DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx",
- (ulong) &sp->mem_root, (ulong) &own_root));
- free_root(&own_root, MYF(0));
+void sp_head::destroy(sp_head *sp)
+{
+ if (sp)
+ {
+ /* Make a copy of main_mem_root as free_root will free the sp */
+ MEM_ROOT own_root= sp->main_mem_root;
+ delete sp;
- DBUG_VOID_RETURN;
+ DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx",
+ (ulong) &sp->mem_root, (ulong) &own_root));
+ free_root(&own_root, MYF(0));
+ }
}
+/*
+ *
+ * sp_head
+ *
+ */
-sp_head::sp_head()
- :Query_arena(&main_mem_root, STMT_INITIALIZED_FOR_SP),
+sp_head::sp_head(MEM_ROOT *mem_root_arg)
+ :Query_arena(NULL, STMT_INITIALIZED_FOR_SP),
+ main_mem_root(*mem_root_arg), // todo: std::move operator.
m_flags(0),
m_sp_cache_version(0),
m_creation_ctx(0),
@@ -603,6 +596,8 @@ sp_head::sp_head()
m_next_cached_sp(0),
m_cont_level(0)
{
+ mem_root= &main_mem_root;
+
m_first_instance= this;
m_first_free_instance= this;
m_last_cached_sp= this;
@@ -848,7 +843,7 @@ sp_head::~sp_head()
my_hash_free(&m_sptabs);
my_hash_free(&m_sroutines);
- delete m_next_cached_sp;
+ sp_head::destroy(m_next_cached_sp);
DBUG_VOID_RETURN;
}
@@ -1315,7 +1310,93 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
thd->m_digest= NULL;
err_status= i->execute(thd, &ip);
+#ifdef WITH_WSREP
+ if (m_type == TYPE_ENUM_PROCEDURE)
+ {
+ mysql_mutex_lock(&thd->LOCK_thd_data);
+ if (thd->wsrep_conflict_state == MUST_REPLAY)
+ {
+ wsrep_replay_sp_transaction(thd);
+ err_status= thd->get_stmt_da()->is_set();
+ thd->wsrep_conflict_state= NO_CONFLICT;
+ }
+ else if (thd->wsrep_conflict_state == ABORTED ||
+ thd->wsrep_conflict_state == CERT_FAILURE)
+ {
+ /*
+ If the statement execution was BF aborted or was aborted
+ due to certification failure, clean up transaction here
+ and reset conflict state to NO_CONFLICT and thd->killed
+ to THD::NOT_KILLED. Error handling is done based on err_status
+ below. Error must have been raised by wsrep hton code before
+ entering here.
+ */
+ DBUG_ASSERT(err_status);
+ DBUG_ASSERT(thd->get_stmt_da()->is_error());
+ thd->wsrep_conflict_state= NO_CONFLICT;
+ thd->killed= NOT_KILLED;
+ }
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
+ }
+#endif /* WITH_WSREP */
+#ifdef WITH_WSREP_NO
+ if (WSREP(thd))
+ {
+ if (((thd->wsrep_trx().state() == wsrep::transaction::s_executing) &&
+ (thd->is_fatal_error || thd->killed)))
+ {
+ WSREP_DEBUG("SP abort err status %d in sub %d trx state %d",
+ err_status, thd->in_sub_stmt, thd->wsrep_trx().state());
+ err_status= 1;
+ thd->is_fatal_error= 1;
+ /*
+ SP was killed, and it is not due to a wsrep conflict.
+ We skip after_command hook at this point because
+ otherwise it clears the error, and cleans up the
+ whole transaction. For now we just return and finish
+ our handling once we are back to mysql_parse.
+ */
+ WSREP_DEBUG("Skipping after_command hook for killed SP");
+ }
+ else
+ {
+ const bool must_replay= wsrep_must_replay(thd);
+ if (must_replay)
+ {
+ WSREP_DEBUG("MUST_REPLAY set after SP, err_status %d trx state: %d",
+ err_status, thd->wsrep_trx().state());
+ }
+ (void) wsrep_after_statement(thd);
+ /*
+ Reset the return code to zero if the transaction was
+ replayed succesfully.
+ */
+ if (must_replay && !wsrep_current_error(thd))
+ {
+ err_status= 0;
+ thd->get_stmt_da()->reset_diagnostics_area();
+ }
+ /*
+ Final wsrep error status for statement is known only after
+ wsrep_after_statement() call. If the error is set, override
+ error in thd diagnostics area and reset wsrep client_state error
+ so that the error does not get propagated via client-server protocol.
+ */
+ if (wsrep_current_error(thd))
+ {
+ wsrep_override_error(thd, wsrep_current_error(thd),
+ wsrep_current_error_status(thd));
+ thd->wsrep_cs().reset_error();
+ /* Reset also thd->killed if it has been set during BF abort. */
+ if (thd->killed == KILL_QUERY)
+ thd->killed= NOT_KILLED;
+ /* if failed transaction was not replayed, must return with error from here */
+ if (!must_replay) err_status = 1;
+ }
+ }
+ }
+#endif /* WITH_WSREP */
thd->m_digest= parent_digest;
if (i->free_list)
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 2b3e568fb9a..47cb0985b05 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -142,7 +142,7 @@ public:
bool
check_routine_name(LEX_STRING *ident);
-class sp_head :private Query_arena
+class sp_head :private Query_arena, public Sql_alloc
{
sp_head(const sp_head &); /**< Prevent use of these */
void operator=(sp_head &);
@@ -301,14 +301,16 @@ public:
being opened is probably enough).
*/
SQL_I_List<Item_trigger_field> m_trg_table_fields;
+private:
+ // users must use sp= sp_head::create()
+ sp_head(MEM_ROOT *mem_root_arg);
- static void *
- operator new(size_t size) throw ();
-
- static void
- operator delete(void *ptr, size_t size) throw ();
+ // users must use sp_head::destroy(sp)
+ virtual ~sp_head();
- sp_head();
+public:
+ static sp_head* create();
+ static void destroy(sp_head *sp);
/// Initialize after we have reset mem_root
void
@@ -326,7 +328,6 @@ public:
void
set_stmt_end(THD *thd);
- virtual ~sp_head();
bool
execute_trigger(THD *thd,
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4569121aba2..cf0b1d87bd7 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -201,7 +201,6 @@ LEX_STRING current_user= { C_STRING_WITH_LEN("*current_user") };
LEX_STRING current_role= { C_STRING_WITH_LEN("*current_role") };
LEX_STRING current_user_and_current_role= { C_STRING_WITH_LEN("*current_user_and_current_role") };
-
#ifndef NO_EMBEDDED_ACCESS_CHECKS
static plugin_ref old_password_plugin;
#endif
@@ -2034,8 +2033,43 @@ bool acl_getroot(Security_context *sctx, char *user, char *host,
DBUG_RETURN(res);
}
-static int check_user_can_set_role(const char *user, const char *host,
- const char *ip, const char *rolename, ulonglong *access)
+static int check_role_is_granted_callback(ACL_USER_BASE *grantee, void *data)
+{
+ LEX_CSTRING *rolename= static_cast<LEX_CSTRING *>(data);
+ if (rolename->length == grantee->user.length &&
+ !strcmp(rolename->str, grantee->user.str))
+ return -1; // End search, we've found our role.
+
+ /* Keep looking, we haven't found our role yet. */
+ return 0;
+}
+
+/*
+ unlike find_user_exact and find_user_wild,
+ this function finds anonymous users too, it's when a
+ user is not empty, but priv_user (acl_user->user) is empty.
+*/
+static ACL_USER *find_user_or_anon(const char *host, const char *user, const char *ip)
+{
+ ACL_USER *result= NULL;
+ mysql_mutex_assert_owner(&acl_cache->lock);
+ for (uint i=0; i < acl_users.elements; i++)
+ {
+ ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*);
+ if ((!acl_user_tmp->user.str ||
+ !strcmp(user, acl_user_tmp->user.str)) &&
+ compare_hostname(&acl_user_tmp->host, host, ip))
+ {
+ result= acl_user_tmp;
+ break;
+ }
+ }
+ return result;
+}
+
+static int check_user_can_set_role(THD *thd, const char *user, const char *host,
+ const char *ip, const char *rolename,
+ ulonglong *access)
{
ACL_ROLE *role;
ACL_USER_BASE *acl_user_base;
@@ -2053,8 +2087,7 @@ static int check_user_can_set_role(const char *user, const char *host,
acl_user= find_user_wild(host, user, ip);
if (acl_user == NULL)
{
- my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename);
- result= -1;
+ result= ER_INVALID_CURRENT_USER;
}
else if (access)
*access= acl_user->access;
@@ -2065,9 +2098,9 @@ static int check_user_can_set_role(const char *user, const char *host,
role= find_acl_role(rolename);
/* According to SQL standard, the same error message must be presented */
- if (role == NULL) {
- my_error(ER_INVALID_ROLE, MYF(0), rolename);
- result= -1;
+ if (role == NULL)
+ {
+ result= ER_INVALID_ROLE;
goto end;
}
@@ -2088,7 +2121,6 @@ static int check_user_can_set_role(const char *user, const char *host,
/* According to SQL standard, the same error message must be presented */
if (!is_granted)
{
- my_error(ER_INVALID_ROLE, MYF(0), rolename);
result= 1;
goto end;
}
@@ -2097,17 +2129,66 @@ static int check_user_can_set_role(const char *user, const char *host,
{
*access = acl_user->access | role->access;
}
+
end:
mysql_mutex_unlock(&acl_cache->lock);
- return result;
+ /* We present different error messages depending if the user has sufficient
+ privileges to know if the INVALID_ROLE exists. */
+ switch (result)
+ {
+ case ER_INVALID_CURRENT_USER:
+ my_error(ER_INVALID_CURRENT_USER, MYF(0), rolename);
+ break;
+ case ER_INVALID_ROLE:
+ /* Role doesn't exist at all */
+ my_error(ER_INVALID_ROLE, MYF(0), rolename);
+ break;
+ case 1:
+ StringBuffer<1024> c_usr;
+ LEX_CSTRING role_lex;
+ /* First, check if current user can see mysql database. */
+ bool read_access= !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 1);
+
+ role_lex.str= rolename;
+ role_lex.length= strlen(rolename);
+ mysql_mutex_lock(&acl_cache->lock);
+ ACL_USER *cur_user= find_user_or_anon(thd->security_ctx->priv_host,
+ thd->security_ctx->priv_user,
+ thd->security_ctx->ip);
+
+ /* If the current user does not have select priv to mysql database,
+ see if the current user can discover the role if it was granted to him.
+ */
+ if (cur_user && (read_access ||
+ traverse_role_graph_down(cur_user, &role_lex,
+ check_role_is_granted_callback,
+ NULL) == -1))
+ {
+ /* Role is not granted but current user can see the role */
+ c_usr.append(user, strlen(user));
+ c_usr.append('@');
+ c_usr.append(host, strlen(host));
+ my_printf_error(ER_INVALID_ROLE, "User %`s has not been granted role %`s",
+ MYF(0), c_usr.c_ptr(), rolename);
+ }
+ else
+ {
+ /* Role is not granted and current user cannot see the role */
+ my_error(ER_INVALID_ROLE, MYF(0), rolename);
+ }
+ mysql_mutex_unlock(&acl_cache->lock);
+ break;
+ }
+
+ return result;
}
+
int acl_check_setrole(THD *thd, char *rolename, ulonglong *access)
{
- /* Yes! priv_user@host. Don't ask why - that's what check_access() does. */
- return check_user_can_set_role(thd->security_ctx->priv_user,
- thd->security_ctx->host, thd->security_ctx->ip, rolename, access);
+ return check_user_can_set_role(thd, thd->security_ctx->priv_user,
+ thd->security_ctx->host, thd->security_ctx->ip, rolename, access);
}
@@ -2886,9 +2967,12 @@ WSREP_ERROR_LABEL:
DBUG_RETURN(result);
}
-int acl_check_set_default_role(THD *thd, const char *host, const char *user)
+int acl_check_set_default_role(THD *thd, const char *host, const char *user,
+ const char *role)
{
- return check_alter_user(thd, host, user);
+ DBUG_ENTER("acl_check_set_default_role");
+ DBUG_RETURN(check_alter_user(thd, host, user) ||
+ check_user_can_set_role(thd, user, host, NULL, role, NULL));
}
int acl_set_default_role(THD *thd, const char *host, const char *user,
@@ -2910,16 +2994,6 @@ int acl_set_default_role(THD *thd, const char *host, const char *user,
DBUG_PRINT("enter",("host: '%s' user: '%s' rolename: '%s'",
safe_str(user), safe_str(host), safe_str(rolename)));
- if (rolename == current_role.str) {
- if (!thd->security_ctx->priv_role[0])
- rolename= "NONE";
- else
- rolename= thd->security_ctx->priv_role;
- }
-
- if (check_user_can_set_role(user, host, host, rolename, NULL))
- DBUG_RETURN(result);
-
if (!strcasecmp(rolename, "NONE"))
clear_role= TRUE;
@@ -3073,31 +3147,6 @@ bool is_acl_user(const char *host, const char *user)
return res;
}
-
-/*
- unlike find_user_exact and find_user_wild,
- this function finds anonymous users too, it's when a
- user is not empty, but priv_user (acl_user->user) is empty.
-*/
-static ACL_USER *find_user_or_anon(const char *host, const char *user, const char *ip)
-{
- ACL_USER *result= NULL;
- mysql_mutex_assert_owner(&acl_cache->lock);
- for (uint i=0; i < acl_users.elements; i++)
- {
- ACL_USER *acl_user_tmp= dynamic_element(&acl_users, i, ACL_USER*);
- if ((!acl_user_tmp->user.str ||
- !strcmp(user, acl_user_tmp->user.str)) &&
- compare_hostname(&acl_user_tmp->host, host, ip))
- {
- result= acl_user_tmp;
- break;
- }
- }
- return result;
-}
-
-
/*
Find first entry that matches the specified user@host pair
*/
@@ -3370,7 +3419,7 @@ static bool test_if_create_new_users(THD *thd)
if (!(db_access & INSERT_ACL))
{
if (check_grant(thd, INSERT_ACL, &tl, FALSE, UINT_MAX, TRUE))
- create_new_users=0;
+ create_new_users=0;
}
}
return create_new_users;
@@ -3426,13 +3475,15 @@ static int replace_user_table(THD *thd, TABLE *table, LEX_USER &combo,
table->key_info->key_length);
if (table->file->ha_index_read_idx_map(table->record[0], 0, user_key,
- HA_WHOLE_KEY,
- HA_READ_KEY_EXACT))
+ HA_WHOLE_KEY, HA_READ_KEY_EXACT))
{
/* what == 'N' means revoke */
if (what == 'N')
{
- my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
+ if (combo.host.length)
+ my_error(ER_NONEXISTING_GRANT, MYF(0), combo.user.str, combo.host.str);
+ else
+ my_error(ER_INVALID_ROLE, MYF(0), combo.user.str);
goto end;
}
/*
@@ -4928,6 +4979,8 @@ static void propagate_role_grants(ACL_ROLE *role,
enum PRIVS_TO_MERGE::what what,
const char *db= 0, const char *name= 0)
{
+ if (!role)
+ return;
mysql_mutex_assert_owner(&acl_cache->lock);
PRIVS_TO_MERGE data= { what, db, name };
@@ -7081,6 +7134,21 @@ err:
}
+static void check_grant_column_int(GRANT_TABLE *grant_table, const char *name,
+ uint length, ulong *want_access)
+{
+ if (grant_table)
+ {
+ *want_access&= ~grant_table->privs;
+ if (*want_access & grant_table->cols)
+ {
+ GRANT_COLUMN *grant_column= column_hash_search(grant_table, name, length);
+ if (grant_column)
+ *want_access&= ~grant_column->rights;
+ }
+ }
+}
+
/*
Check column rights in given security context
@@ -7103,9 +7171,6 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
const char *db_name, const char *table_name,
const char *name, uint length, Security_context *sctx)
{
- GRANT_TABLE *grant_table;
- GRANT_TABLE *grant_table_role;
- GRANT_COLUMN *grant_column;
ulong want_access= grant->want_privilege & ~grant->privilege;
DBUG_ENTER("check_grant_column");
DBUG_PRINT("enter", ("table: %s want_access: %lu", table_name, want_access));
@@ -7130,45 +7195,18 @@ bool check_grant_column(THD *thd, GRANT_INFO *grant,
grant->version= grant_version; /* purecov: inspected */
}
- grant_table= grant->grant_table_user;
- grant_table_role= grant->grant_table_role;
-
- if (!grant_table && !grant_table_role)
- goto err;
+ check_grant_column_int(grant->grant_table_user, name, length, &want_access);
+ check_grant_column_int(grant->grant_table_role, name, length, &want_access);
- if (grant_table)
- {
- grant_column= column_hash_search(grant_table, name, length);
- if (grant_column)
- {
- want_access&= ~grant_column->rights;
- }
- }
- if (grant_table_role)
- {
- grant_column= column_hash_search(grant_table_role, name, length);
- if (grant_column)
- {
- want_access&= ~grant_column->rights;
- }
- }
+ mysql_rwlock_unlock(&LOCK_grant);
if (!want_access)
- {
- mysql_rwlock_unlock(&LOCK_grant);
DBUG_RETURN(0);
- }
-err:
- mysql_rwlock_unlock(&LOCK_grant);
char command[128];
get_privilege_desc(command, sizeof(command), want_access);
/* TODO perhaps error should print current rolename aswell */
- my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
- command,
- sctx->priv_user,
- sctx->host_or_ip,
- name,
- table_name);
+ my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0), command, sctx->priv_user,
+ sctx->host_or_ip, name, table_name);
DBUG_RETURN(1);
}
@@ -8508,17 +8546,6 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc)
mysql_mutex_unlock(&acl_cache->lock);
}
-static int check_role_is_granted_callback(ACL_USER_BASE *grantee, void *data)
-{
- LEX_CSTRING *rolename= static_cast<LEX_CSTRING *>(data);
- if (rolename->length == grantee->user.length &&
- !strcmp(rolename->str, grantee->user.str))
- return -1; // End search, we've found our role.
-
- /* Keep looking, we haven't found our role yet. */
- return 0;
-}
-
/*
Initialize a TABLE_LIST array and open grant tables
@@ -10329,7 +10356,7 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user,
Security context in THD contains two pairs of (user,host):
1. (user,host) pair referring to inbound connection.
2. (priv_user,priv_host) pair obtained from mysql.user table after doing
- authnetication of incoming connection.
+ authentication of incoming connection.
Privileges should be checked wrt (priv_user, priv_host) tuple, because
(user,host) pair obtained from inbound connection may have different
values than what is actually stored in mysql.user table and while granting
@@ -10672,7 +10699,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
-static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
+static bool update_schema_privilege(THD *thd, TABLE *table, const char *buff,
const char* db, const char* t_name,
const char* column, uint col_length,
const char *priv, uint priv_length,
@@ -10696,6 +10723,21 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
#endif
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+class Grantee_str
+{
+ char m_buff[USER_HOST_BUFF_SIZE + 6 /* 4 quotes, @, '\0' */];
+public:
+ Grantee_str(const char *user, const char *host)
+ {
+ DBUG_ASSERT(strlen(user) + strlen(host) + 6 < sizeof(m_buff));
+ strxmov(m_buff, "'", user, "'@'", host, "'", NullS);
+ }
+ operator const char *() const { return m_buff; }
+};
+#endif
+
+
int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -10703,7 +10745,6 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
uint counter;
ACL_USER *acl_user;
ulong want_access;
- char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1);
@@ -10730,10 +10771,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
if (!(want_access & GRANT_ACL))
is_grantable= "NO";
- strxmov(buff,"'",user,"'@'",host,"'",NullS);
+ Grantee_str grantee(user, host);
if (!(want_access & ~GRANT_ACL))
{
- if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
+ if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0,
STRING_WITH_LEN("USAGE"), is_grantable))
{
error= 1;
@@ -10746,9 +10787,9 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
ulong j,test_access= want_access & ~GRANT_ACL;
for (priv_id=0, j = SELECT_ACL;j <= GLOBAL_ACLS; priv_id++,j <<= 1)
{
- if (test_access & j)
+ if (test_access & j)
{
- if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
+ if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0,
command_array[priv_id],
command_lengths[priv_id], is_grantable))
{
@@ -10776,7 +10817,6 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
uint counter;
ACL_DB *acl_db;
ulong want_access;
- char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1);
@@ -10807,10 +10847,10 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
is_grantable= "NO";
}
- strxmov(buff,"'",user,"'@'",host,"'",NullS);
+ Grantee_str grantee(user, host);
if (!(want_access & ~GRANT_ACL))
{
- if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0,
+ if (update_schema_privilege(thd, table, grantee, acl_db->db, 0, 0,
0, STRING_WITH_LEN("USAGE"), is_grantable))
{
error= 1;
@@ -10824,7 +10864,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
if (test_access & j)
{
- if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0,
+ if (update_schema_privilege(thd, table,
+ grantee, acl_db->db, 0, 0, 0,
command_array[cnt], command_lengths[cnt],
is_grantable))
{
@@ -10850,7 +10891,6 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
int error= 0;
uint index;
- char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1);
@@ -10885,10 +10925,11 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
if (!(table_access & GRANT_ACL))
is_grantable= "NO";
- strxmov(buff, "'", user, "'@'", host, "'", NullS);
+ Grantee_str grantee(user, host);
if (!test_access)
{
- if (update_schema_privilege(thd, table, buff, grant_table->db,
+ if (update_schema_privilege(thd, table,
+ grantee, grant_table->db,
grant_table->tname, 0, 0,
STRING_WITH_LEN("USAGE"), is_grantable))
{
@@ -10904,7 +10945,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{
if (test_access & j)
{
- if (update_schema_privilege(thd, table, buff, grant_table->db,
+ if (update_schema_privilege(thd, table,
+ grantee, grant_table->db,
grant_table->tname, 0, 0,
command_array[cnt],
command_lengths[cnt], is_grantable))
@@ -10932,7 +10974,6 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
#ifndef NO_EMBEDDED_ACCESS_CHECKS
int error= 0;
uint index;
- char buff[100];
TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1);
@@ -10961,7 +11002,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
is_grantable= "NO";
ulong test_access= table_access & ~GRANT_ACL;
- strxmov(buff, "'", user, "'@'", host, "'", NullS);
+ Grantee_str grantee(user, host);
if (!test_access)
continue;
else
@@ -10980,7 +11021,9 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
my_hash_element(&grant_table->hash_columns,col_index);
if ((grant_column->rights & j) && (table_access & j))
{
- if (update_schema_privilege(thd, table, buff, grant_table->db,
+ if (update_schema_privilege(thd, table,
+ grantee,
+ grant_table->db,
grant_table->tname,
grant_column->column,
grant_column->key_length,
@@ -11430,6 +11473,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio,
int2store(end+5, thd->client_capabilities >> 16);
end[7]= data_len;
DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;);
+ DBUG_EXECUTE_IF("increase_srv_handshake_scramble_len", end[7]= 50;);
bzero(end + 8, 10);
end+= 18;
/* write scramble tail */
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index c191cb83de5..3bd896cab79 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -402,7 +402,7 @@ bool acl_check_proxy_grant_access (THD *thd, const char *host, const char *user,
bool with_grant);
int acl_setrole(THD *thd, char *rolename, ulonglong access);
int acl_check_setrole(THD *thd, char *rolename, ulonglong *access);
-int acl_check_set_default_role(THD *thd, const char *host, const char *user);
+int acl_check_set_default_role(THD *thd, const char *host, const char *user, const char *role);
int acl_set_default_role(THD *thd, const char *host, const char *user,
const char *rolename);
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 4afaff58223..3f518312526 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -727,8 +727,18 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
{
compl_result_code= result_code= HA_ADMIN_INVALID;
}
+
+ /*
+ The check for Alter_info::ALTER_ADMIN_PARTITION implements this logic:
+ do not collect EITS STATS for this syntax:
+ ALTER TABLE ... ANALYZE PARTITION p
+ EITS statistics is global (not per-partition). Collecting global stats
+ is much more expensive processing just one partition, so the most
+ appropriate action is to just not collect EITS stats for this command.
+ */
collect_eis=
(table->table->s->table_category == TABLE_CATEGORY_USER &&
+ !(lex->alter_info.flags & Alter_info::ALTER_ADMIN_PARTITION) &&
(get_use_stat_tables_mode(thd) > NEVER ||
lex->with_persistent_for_clause));
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 1c4e7600d87..1031a384d71 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates.
- Copyright (c) 2010, 2016, MariaDB
+ Copyright (c) 2010, 2020, MariaDB
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
@@ -1892,7 +1892,7 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
FALSE);
/* extra() call must come only after all instances above are closed */
if (function != HA_EXTRA_NOT_USED)
- (void) table->file->extra(function);
+ DBUG_RETURN(table->file->extra(function));
DBUG_RETURN(FALSE);
}
@@ -4784,7 +4784,7 @@ restart:
}
}
- if (WSREP_ON &&
+ if (WSREP(thd) &&
wsrep_replicate_myisam &&
(*start) &&
(*start)->table &&
@@ -5037,10 +5037,19 @@ bool Lock_tables_prelocking_strategy::
handle_table(THD *thd, Query_tables_list *prelocking_ctx,
TABLE_LIST *table_list, bool *need_prelocking)
{
+ TABLE_LIST **last= prelocking_ctx->query_tables_last;
+
if (DML_prelocking_strategy::handle_table(thd, prelocking_ctx, table_list,
need_prelocking))
return TRUE;
+ /*
+ normally we don't need to open FK-prelocked tables for RESTRICT,
+ MDL is enough. But under LOCK TABLES we have to open everything
+ */
+ for (TABLE_LIST *tl= *last; tl; tl= tl->next_global)
+ tl->open_strategy= TABLE_LIST::OPEN_NORMAL;
+
/* We rely on a caller to check that table is going to be changed. */
DBUG_ASSERT(table_list->lock_type >= TL_WRITE_ALLOW_WRITE);
@@ -8297,15 +8306,11 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
FALSE ok; In this case *map will include the chosen index
TRUE error
*/
-bool setup_tables_and_check_access(THD *thd,
- Name_resolution_context *context,
+bool setup_tables_and_check_access(THD *thd, Name_resolution_context *context,
List<TABLE_LIST> *from_clause,
- TABLE_LIST *tables,
- List<TABLE_LIST> &leaves,
- bool select_insert,
- ulong want_access_first,
- ulong want_access,
- bool full_table_list)
+ TABLE_LIST *tables, List<TABLE_LIST> &leaves,
+ bool select_insert, ulong want_access_first,
+ ulong want_access, bool full_table_list)
{
DBUG_ENTER("setup_tables_and_check_access");
@@ -8880,8 +8885,7 @@ fill_record(THD *thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
rfield->field_index == table->next_number_field->field_index)
table->auto_increment_field_not_null= TRUE;
if (rfield->vcol_info &&
- value->type() != Item::DEFAULT_VALUE_ITEM &&
- value->type() != Item::NULL_ITEM &&
+ !value->vcol_assignment_allowed_value() &&
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -9089,8 +9093,7 @@ fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
if (field->field_index == autoinc_index)
table->auto_increment_field_not_null= TRUE;
if (field->vcol_info &&
- value->type() != Item::DEFAULT_VALUE_ITEM &&
- value->type() != Item::NULL_ITEM &&
+ !value->vcol_assignment_allowed_value() &&
table->s->table_category != TABLE_CATEGORY_TEMPORARY)
{
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 1105c9a55ec..b8d4525b5d7 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -78,8 +78,9 @@ int binlog_defragment(THD *thd)
memcpy(thd->lex->comment.str + gathered_length, entry[k]->value,
entry[k]->length);
gathered_length += entry[k]->length;
- update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0);
}
+ for (uint k=0; k < 2; k++)
+ update_hash(entry[k], true, NULL, 0, STRING_RESULT, &my_charset_bin, 0);
DBUG_ASSERT(gathered_length == thd->lex->comment.length);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 44ae9d32906..571570f6a85 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -3367,7 +3367,7 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used,
if (!insert_table(thd, key_length, key, (*block_table),
tables_used->view_db.length, 0,
HA_CACHE_TBL_NONTRANSACT, 0, 0, TRUE))
- DBUG_RETURN(0);
+ goto err_cleanup;
/*
We do not need to register view tables here because they are already
present in the global list.
@@ -3391,7 +3391,7 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used,
tables_used->callback_func,
tables_used->engine_data,
TRUE))
- DBUG_RETURN(0);
+ goto err_cleanup;
if (tables_used->table->file->
register_query_cache_dependant_tables(thd, this, block_table, &n))
@@ -3399,6 +3399,11 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used,
}
}
DBUG_RETURN(n - counter);
+err_cleanup:
+ // Mark failed
+ (*block_table)->next= (*block_table)->prev= NULL;
+ (*block_table)->parent= NULL;
+ DBUG_RETURN(0);
}
/*
@@ -3432,7 +3437,12 @@ my_bool Query_cache::register_all_tables(THD *thd,
for (Query_cache_block_table *tmp = block->table(0) ;
tmp != block_table;
tmp++)
- unlink_table(tmp);
+ {
+ if (tmp->prev) // not marked as failed and unuseable
+ unlink_table(tmp);
+ else
+ break;
+ }
if (block_table->parent)
unlink_table(block_table);
}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index ab105c67507..6897a26bda1 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -71,6 +71,7 @@
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
+#include "repl_failsafe.h"
/*
The following is used to initialise Table_ident with a internal
@@ -1593,6 +1594,7 @@ THD::~THD()
if (rgi_slave)
rgi_slave->cleanup_after_session();
my_free(semisync_info);
+ unregister_slave(this, true, true);
#endif
main_lex.free_set_stmt_mem_root();
free_root(&main_mem_root, MYF(0));
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 56bb9f45877..7ca3896a69d 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -781,9 +781,9 @@ typedef struct system_status_var
ulong feature_xml; /* +1 when XPATH is used */
/* From MASTER_GTID_WAIT usage */
- ulonglong master_gtid_wait_timeouts; /* Number of timeouts */
- ulonglong master_gtid_wait_time; /* Time in microseconds */
- ulonglong master_gtid_wait_count;
+ ulong master_gtid_wait_timeouts; /* Number of timeouts */
+ ulong master_gtid_wait_time; /* Time in microseconds */
+ ulong master_gtid_wait_count;
ulong empty_queries;
ulong access_denied_errors;
@@ -5161,16 +5161,21 @@ user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
class Unique :public Sql_alloc
{
DYNAMIC_ARRAY file_ptrs;
- ulong max_elements;
+ ulong max_elements; /* Total number of elements that will be stored in-memory */
ulonglong max_in_memory_size;
IO_CACHE file;
TREE tree;
uchar *record_pointers;
+ /* Number of elements filtered out due to min_dupl_count when storing results
+ to table. See Unique::get */
ulong filtered_out_elems;
bool flush();
uint size;
- uint full_size;
- uint min_dupl_count; /* always 0 for unions, > 0 for intersections */
+ uint full_size; /* Size of element + space needed to store the number of
+ duplicates found for the element. */
+ uint min_dupl_count; /* Minimum number of occurences of element required for
+ it to be written to record_pointers.
+ always 0 for unions, > 0 for intersections */
bool with_counters;
bool merge(TABLE *table, uchar *buff, bool without_last_merge);
@@ -5211,6 +5216,9 @@ public:
{
ulonglong max_elems_in_tree=
max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size);
+
+ if (max_elems_in_tree == 0)
+ max_elems_in_tree= 1;
return (int) (sizeof(uint)*(1 + nkeys/max_elems_in_tree));
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 1cd2a369d7a..e863308159e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2018, MariaDB Corporation
+/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2020, MariaDB Corporation
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
@@ -785,7 +785,7 @@ void lex_end_stage1(LEX *lex)
}
else
{
- delete lex->sphead;
+ sp_head::destroy(lex->sphead);
lex->sphead= NULL;
}
@@ -1181,17 +1181,27 @@ static inline uint int_token(const char *str,uint length)
*/
bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
{
+ // only one level of nested comments are allowed
+ DBUG_ASSERT(remaining_recursions_permitted == 0 ||
+ remaining_recursions_permitted == 1);
uchar c;
while (! lip->eof())
{
c= lip->yyGet();
- if (remaining_recursions_permitted > 0)
+ if (remaining_recursions_permitted == 1)
{
if ((c == '/') && (lip->yyPeek() == '*'))
{
+ lip->yyUnput('('); // Replace nested "/*..." with "(*..."
+ lip->yySkip(); // and skip "("
+
lip->yySkip(); /* Eat asterisk */
- consume_comment(lip, remaining_recursions_permitted-1);
+ if (consume_comment(lip, 0))
+ return true;
+
+ lip->yyUnput(')'); // Replace "...*/" with "...*)"
+ lip->yySkip(); // and skip ")"
continue;
}
}
@@ -2781,7 +2791,7 @@ void LEX::cleanup_lex_after_parse_error(THD *thd)
if (thd->lex->sphead)
{
thd->lex->sphead->restore_thd_mem_root(thd);
- delete thd->lex->sphead;
+ sp_head::destroy(thd->lex->sphead);
thd->lex->sphead= NULL;
}
}
@@ -3792,7 +3802,8 @@ bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
sl->options|= SELECT_DESCRIBE;
inner_join->select_options|= SELECT_DESCRIBE;
}
- res= inner_join->optimize();
+ if ((res= inner_join->optimize()))
+ return TRUE;
if (!inner_join->cleaned)
sl->update_used_tables();
sl->update_correlated_cache();
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 218d0dbd357..14ac657862f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
- Copyright (c) 2008, 2019, MariaDB
+ Copyright (c) 2008, 2020, MariaDB
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
@@ -669,11 +669,6 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
char *buf= thd->strmake(init_command->str, len);
mysql_rwlock_unlock(var_lock);
-#if defined(ENABLED_PROFILING)
- thd->profiling.start_new_query();
- thd->profiling.set_query_source(buf, len);
-#endif
-
THD_STAGE_INFO(thd, stage_execution_of_init_command);
save_client_capabilities= thd->client_capabilities;
thd->client_capabilities|= CLIENT_MULTI_QUERIES;
@@ -688,9 +683,6 @@ void execute_init_command(THD *thd, LEX_STRING *init_command,
thd->client_capabilities= save_client_capabilities;
thd->net.vio= save_vio;
-#if defined(ENABLED_PROFILING)
- thd->profiling.finish_current_query();
-#endif
}
@@ -1493,7 +1485,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (parser_state.init(thd, thd->query(), thd->query_length()))
break;
- if (WSREP_ON)
+ if (WSREP(thd))
wsrep_mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
else
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
@@ -1574,13 +1566,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
*/
statistic_increment(thd->status_var.questions, &LOCK_status);
- if(!WSREP(thd))
+ if (!WSREP(thd))
thd->set_time(); /* Reset the query start time. */
parser_state.reset(beginning_of_next_stmt, length);
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
- if (WSREP_ON)
+ if (WSREP(thd))
wsrep_mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
else
mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
@@ -1739,7 +1731,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
general_log_print(thd, command, "Log: '%s' Pos: %lu", name, pos);
if (nlen < FN_REFLEN)
mysql_binlog_send(thd, thd->strmake(name, nlen), (my_off_t)pos, flags);
- unregister_slave(thd,1,1);
/* fake COM_QUIT -- if we get here, the thread needs to terminate */
error = TRUE;
break;
@@ -4347,7 +4338,7 @@ mysql_execute_command(THD *thd)
/* Don't do it, if we are inside a SP */
if (!thd->spcont)
{
- delete lex->sphead;
+ sp_head::destroy(lex->sphead);
lex->sphead= NULL;
}
/* lex->unit.cleanup() is called outside, no need to call it here */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 2c6aeda794a..f5adaeaa956 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3607,7 +3607,7 @@ Prepared_statement::~Prepared_statement()
free_items();
if (lex)
{
- delete lex->sphead;
+ sp_head::destroy(lex->sphead);
delete lex->result;
delete (st_lex_local *) lex;
}
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 851bff5fd24..2d644ffc5ef 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -2027,9 +2027,13 @@ static int init_binlog_sender(binlog_send_info *info,
});
if (global_system_variables.log_warnings > 1)
+ {
sql_print_information(
- "Start binlog_dump to slave_server(%lu), pos(%s, %lu)",
- thd->variables.server_id, log_ident, (ulong)*pos);
+ "Start binlog_dump to slave_server(%lu), pos(%s, %lu), "
+ "using_gtid(%d), gtid('%s')", thd->variables.server_id,
+ log_ident, (ulong)*pos, info->using_gtid_state,
+ connect_gtid_state.c_ptr_quick());
+ }
#ifndef DBUG_OFF
if (opt_sporadic_binlog_dump_fail && (binlog_dump_count++ % 2))
@@ -3838,6 +3842,7 @@ bool mysql_show_binlog_events(THD* thd)
{
Protocol *protocol= thd->protocol;
List<Item> field_list;
+ char errmsg_buf[MYSYS_ERRMSG_SIZE];
const char *errmsg = 0;
bool ret = TRUE;
/*
@@ -3852,6 +3857,9 @@ bool mysql_show_binlog_events(THD* thd)
Master_info *mi= 0;
LOG_INFO linfo;
LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ enum enum_binlog_checksum_alg checksum_alg;
+ my_off_t binlog_size;
+ MY_STAT s;
DBUG_ENTER("mysql_show_binlog_events");
@@ -3900,10 +3908,6 @@ bool mysql_show_binlog_events(THD* thd)
mi= 0;
}
- /* Validate user given position using checksum */
- if (lex_mi->pos == pos && !opt_master_verify_checksum)
- verify_checksum_once= true;
-
unit->set_limit(thd->lex->current_select);
limit_start= unit->offset_limit_cnt;
limit_end= unit->select_limit_cnt;
@@ -3930,6 +3934,17 @@ bool mysql_show_binlog_events(THD* thd)
if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
goto err;
+ my_stat(linfo.log_file_name, &s, MYF(0));
+ binlog_size= s.st_size;
+ if (lex_mi->pos > binlog_size)
+ {
+ sprintf(errmsg_buf, "Invalid pos specified. Requested from pos:%llu is "
+ "greater than actual file size:%lu\n", lex_mi->pos,
+ (ulong)s.st_size);
+ errmsg= errmsg_buf;
+ goto err;
+ }
+
/*
to account binlog event header size
*/
@@ -3981,7 +3996,43 @@ bool mysql_show_binlog_events(THD* thd)
}
}
- my_b_seek(&log, pos);
+ if (lex_mi->pos > BIN_LOG_HEADER_SIZE)
+ {
+ checksum_alg= description_event->checksum_alg;
+ /* Validate user given position using checksum */
+ if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
+ checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
+ {
+ if (!opt_master_verify_checksum)
+ verify_checksum_once= true;
+ my_b_seek(&log, pos);
+ }
+ else
+ {
+ my_off_t cur_pos= my_b_tell(&log);
+ ulong next_event_len= 0;
+ uchar buff[IO_SIZE];
+ while (cur_pos < pos)
+ {
+ my_b_seek(&log, cur_pos + EVENT_LEN_OFFSET);
+ if (my_b_read(&log, (uchar *)buff, sizeof(next_event_len)))
+ {
+ mysql_mutex_unlock(log_lock);
+ errmsg = "Could not read event_length";
+ goto err;
+ }
+ next_event_len= uint4korr(buff);
+ cur_pos= cur_pos + next_event_len;
+ }
+ if (cur_pos > pos)
+ {
+ mysql_mutex_unlock(log_lock);
+ errmsg= "Invalid input pos specified please provide valid one.";
+ goto err;
+ }
+ my_b_seek(&log, cur_pos);
+ }
+ }
for (event_count = 0;
(ev = Log_event::read_log_event(&log, (mysql_mutex_t*) 0,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 40941294013..138f98212aa 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -399,11 +399,14 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
If LIMIT ROWS EXAMINED interrupted query execution, issue a warning,
continue with normal processing and produce an incomplete query result.
*/
+ bool saved_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning= false;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT,
ER_THD(thd, ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT),
thd->accessed_rows_and_keys,
thd->lex->limit_rows_examined->val_uint());
+ thd->abort_on_warning= saved_abort_on_warning;
thd->reset_killed();
}
/* Disable LIMIT ROWS EXAMINED after query execution. */
@@ -1055,11 +1058,11 @@ int JOIN::optimize()
if (optimization_state != JOIN::NOT_OPTIMIZED)
return FALSE;
optimization_state= JOIN::OPTIMIZATION_IN_PROGRESS;
+ create_explain_query_if_not_exists(thd->lex, thd->mem_root);
int res= optimize_inner();
if (!res && have_query_plan != QEP_DELETED)
{
- create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE;
save_explain_data(thd->lex->explain, false /* can overwrite */,
need_tmp,
@@ -4267,7 +4270,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
for (i= 0; i < join->table_count ; i++)
if (double rr= join->best_positions[i].records_read)
records= COST_MULT(records, rr);
- ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records;
+ ha_rows rows= records > (double) HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records;
set_if_smaller(rows, unit->select_limit_cnt);
join->select_lex->increase_derived_records(rows);
}
@@ -13669,12 +13672,16 @@ static int compare_fields_by_table_order(Item *field1,
{
int cmp= 0;
bool outer_ref= 0;
- Item_field *f1= (Item_field *) (field1->real_item());
- Item_field *f2= (Item_field *) (field2->real_item());
- if (field1->const_item() || f1->const_item())
+ Item *field1_real= field1->real_item();
+ Item *field2_real= field2->real_item();
+
+ if (field1->const_item() || field1_real->const_item())
return 1;
- if (field2->const_item() || f2->const_item())
+ if (field2->const_item() || field2_real->const_item())
return -1;
+
+ Item_field *f1= (Item_field *) field1_real;
+ Item_field *f2= (Item_field *) field2_real;
if (f2->used_tables() & OUTER_REF_TABLE_BIT)
{
outer_ref= 1;
@@ -21597,6 +21604,9 @@ check_reverse_order:
else if (select && select->quick)
select->quick->need_sorted_output();
+ tab->read_record.unlock_row= (tab->type == JT_EQ_REF) ?
+ join_read_key_unlock_row : rr_unlock_row;
+
} // QEP has been modified
/*
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index fbdb76e9e71..8eba6ef6027 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
- Copyright (c) 2009, 2017, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
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
@@ -4953,6 +4953,29 @@ bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
}
+/*
+ Check if the specified database exists on disk.
+
+ @param dbname - the database name
+ @retval true - on error, the database directory does not exists
+ @retval false - on success, the database directory exists
+*/
+static bool verify_database_directory_exists(const LEX_STRING &dbname)
+{
+ DBUG_ENTER("verify_database_directory_exists");
+ char path[FN_REFLEN + 16];
+ uint path_len;
+ MY_STAT stat_info;
+ if (!dbname.str[0])
+ DBUG_RETURN(true); // Empty database name: does not exist.
+ path_len= build_table_filename(path, sizeof(path) - 1, dbname.str, "", "", 0);
+ path[path_len - 1]= 0;
+ if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0)))
+ DBUG_RETURN(true); // The database directory was not found: does not exist.
+ DBUG_RETURN(false); // The database directory was found.
+}
+
+
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
{
/*
@@ -4981,19 +5004,10 @@ int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
If we have lookup db value we should check that the database exists
*/
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
- db_names.at(0) != &INFORMATION_SCHEMA_NAME)
- {
- char path[FN_REFLEN+16];
- uint path_len;
- MY_STAT stat_info;
- if (!lookup_field_vals.db_value.str[0])
- DBUG_RETURN(0);
- path_len= build_table_filename(path, sizeof(path) - 1,
- lookup_field_vals.db_value.str, "", "", 0);
- path[path_len-1]= 0;
- if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0)))
- DBUG_RETURN(0);
- }
+ (!db_names.elements() /* The database name was too long */||
+ (db_names.at(0) != &INFORMATION_SCHEMA_NAME &&
+ verify_database_directory_exists(lookup_field_vals.db_value))))
+ DBUG_RETURN(0);
for (size_t i=0; i < db_names.elements(); i++)
{
@@ -5863,7 +5877,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
{
free_table_share(&share);
if (free_sp_head)
- delete sp;
+ sp_head::destroy(sp);
DBUG_RETURN(1);
}
}
@@ -5919,7 +5933,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
}
}
if (free_sp_head)
- delete sp;
+ sp_head::destroy(sp);
}
free_table_share(&share);
DBUG_RETURN(error);
@@ -6012,7 +6026,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
store_column_type(table, field, cs, 5);
free_table_share(&share);
if (free_sp_head)
- delete sp;
+ sp_head::destroy(sp);
}
}
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 11e2db9ae44..c2581fd6105 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -2096,8 +2096,8 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
sizeof(Index_statistics) * keys);
uint key_parts= table->s->ext_key_parts;
- ulong *idx_avg_frequency= (ulong*) alloc_root(&table->mem_root,
- sizeof(ulong) * key_parts);
+ ulonglong *idx_avg_frequency= (ulonglong*) alloc_root(&table->mem_root,
+ sizeof(ulonglong) * key_parts);
uint columns= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++)
@@ -2142,7 +2142,7 @@ int alloc_statistics_for_table(THD* thd, TABLE *table)
}
}
- memset(idx_avg_frequency, 0, sizeof(ulong) * key_parts);
+ memset(idx_avg_frequency, 0, sizeof(ulonglong) * key_parts);
KEY *key_info, *end;
for (key_info= table->key_info, end= key_info + table->s->keys;
@@ -2204,27 +2204,13 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share)
DBUG_ENTER("alloc_statistics_for_table_share");
- DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
- DEBUG_SYNC(thd, "statistics_mem_alloc_start2");
-
- mysql_mutex_lock(&table_share->LOCK_share);
-
- if (stats_cb->stats_can_be_read)
- {
- mysql_mutex_unlock(&table_share->LOCK_share);
- DBUG_RETURN(0);
- }
-
Table_statistics *table_stats= stats_cb->table_stats;
if (!table_stats)
{
table_stats= (Table_statistics *) alloc_root(&stats_cb->mem_root,
sizeof(Table_statistics));
if (!table_stats)
- {
- mysql_mutex_unlock(&table_share->LOCK_share);
DBUG_RETURN(1);
- }
memset(table_stats, 0, sizeof(Table_statistics));
stats_cb->table_stats= table_stats;
}
@@ -2272,14 +2258,14 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share)
}
uint key_parts= table_share->ext_key_parts;
- ulong *idx_avg_frequency= table_stats->idx_avg_frequency;
+ ulonglong *idx_avg_frequency= table_stats->idx_avg_frequency;
if (!idx_avg_frequency)
{
- idx_avg_frequency= (ulong*) alloc_root(&stats_cb->mem_root,
- sizeof(ulong) * key_parts);
+ idx_avg_frequency= (ulonglong*) alloc_root(&stats_cb->mem_root,
+ sizeof(ulonglong) * key_parts);
if (idx_avg_frequency)
{
- memset(idx_avg_frequency, 0, sizeof(ulong) * key_parts);
+ memset(idx_avg_frequency, 0, sizeof(ulonglong) * key_parts);
table_stats->idx_avg_frequency= idx_avg_frequency;
for (key_info= table_share->key_info, end= key_info + keys;
key_info < end;
@@ -2290,89 +2276,11 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share)
}
}
}
-
- if (column_stats && index_stats && idx_avg_frequency)
- stats_cb->stats_can_be_read= TRUE;
-
- mysql_mutex_unlock(&table_share->LOCK_share);
-
- DBUG_RETURN(0);
+ DBUG_RETURN(column_stats && index_stats && idx_avg_frequency ? 0 : 1);
}
/**
- @brief
- Allocate memory for the histogram used by a table share
-
- @param
- thd Thread handler
- @param
- table_share Table share for which the memory for histogram data is allocated
- @param
- is_safe TRUE <-> at any time only one thread can perform the function
-
- @note
- The function allocates the memory for the histogram built for a table in the
- table's share memory with the intention to read the data there from the
- system persistent statistical table mysql.column_stats,
- The memory is allocated in the table_share's mem_root.
- If the parameter is_safe is TRUE then it is guaranteed that at any given time
- only one thread is executed the code of the function.
-
- @retval
- 0 If the memory for all statistical data has been successfully allocated
- @retval
- 1 Otherwise
-
- @note
- Currently the function always is called with the parameter is_safe set
- to FALSE.
-*/
-
-static
-int alloc_histograms_for_table_share(THD* thd, TABLE_SHARE *table_share,
- bool is_safe)
-{
- TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb;
-
- DBUG_ENTER("alloc_histograms_for_table_share");
-
- if (!is_safe)
- mysql_mutex_lock(&table_share->LOCK_share);
-
- if (stats_cb->histograms_can_be_read)
- {
- if (!is_safe)
- mysql_mutex_unlock(&table_share->LOCK_share);
- DBUG_RETURN(0);
- }
-
- Table_statistics *table_stats= stats_cb->table_stats;
- ulong total_hist_size= table_stats->total_hist_size;
-
- if (total_hist_size && !table_stats->histograms)
- {
- uchar *histograms= (uchar *) alloc_root(&stats_cb->mem_root,
- total_hist_size);
- if (!histograms)
- {
- if (!is_safe)
- mysql_mutex_unlock(&table_share->LOCK_share);
- DBUG_RETURN(1);
- }
- memset(histograms, 0, total_hist_size);
- table_stats->histograms= histograms;
- stats_cb->histograms_can_be_read= TRUE;
- }
-
- if (!is_safe)
- mysql_mutex_unlock(&table_share->LOCK_share);
-
- DBUG_RETURN(0);
-
-}
-
-/**
@brief
Initialize the aggregation fields to collect statistics on a column
@@ -2913,11 +2821,22 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
Field **field_ptr;
KEY *key_info, *key_info_end;
TABLE_SHARE *table_share= table->s;
- Table_statistics *read_stats= table_share->stats_cb.table_stats;
DBUG_ENTER("read_statistics_for_table");
+ DEBUG_SYNC(thd, "statistics_mem_alloc_start1");
+ DEBUG_SYNC(thd, "statistics_mem_alloc_start2");
+
+ if (!table_share->stats_cb.start_stats_load())
+ DBUG_RETURN(table_share->stats_cb.stats_are_ready() ? 0 : 1);
+
+ if (alloc_statistics_for_table_share(thd, table_share))
+ {
+ table_share->stats_cb.abort_stats_load();
+ DBUG_RETURN(1);
+ }
/* Read statistics from the statistical table table_stats */
+ Table_statistics *read_stats= table_share->stats_cb.table_stats;
stat_table= stat_tables[TABLE_STAT].table;
Table_stat table_stat(stat_table, table);
table_stat.set_key_fields();
@@ -2934,7 +2853,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
column_stat.get_stat_values();
total_hist_size+= table_field->read_stats->histogram.get_size();
}
- read_stats->total_hist_size= total_hist_size;
+ table_share->stats_cb.total_hist_size= total_hist_size;
/* Read statistics from the statistical table index_stats */
stat_table= stat_tables[INDEX_STAT].table;
@@ -2995,9 +2914,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
}
}
}
-
- table->stats_is_read= TRUE;
-
+ table_share->stats_cb.end_stats_load();
DBUG_RETURN(0);
}
@@ -3037,71 +2954,6 @@ void delete_stat_values_for_table_share(TABLE_SHARE *table_share)
/**
@brief
- Check whether any statistics is to be read for tables from a table list
-
- @param
- thd The thread handle
- @param
- tables The tables list for whose tables the check is to be done
-
- @details
- The function checks whether for any of the tables opened and locked for
- a statement statistics from statistical tables is needed to be read.
-
- @retval
- TRUE statistics for any of the tables is needed to be read
- @retval
- FALSE Otherwise
-*/
-
-static
-bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables)
-{
- if (!tables)
- return FALSE;
-
- /*
- Do not read statistics for any query that explicity involves
- statistical tables, failure to to do so we may end up
- in a deadlock.
- */
-
- for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
- {
- if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table)
- {
- TABLE_SHARE *table_share= tl->table->s;
- if (table_share &&
- table_share->table_category != TABLE_CATEGORY_USER
- && is_stat_table(tl->db, tl->alias))
- return FALSE;
- }
- }
-
- for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
- {
- if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table)
- {
- TABLE_SHARE *table_share= tl->table->s;
- if (table_share &&
- table_share->stats_cb.stats_can_be_read &&
- (!table_share->stats_cb.stats_is_read ||
- (!table_share->stats_cb.histograms_are_read &&
- thd->variables.optimizer_use_condition_selectivity > 3)))
- return TRUE;
- if (table_share->stats_cb.stats_is_read)
- tl->table->stats_is_read= TRUE;
- if (table_share->stats_cb.histograms_are_read)
- tl->table->histograms_are_read= TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-/**
- @brief
Read histogram for a table from the persistent statistical tables
@param
@@ -3135,26 +2987,25 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables)
static
int read_histograms_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
{
- TABLE_SHARE *table_share= table->s;
-
+ TABLE_STATISTICS_CB *stats_cb= &table->s->stats_cb;
DBUG_ENTER("read_histograms_for_table");
- if (!table_share->stats_cb.histograms_can_be_read)
+ if (stats_cb->start_histograms_load())
{
- (void) alloc_histograms_for_table_share(thd, table_share, FALSE);
- }
- if (table_share->stats_cb.histograms_can_be_read &&
- !table_share->stats_cb.histograms_are_read)
- {
- Field **field_ptr;
- uchar *histogram= table_share->stats_cb.table_stats->histograms;
- TABLE *stat_table= stat_tables[COLUMN_STAT].table;
- Column_stat column_stat(stat_table, table);
- for (field_ptr= table_share->field; *field_ptr; field_ptr++)
+ uchar *histogram= (uchar *) alloc_root(&stats_cb->mem_root,
+ stats_cb->total_hist_size);
+ if (!histogram)
+ {
+ stats_cb->abort_histograms_load();
+ DBUG_RETURN(1);
+ }
+ memset(histogram, 0, stats_cb->total_hist_size);
+
+ Column_stat column_stat(stat_tables[COLUMN_STAT].table, table);
+ for (Field **field_ptr= table->s->field; *field_ptr; field_ptr++)
{
Field *table_field= *field_ptr;
- uint hist_size= table_field->read_stats->histogram.get_size();
- if (hist_size)
+ if (uint hist_size= table_field->read_stats->histogram.get_size())
{
column_stat.set_key_fields(table_field);
table_field->read_stats->histogram.set_values(histogram);
@@ -3162,8 +3013,9 @@ int read_histograms_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
histogram+= hist_size;
}
}
+ stats_cb->end_histograms_load();
}
-
+ table->histograms_are_read= true;
DBUG_RETURN(0);
}
@@ -3211,6 +3063,23 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables)
}
+static void dump_stats_from_share_to_table(TABLE *table)
+{
+ TABLE_SHARE *table_share= table->s;
+ KEY *key_info= table_share->key_info;
+ KEY *key_info_end= key_info + table_share->keys;
+ KEY *table_key_info= table->key_info;
+ for ( ; key_info < key_info_end; key_info++, table_key_info++)
+ table_key_info->read_stats= key_info->read_stats;
+
+ Field **field_ptr= table_share->field;
+ Field **table_field_ptr= table->field;
+ for ( ; *field_ptr; field_ptr++, table_field_ptr++)
+ (*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
+ table->stats_is_read= true;
+}
+
+
int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST stat_tables[STATISTICS_TABLES];
@@ -3221,38 +3090,42 @@ int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
if (thd->bootstrap || thd->variables.use_stat_tables == NEVER)
DBUG_RETURN(0);
+ bool found_stat_table= false;
+ bool statistics_for_tables_is_needed= false;
+
for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
{
- if (tl->table)
+ TABLE_SHARE *table_share;
+ if (!tl->is_view_or_derived() && tl->table && (table_share= tl->table->s) &&
+ table_share->tmp_table == NO_TMP_TABLE)
{
- TABLE_SHARE *table_share= tl->table->s;
- if (table_share && table_share->table_category == TABLE_CATEGORY_USER &&
- table_share->tmp_table == NO_TMP_TABLE)
+ if (table_share->table_category == TABLE_CATEGORY_USER)
{
- if (table_share->stats_cb.stats_can_be_read ||
- !alloc_statistics_for_table_share(thd, table_share))
+ if (table_share->stats_cb.stats_are_ready())
{
- if (table_share->stats_cb.stats_can_be_read)
- {
- KEY *key_info= table_share->key_info;
- KEY *key_info_end= key_info + table_share->keys;
- KEY *table_key_info= tl->table->key_info;
- for ( ; key_info < key_info_end; key_info++, table_key_info++)
- table_key_info->read_stats= key_info->read_stats;
- Field **field_ptr= table_share->field;
- Field **table_field_ptr= tl->table->field;
- for ( ; *field_ptr; field_ptr++, table_field_ptr++)
- (*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
- tl->table->stats_is_read= table_share->stats_cb.stats_is_read;
- }
+ if (!tl->table->stats_is_read)
+ dump_stats_from_share_to_table(tl->table);
+ tl->table->histograms_are_read=
+ table_share->stats_cb.histograms_are_ready();
+ if (table_share->stats_cb.histograms_are_ready() ||
+ thd->variables.optimizer_use_condition_selectivity <= 3)
+ continue;
}
+ statistics_for_tables_is_needed= true;
}
+ else if (is_stat_table(tl->db, tl->alias))
+ found_stat_table= true;
}
}
DEBUG_SYNC(thd, "statistics_read_start");
- if (!statistics_for_tables_is_needed(thd, tables))
+ /*
+ Do not read statistics for any query that explicity involves
+ statistical tables, failure to to do so we may end up
+ in a deadlock.
+ */
+ if (found_stat_table || !statistics_for_tables_is_needed)
DBUG_RETURN(0);
if (open_stat_tables(thd, stat_tables, &open_tables_backup, FALSE))
@@ -3260,32 +3133,22 @@ int read_statistics_for_tables(THD *thd, TABLE_LIST *tables)
for (TABLE_LIST *tl= tables; tl; tl= tl->next_global)
{
- if (!tl->is_view_or_derived() && !is_temporary_table(tl) && tl->table)
- {
- TABLE_SHARE *table_share= tl->table->s;
- if (table_share && !(table_share->table_category == TABLE_CATEGORY_USER))
- continue;
-
- if (table_share &&
- table_share->stats_cb.stats_can_be_read &&
- !table_share->stats_cb.stats_is_read)
+ TABLE_SHARE *table_share;
+ if (!tl->is_view_or_derived() && tl->table && (table_share= tl->table->s) &&
+ table_share->tmp_table == NO_TMP_TABLE &&
+ table_share->table_category == TABLE_CATEGORY_USER)
+ {
+ if (!tl->table->stats_is_read)
{
- (void) read_statistics_for_table(thd, tl->table, stat_tables);
- table_share->stats_cb.stats_is_read= TRUE;
+ if (!read_statistics_for_table(thd, tl->table, stat_tables))
+ dump_stats_from_share_to_table(tl->table);
+ else
+ continue;
}
- if (table_share->stats_cb.stats_is_read)
- tl->table->stats_is_read= TRUE;
- if (thd->variables.optimizer_use_condition_selectivity > 3 &&
- table_share && table_share->stats_cb.stats_can_be_read &&
- !table_share->stats_cb.histograms_are_read)
- {
+ if (thd->variables.optimizer_use_condition_selectivity > 3)
(void) read_histograms_for_table(thd, tl->table, stat_tables);
- table_share->stats_cb.histograms_are_read= TRUE;
- }
- if (table_share->stats_cb.histograms_are_read)
- tl->table->histograms_are_read= TRUE;
}
- }
+ }
close_system_tables(thd, &open_tables_backup);
diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h
index 71d727eab07..903d164ca99 100644
--- a/sql/sql_statistics.h
+++ b/sql/sql_statistics.h
@@ -279,8 +279,9 @@ public:
uchar *min_max_record_buffers; /* Record buffers for min/max values */
Column_statistics *column_stats; /* Array of statistical data for columns */
Index_statistics *index_stats; /* Array of statistical data for indexes */
- ulong *idx_avg_frequency; /* Array of records per key for index prefixes */
- ulong total_hist_size; /* Total size of all histograms */
+
+ /* Array of records per key for index prefixes */
+ ulonglong *idx_avg_frequency;
uchar *histograms; /* Sequence of histograms */
};
@@ -332,7 +333,7 @@ private:
CHAR values are stripped of trailing spaces.
Flexible values are stripped of their length prefixes.
*/
- ulong avg_length;
+ ulonglong avg_length;
/*
The ratio N/D multiplied by the scale factor Scale_factor_avg_frequency,
@@ -340,7 +341,7 @@ private:
N is the number of rows with not null value in the column,
D the number of distinct values among them
*/
- ulong avg_frequency;
+ ulonglong avg_frequency;
public:
@@ -390,12 +391,12 @@ public:
void set_avg_length (double val)
{
- avg_length= (ulong) (val * Scale_factor_avg_length);
+ avg_length= (ulonglong) (val * Scale_factor_avg_length);
}
void set_avg_frequency (double val)
{
- avg_frequency= (ulong) (val * Scale_factor_avg_frequency);
+ avg_frequency= (ulonglong) (val * Scale_factor_avg_frequency);
}
bool min_max_values_are_provided()
@@ -434,11 +435,11 @@ private:
in the first k components, and D is the number of distinct
k-component prefixes among them
*/
- ulong *avg_frequency;
+ ulonglong *avg_frequency;
public:
- void init_avg_frequency(ulong *ptr) { avg_frequency= ptr; }
+ void init_avg_frequency(ulonglong *ptr) { avg_frequency= ptr; }
bool avg_frequency_is_inited() { return avg_frequency != NULL; }
@@ -449,7 +450,7 @@ public:
void set_avg_frequency(uint i, double val)
{
- avg_frequency[i]= (ulong) (val * Scale_factor_avg_frequency);
+ avg_frequency[i]= (ulonglong) (val * Scale_factor_avg_frequency);
}
};
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 6fd3d7a10db..fe756fe1cdf 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -3,7 +3,7 @@
/*
Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2008, 2013, Monty Program Ab.
+ Copyright (c) 2008, 2020, MariaDB Corporation.
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
@@ -512,7 +512,8 @@ public:
}
void q_append(const char *data, uint32 data_len)
{
- memcpy(Ptr + str_length, data, data_len);
+ if (data_len)
+ memcpy(Ptr + str_length, data, data_len);
str_length += data_len;
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index e694c52e272..ef6a8c01843 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2010, 2019, MariaDB
+ Copyright (c) 2010, 2020, MariaDB
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
@@ -5338,7 +5338,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
DBUG_ENTER("mysql_create_like_table");
#ifdef WITH_WSREP
- if (WSREP_ON && !thd->wsrep_applier &&
+ if (WSREP(thd) && !thd->wsrep_applier &&
wsrep_create_like_table(thd, table, src_table, create_info))
DBUG_RETURN(res);
#endif
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index 6d94de047e8..421eb79c7a3 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013 Monty Program Ab.
+ Copyright (c) 2009, 2020, MariaDB Corporation.
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
@@ -402,7 +402,7 @@ bool double_to_datetime_with_warn(double value, MYSQL_TIME *ltime,
if (neg)
value= -value;
- if (value > LONGLONG_MAX)
+ if (value > static_cast<double>(LONGLONG_MAX))
value= static_cast<double>(LONGLONG_MAX);
longlong nr= static_cast<ulonglong>(floor(value));
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 4ecd8139921..2972ceecd8a 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -34,7 +34,9 @@
#include "sql_handler.h" // mysql_ha_rm_tables
#include "sp_cache.h" // sp_invalidate_cache
#include <mysys_err.h>
-
+#ifdef WITH_WSREP
+#include "debug_sync.h"
+#endif /* WITH_WSREP */
/*************************************************************************/
template <class T>
@@ -506,7 +508,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
#ifdef WITH_WSREP
if (thd->wsrep_exec_mode == LOCAL_STATE)
- WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
+ WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, tables);
#endif
/* We should have only one table in table list. */
@@ -568,6 +570,16 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
goto end;
}
+#ifdef WITH_WSREP
+ DBUG_EXECUTE_IF("sync.mdev_20225",
+ {
+ const char act[]=
+ "now "
+ "wait_for signal.mdev_20225_continue";
+ DBUG_ASSERT(!debug_sync_set_action(thd,
+ STRING_WITH_LEN(act)));
+ };);
+#endif /* WITH_WSREP */
result= (create ?
table->triggers->create_trigger(thd, tables, &stmt_query):
table->triggers->drop_trigger(thd, tables, &stmt_query));
@@ -1063,7 +1075,7 @@ Table_triggers_list::~Table_triggers_list()
{
for (int i= 0; i < (int)TRG_EVENT_MAX; i++)
for (int j= 0; j < (int)TRG_ACTION_MAX; j++)
- delete bodies[i][j];
+ sp_head::destroy(bodies[i][j]);
/* Free blobs used in insert */
if (record0_field)
diff --git a/sql/sql_type_int.h b/sql/sql_type_int.h
index 74e59b08385..5988a985a2d 100644
--- a/sql/sql_type_int.h
+++ b/sql/sql_type_int.h
@@ -67,6 +67,26 @@ public:
*/
return cmp_signed(other);
}
+ bool operator==(const Longlong_hybrid &nr) const
+ {
+ return cmp(nr) == 0;
+ }
+ bool operator==(ulonglong nr) const
+ {
+ return cmp(Longlong_hybrid((longlong) nr, true)) == 0;
+ }
+ bool operator==(uint nr) const
+ {
+ return cmp(Longlong_hybrid((longlong) nr, true)) == 0;
+ }
+ bool operator==(longlong nr) const
+ {
+ return cmp(Longlong_hybrid(nr, false)) == 0;
+ }
+ bool operator==(int nr) const
+ {
+ return cmp(Longlong_hybrid(nr, false)) == 0;
+ }
};
#endif // SQL_TYPE_INT_INCLUDED
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 38de2d592ed..0e623777ef0 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -388,6 +388,25 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS;
is_union_select= is_union() || fake_select_lex;
+ /*
+ If we are reading UNION output and the UNION is in the
+ IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should
+ be removed.
+ Example:
+ select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1)
+
+ (as for ORDER BY ... LIMIT, it currently not supported inside
+ IN/ALL/ANY subqueries)
+ (For non-UNION this removal of ORDER BY clause is done in
+ check_and_do_in_subquery_rewrites())
+ */
+ if (is_union() && item &&
+ (item->is_in_predicate() || item->is_exists_predicate()))
+ {
+ global_parameters()->order_list.first= NULL;
+ global_parameters()->order_list.elements= 0;
+ }
+
/* Global option */
if (is_union_select)
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 1360bf9fb74..f44aaa2ea99 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -413,6 +413,8 @@ int mysql_update(THD *thd,
query_plan.set_no_partitions();
if (thd->lex->describe || thd->lex->analyze_stmt)
goto produce_explain_and_leave;
+ if (thd->is_error())
+ DBUG_RETURN(1);
my_ok(thd); // No matching records
DBUG_RETURN(0);
@@ -1119,8 +1121,7 @@ bool mysql_prepare_update(THD *thd, TABLE_LIST *table_list,
DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &select_lex->context,
- &select_lex->top_join_list,
- table_list,
+ &select_lex->top_join_list, table_list,
select_lex->leaf_tables,
FALSE, UPDATE_ACL, SELECT_ACL, TRUE) ||
setup_conds(thd, table_list, select_lex->leaf_tables, conds) ||
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index cb92f30c932..0984372fedc 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -442,9 +442,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
if (open_temporary_tables(thd, lex->query_tables) ||
open_and_lock_tables(thd, lex->query_tables, TRUE, 0))
{
- view= lex->unlink_first_table(&link_to_local);
res= TRUE;
- goto err;
+ goto err_no_relink;
}
view= lex->unlink_first_table(&link_to_local);
@@ -694,10 +693,12 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
WSREP_ERROR_LABEL:
res= TRUE;
+ goto err_no_relink;
err:
THD_STAGE_INFO(thd, stage_end);
lex->link_first_table_back(view, link_to_local);
+err_no_relink:
unit->cleanup();
DBUG_RETURN(res || thd->is_error());
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 71e0a18b1a3..2a46bb2a027 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -224,7 +224,7 @@ static sp_head *make_sp_head(THD *thd, sp_name *name,
sp_head *sp;
/* Order is important here: new - reset - init */
- if ((sp= new sp_head()))
+ if ((sp= sp_head::create()))
{
sp->reset_thd_mem_root(thd);
sp->init(lex);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 9f87c846fd0..7dc1d1ab6e8 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2178,7 +2178,7 @@ static Sys_var_ulong Sys_max_sort_length(
"the first max_sort_length bytes of each value are used; the rest "
"are ignored)",
SESSION_VAR(max_sort_length), CMD_LINE(REQUIRED_ARG),
- VALID_RANGE(4, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1));
+ VALID_RANGE(8, 8192*1024L), DEFAULT(1024), BLOCK_SIZE(1));
static Sys_var_ulong Sys_max_sp_recursion_depth(
"max_sp_recursion_depth",
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index ae4568866b7..737f9bb545c 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -614,7 +614,11 @@ public:
{ DBUG_ASSERT(FALSE); }
void global_save_default(THD *thd, set_var *var)
- { DBUG_ASSERT(FALSE); }
+ {
+ char *ptr= (char*)(intptr)option.def_value;
+ var->save_result.string_value.str= ptr;
+ var->save_result.string_value.length= ptr ? strlen(ptr) : 0;
+ }
bool session_update(THD *thd, set_var *var)
{
diff --git a/sql/table.cc b/sql/table.cc
index 52e63ea7389..20fc86e35f0 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -64,8 +64,11 @@ LEX_STRING parse_vcol_keyword= { C_STRING_WITH_LEN("PARSE_VCOL_EXPR ") };
/* Functions defined in this file */
-static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
- uint types, char **names);
+static bool fix_type_pointers(const char ***typelib_value_names,
+ uint **typelib_value_lengths,
+ TYPELIB *point_to_type, uint types,
+ char *names, size_t names_length);
+
static uint find_field(Field **fields, uchar *record, uint start, uint length);
inline bool is_system_table_name(const char *name, uint length);
@@ -413,10 +416,6 @@ void TABLE_SHARE::destroy()
delete_stat_values_for_table_share(this);
free_root(&stats_cb.mem_root, MYF(0));
- stats_cb.stats_can_be_read= FALSE;
- stats_cb.stats_is_read= FALSE;
- stats_cb.histograms_can_be_read= FALSE;
- stats_cb.histograms_are_read= FALSE;
/* The mutexes are initialized only for shares that are part of the TDC */
if (tmp_table == NO_TMP_TABLE)
@@ -670,7 +669,8 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
uint keys, KEY *keyinfo,
uint new_frm_ver, uint &ext_key_parts,
TABLE_SHARE *share, uint len,
- KEY *first_keyinfo, char* &keynames)
+ KEY *first_keyinfo,
+ LEX_STRING *keynames)
{
uint i, j, n_length;
KEY_PART_INFO *key_part= NULL;
@@ -813,10 +813,13 @@ static bool create_key_infos(const uchar *strpos, const uchar *frm_image_end,
}
share->ext_key_parts+= keyinfo->ext_key_parts;
}
- keynames=(char*) key_part;
- strpos+= strnmov(keynames, (char *) strpos, frm_image_end - strpos) - keynames;
+ keynames->str= (char*) key_part;
+ keynames->length= strnmov(keynames->str, (char *) strpos,
+ frm_image_end - strpos) - keynames->str;
+ strpos+= keynames->length;
if (*strpos++) // key names are \0-terminated
return 1;
+ keynames->length++; // Include '\0', to make fix_type_pointers() happy.
//reading index comments
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
@@ -918,12 +921,14 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
TABLE_SHARE *share= this;
uint new_frm_ver, field_pack_length, new_field_pack_flag;
uint interval_count, interval_parts, read_length, int_length;
+ uint total_typelib_value_count;
uint db_create_options, keys, key_parts, n_length;
uint com_length, null_bit_pos;
uint extra_rec_buf_length;
uint i;
bool use_hash;
- char *keynames, *names, *comment_pos;
+ LEX_STRING keynames= {NULL, 0};
+ char *names, *comment_pos;
const uchar *forminfo, *extra2;
const uchar *frm_image_end = frm_image + frm_length;
uchar *record, *null_flags, *null_pos;
@@ -935,6 +940,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
KEY_PART_INFO *key_part= NULL;
Field **field_ptr, *reg_field;
const char **interval_array;
+ uint *typelib_value_lengths= NULL;
enum legacy_db_type legacy_db_type;
my_bitmap_map *bitmaps;
bool null_bits_are_used;
@@ -1237,7 +1243,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
new_frm_ver, ext_key_parts,
- share, len, &first_keyinfo, keynames))
+ share, len, &first_keyinfo, &keynames))
goto err;
if (next_chunk + 5 < buff_end)
@@ -1330,7 +1336,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
{
if (create_key_infos(disk_buff + 6, frm_image_end, keys, keyinfo,
new_frm_ver, ext_key_parts,
- share, len, &first_keyinfo, keynames))
+ share, len, &first_keyinfo, &keynames))
goto err;
}
@@ -1372,6 +1378,24 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
DBUG_PRINT("info",("i_count: %d i_parts: %d index: %d n_length: %d int_length: %d com_length: %d vcol_screen_length: %d", interval_count,interval_parts, keys,n_length,int_length, com_length, vcol_screen_length));
+ /*
+ We load the following things into TYPELIBs:
+ - One TYPELIB for field names
+ - interval_count TYPELIBs for ENUM/SET values
+ - One TYPELIB for key names
+ Every TYPELIB requires one extra value with a NULL pointer and zero length,
+ which is the end-of-values marker.
+ TODO-10.5+:
+ Note, we should eventually reuse this total_typelib_value_count
+ to allocate interval_array. The above code reserves less space
+ than total_typelib_value_count pointers. So it seems `interval_array`
+ and `names` overlap in the memory. Too dangerous to fix in 10.1.
+ */
+ total_typelib_value_count=
+ (share->fields + 1/*end-of-values marker*/) +
+ (interval_parts + interval_count/*end-of-values markers*/) +
+ (keys + 1/*end-of-values marker*/);
+
if (!(field_ptr = (Field **)
alloc_root(&share->mem_root,
@@ -1383,6 +1407,12 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
vcol_screen_length)))))
goto err; /* purecov: inspected */
+
+ if (!(typelib_value_lengths= (uint *) alloc_root(&share->mem_root,
+ total_typelib_value_count *
+ sizeof(uint *))))
+ goto err;
+
share->field= field_ptr;
read_length=(uint) (share->fields * field_pack_length +
pos+ (uint) (n_length+int_length+com_length+
@@ -1391,6 +1421,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
interval_array= (const char **) (share->intervals+interval_count);
+ // This looks wrong: shouldn't it be (+2+interval_count) instread of (+3) ?
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
if (!interval_count)
share->intervals= 0; // For better debugging
@@ -1403,34 +1434,21 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length,
vcol_screen_length);
- fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
- if (share->fieldnames.count != share->fields)
+ if (fix_type_pointers(&interval_array, &typelib_value_lengths,
+ &share->fieldnames, 1, names, n_length) ||
+ share->fieldnames.count != share->fields)
goto err;
- fix_type_pointers(&interval_array, share->intervals, interval_count,
- &names);
- {
- /* Set ENUM and SET lengths */
- TYPELIB *interval;
- for (interval= share->intervals;
- interval < share->intervals + interval_count;
- interval++)
- {
- uint count= (uint) (interval->count + 1) * sizeof(uint);
- if (!(interval->type_lengths= (uint *) alloc_root(&share->mem_root,
- count)))
- goto err;
- for (count= 0; count < interval->count; count++)
- {
- char *val= (char*) interval->type_names[count];
- interval->type_lengths[count]= strlen(val);
- }
- interval->type_lengths[count]= 0;
- }
- }
+ if (fix_type_pointers(&interval_array, &typelib_value_lengths,
+ share->intervals, interval_count,
+ names + n_length, int_length))
+ goto err;
- if (keynames)
- fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
+ if (keynames.length &&
+ (fix_type_pointers(&interval_array, &typelib_value_lengths,
+ &share->keynames, 1, keynames.str, keynames.length) ||
+ share->keynames.count != keys))
+ goto err;
/* Allocate handler */
if (!(handler_file= get_new_handler(share, thd->mem_root,
@@ -3216,37 +3234,81 @@ void open_table_error(TABLE_SHARE *share, enum open_frm_error error,
** with a '\0'
*/
-static void
-fix_type_pointers(const char ***array, TYPELIB *point_to_type, uint types,
- char **names)
+static bool
+fix_type_pointers(const char ***typelib_value_names,
+ uint **typelib_value_lengths,
+ TYPELIB *point_to_type, uint types,
+ char *ptr, size_t length)
{
- char *type_name, *ptr;
- char chr;
+ const char *end= ptr + length;
- ptr= *names;
while (types--)
{
+ char sep;
point_to_type->name=0;
- point_to_type->type_names= *array;
+ point_to_type->type_names= *typelib_value_names;
+ point_to_type->type_lengths= *typelib_value_lengths;
- if ((chr= *ptr)) /* Test if empty type */
+ /*
+ Typelib can be encoded as:
+ 1) 0x00 - empty typelib
+ 2) 0xFF 0x00 - empty typelib (index names)
+ 3) sep (value sep)... 0x00 - non-empty typelib (where sep is a separator)
+ */
+ if (length == 2 && ptr[0] == (char) 0xFF && ptr[1] == '\0')
+ {
+ /*
+ This is a special case #2.
+ If there are no indexes at all, index names can be encoded
+ as a two byte sequence: 0xFF 0x00
+ TODO: Check if it's a bug in the FRM packing routine.
+ It should probably write just 0x00 instead of 0xFF00.
+ */
+ ptr+= 2;
+ }
+ else if ((sep= *ptr++)) // A non-empty typelib
{
- while ((type_name=strchr(ptr+1,chr)) != NullS)
+ for ( ; ptr < end; )
{
- *((*array)++) = ptr+1;
- *type_name= '\0'; /* End string */
- ptr=type_name;
+ // Now scan the next value+sep pair
+ char *vend= (char*) memchr(ptr, sep, end - ptr);
+ if (!vend)
+ return true; // Bad format
+ *((*typelib_value_names)++)= ptr;
+ *((*typelib_value_lengths)++)= vend - ptr;
+ *vend= '\0'; // Change sep to '\0'
+ ptr= vend + 1; // Shift from sep to the next byte
+ /*
+ Now we can have either:
+ - the end-of-typelib marker (0x00)
+ - more value+sep pairs
+ */
+ if (!*ptr)
+ {
+ /*
+ We have an ambiguity here. 0x00 can be an end-of-typelib marker,
+ but it can also be a part of the next value:
+ CREATE TABLE t1 (a ENUM(0x61, 0x0062) CHARACTER SET BINARY);
+ If this is the last ENUM/SET in the table and there is still more
+ packed data left after 0x00, then we know for sure that 0x00
+ is a part of the next value.
+ TODO-10.5+: we should eventually introduce a new unambiguous
+ typelib encoding for FRM.
+ */
+ if (!types && ptr + 1 < end)
+ continue; // A binary value starting with 0x00
+ ptr++; // Consume the end-of-typelib marker
+ break; // End of the current typelib
+ }
}
- ptr+=2; /* Skip end mark and last 0 */
}
- else
- ptr++;
- point_to_type->count= (uint) (*array - point_to_type->type_names);
+ point_to_type->count= (uint) (*typelib_value_names -
+ point_to_type->type_names);
point_to_type++;
- *((*array)++)= NullS; /* End of type */
+ *((*typelib_value_names)++)= NullS; /* End of type */
+ *((*typelib_value_lengths)++)= 0; /* End of type */
}
- *names=ptr; /* Update end */
- return;
+ return ptr != end;
} /* fix_type_pointers */
@@ -3728,7 +3790,6 @@ bool check_column_name(const char *name)
been opened.
@param[in] table The table to check
- @param[in] table_f_count Expected number of columns in the table
@param[in] table_def Expected structure of the table (column name
and type)
diff --git a/sql/table.h b/sql/table.h
index 44803b5aacd..2ea9b514df4 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -594,15 +594,94 @@ enum open_frm_error {
from persistent statistical tables
*/
-struct TABLE_STATISTICS_CB
+class TABLE_STATISTICS_CB
{
+ class Statistics_state
+ {
+ enum state_codes
+ {
+ EMPTY, /** data is not loaded */
+ LOADING, /** data is being loaded in some connection */
+ READY /** data is loaded and available for use */
+ };
+ int32 state;
+
+ public:
+ /** No state copy */
+ Statistics_state &operator=(const Statistics_state &) { return *this; }
+
+ /** Checks if data loading have been completed */
+ bool is_ready() const
+ {
+ return my_atomic_load32_explicit(const_cast<int32*>(&state),
+ MY_MEMORY_ORDER_ACQUIRE) == READY;
+ }
+
+ /**
+ Sets mutual exclusion for data loading
+
+ If stats are in LOADING state, waits until state change.
+
+ @return
+ @retval true atomic EMPTY -> LOADING transfer completed, ok to load
+ @retval false stats are in READY state, no need to load
+ */
+ bool start_load()
+ {
+ for (;;)
+ {
+ int32 expected= EMPTY;
+ if (my_atomic_cas32_weak_explicit(&state, &expected, LOADING,
+ MY_MEMORY_ORDER_RELAXED,
+ MY_MEMORY_ORDER_RELAXED))
+ return true;
+ if (expected == READY)
+ return false;
+ (void) LF_BACKOFF;
+ }
+ }
+
+ /** Marks data available for subsequent use */
+ void end_load()
+ {
+ DBUG_ASSERT(my_atomic_load32_explicit(&state, MY_MEMORY_ORDER_RELAXED) ==
+ LOADING);
+ my_atomic_store32_explicit(&state, READY, MY_MEMORY_ORDER_RELEASE);
+ }
+
+ /** Restores empty state on error (e.g. OOM) */
+ void abort_load()
+ {
+ DBUG_ASSERT(my_atomic_load32_explicit(&state, MY_MEMORY_ORDER_RELAXED) ==
+ LOADING);
+ my_atomic_store32_explicit(&state, EMPTY, MY_MEMORY_ORDER_RELAXED);
+ }
+ };
+
+ class Statistics_state stats_state;
+ class Statistics_state hist_state;
+
+public:
MEM_ROOT mem_root; /* MEM_ROOT to allocate statistical data for the table */
Table_statistics *table_stats; /* Structure to access the statistical data */
- bool stats_can_be_read; /* Memory for statistical data is allocated */
- bool stats_is_read; /* Statistical data for table has been read
- from statistical tables */
- bool histograms_can_be_read;
- bool histograms_are_read;
+ ulong total_hist_size; /* Total size of all histograms */
+
+ bool histograms_are_ready() const
+ {
+ return !total_hist_size || hist_state.is_ready();
+ }
+
+ bool start_histograms_load()
+ {
+ return total_hist_size && hist_state.start_load();
+ }
+
+ void end_histograms_load() { hist_state.end_load(); }
+ void abort_histograms_load() { hist_state.abort_load(); }
+ bool stats_are_ready() const { return stats_state.is_ready(); }
+ bool start_stats_load() { return stats_state.start_load(); }
+ void end_stats_load() { stats_state.end_load(); }
+ void abort_stats_load() { stats_state.abort_load(); }
};
@@ -1212,9 +1291,16 @@ public:
/* number of select if it is derived table */
uint derived_select_number;
/*
- 0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0.
- If maybe_null !=0, this table is inner w.r.t. some outer join operation,
- and null_row may be true.
+ Possible values:
+ - 0 by default
+ - JOIN_TYPE_{LEFT|RIGHT} if the table is inner w.r.t an outer join
+ operation
+ - 1 if the SELECT has mixed_implicit_grouping=1. example:
+ select max(col1), col2 from t1. In this case, the query produces
+ one row with all columns having NULL values.
+
+ Interpetation: If maybe_null!=0, all fields of the table are considered
+ NULLable (and have NULL values when null_row=true)
*/
uint maybe_null;
int current_lock; /* Type of lock on table */
@@ -1813,6 +1899,9 @@ struct TABLE_LIST
open_type= routine ? OT_TEMPORARY_OR_BASE : OT_BASE_ONLY;
belong_to_view= belong_to_view_arg;
trg_event_map= trg_event_map_arg;
+ /* MDL is enough for read-only FK checks, we don't need the table */
+ if (prelocking_placeholder == FK && lock_type < TL_WRITE_ALLOW_WRITE)
+ open_strategy= OPEN_STUB;
**last_ptr= this;
prev_global= *last_ptr;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 960dde38237..fa5a24d3c8a 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2748,9 +2748,11 @@ main(int argc, char **argv)
printf("TRUNCATE TABLE time_zone_name;\n");
printf("TRUNCATE TABLE time_zone_transition;\n");
printf("TRUNCATE TABLE time_zone_transition_type;\n");
+ printf("START TRANSACTION;\n");
if (scan_tz_dir(root_name_end, 0, opt_verbose))
{
+ printf("ROLLBACK;\n");
fflush(stdout);
fprintf(stderr,
"There were fatal errors during processing "
@@ -2758,6 +2760,7 @@ main(int argc, char **argv)
return 1;
}
+ printf("COMMIT;\n");
printf("ALTER TABLE time_zone_transition "
"ORDER BY Time_zone_id, Transition_time;\n");
printf("ALTER TABLE time_zone_transition_type "
diff --git a/sql/uniques.cc b/sql/uniques.cc
index 03f25d31384..27da0fc54c6 100644
--- a/sql/uniques.cc
+++ b/sql/uniques.cc
@@ -317,6 +317,9 @@ double Unique::get_use_cost(uint *buffer, size_t nkeys, uint key_size,
max_elements_in_tree= ((size_t) max_in_memory_size /
ALIGN_SIZE(sizeof(TREE_ELEMENT)+key_size));
+ if (max_elements_in_tree == 0)
+ max_elements_in_tree= 1;
+
n_full_trees= nkeys / max_elements_in_tree;
last_tree_elems= nkeys % max_elements_in_tree;
@@ -781,7 +784,13 @@ bool Unique::get(TABLE *table)
/* Not enough memory; Save the result to file && free memory used by tree */
if (flush())
return 1;
- size_t buff_sz= (max_in_memory_size / full_size + 1) * full_size;
+
+ /*
+ merge_buffer must fit at least MERGEBUFF2 + 1 keys, because
+ merge_index() can merge that many BUFFPEKs at once. The extra space for
+ one key for Sort_param::unique_buff
+ */
+ size_t buff_sz= MY_MAX(MERGEBUFF2+1, max_in_memory_size/full_size+1) * full_size;
if (!(sort_buffer= (uchar*) my_malloc(buff_sz, MYF(MY_THREAD_SPECIFIC|MY_WME))))
return 1;
diff --git a/sql/unireg.cc b/sql/unireg.cc
index b116218b60e..2ccc440f71b 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -498,6 +498,18 @@ static uint pack_keys(uchar *keybuff, uint key_count, KEY *keyinfo,
} /* pack_keys */
+static uint typelib_values_packed_length(const TYPELIB *t)
+{
+ uint length= 0;
+ for (uint i= 0; t->type_names[i]; i++)
+ {
+ length+= t->type_lengths[i];
+ length++; /* Separator */
+ }
+ return length;
+}
+
+
/* Make formheader */
static bool pack_header(THD *thd, uchar *forminfo,
@@ -619,9 +631,8 @@ static bool pack_header(THD *thd, uchar *forminfo,
field->interval_id=get_interval_id(&int_count,create_fields,field);
if (old_int_count != int_count)
{
- for (const char **pos=field->interval->type_names ; *pos ; pos++)
- int_length+=(uint) strlen(*pos)+1; // field + suffix prefix
- int_parts+=field->interval->count+1;
+ int_length+= typelib_values_packed_length(field->interval);
+ int_parts+= field->interval->count + 1;
}
}
if (f_maybe_null(field->pack_flag))
@@ -710,11 +721,7 @@ static size_t packed_fields_length(List<Create_field> &create_fields)
{
int_count= field->interval_id;
length++;
- for (int i=0; field->interval->type_names[i]; i++)
- {
- length+= field->interval->type_lengths[i];
- length++;
- }
+ length+= typelib_values_packed_length(field->interval);
length++;
}
if (field->vcol_info)
diff --git a/sql/win_tzname_data.h b/sql/win_tzname_data.h
index 28a14ab7c11..03197227f8e 100644
--- a/sql/win_tzname_data.h
+++ b/sql/win_tzname_data.h
@@ -23,13 +23,13 @@
{L"Haiti Standard Time","America/Port-au-Prince"},
{L"Cuba Standard Time","America/Havana"},
{L"US Eastern Standard Time","America/Indianapolis"},
+{L"Turks And Caicos Standard Time","America/Grand_Turk"},
{L"Paraguay Standard Time","America/Asuncion"},
{L"Atlantic Standard Time","America/Halifax"},
{L"Venezuela Standard Time","America/Caracas"},
{L"Central Brazilian Standard Time","America/Cuiaba"},
{L"SA Western Standard Time","America/La_Paz"},
{L"Pacific SA Standard Time","America/Santiago"},
-{L"Turks And Caicos Standard Time","America/Grand_Turk"},
{L"Newfoundland Standard Time","America/St_Johns"},
{L"Tocantins Standard Time","America/Araguaina"},
{L"E. South America Standard Time","America/Sao_Paulo"},
@@ -46,11 +46,11 @@
{L"UTC","Etc/GMT"},
{L"GMT Standard Time","Europe/London"},
{L"Greenwich Standard Time","Atlantic/Reykjavik"},
+{L"Sao Tome Standard Time","Africa/Sao_Tome"},
+{L"Morocco Standard Time","Africa/Casablanca"},
{L"W. Europe Standard Time","Europe/Berlin"},
{L"Central Europe Standard Time","Europe/Budapest"},
{L"Romance Standard Time","Europe/Paris"},
-{L"Morocco Standard Time","Africa/Casablanca"},
-{L"Sao Tome Standard Time","Africa/Sao_Tome"},
{L"Central European Standard Time","Europe/Warsaw"},
{L"W. Central Africa Standard Time","Africa/Lagos"},
{L"Jordan Standard Time","Asia/Amman"},
@@ -81,11 +81,13 @@
{L"Mauritius Standard Time","Indian/Mauritius"},
{L"Saratov Standard Time","Europe/Saratov"},
{L"Georgian Standard Time","Asia/Tbilisi"},
+{L"Volgograd Standard Time","Europe/Volgograd"},
{L"Caucasus Standard Time","Asia/Yerevan"},
{L"Afghanistan Standard Time","Asia/Kabul"},
{L"West Asia Standard Time","Asia/Tashkent"},
{L"Ekaterinburg Standard Time","Asia/Yekaterinburg"},
{L"Pakistan Standard Time","Asia/Karachi"},
+{L"Qyzylorda Standard Time","Asia/Qyzylorda"},
{L"India Standard Time","Asia/Calcutta"},
{L"Sri Lanka Standard Time","Asia/Colombo"},
{L"Nepal Standard Time","Asia/Katmandu"},
diff --git a/sql/winservice.c b/sql/winservice.c
index d9605f3a6c4..7a7e7616e76 100644
--- a/sql/winservice.c
+++ b/sql/winservice.c
@@ -116,6 +116,23 @@ BOOL exclude_service(mysqld_service_properties *props)
}
+static void get_datadir_from_ini(const char *ini, char *service_name, char *datadir, size_t sz)
+{
+ *datadir= 0;
+ const char *sections[]= {service_name, "mysqld", "server", "mariadb",
+ "mariadbd"};
+ for (int i= 0; i < sizeof(sections) / sizeof(sections[0]); i++)
+ {
+ if (sections[i])
+ {
+ GetPrivateProfileStringA(sections[i], "datadir", NULL, datadir, sz, ini);
+ if (*datadir)
+ return;
+ }
+ }
+}
+
+
/*
Retrieve some properties from windows mysqld service binary path.
We're interested in ini file location and datadir, and also in version of
@@ -135,6 +152,7 @@ int get_mysql_service_properties(const wchar_t *bin_path,
wchar_t **args= NULL;
int retval= 1;
BOOL have_inifile;
+ char service_name[MAX_PATH];
props->datadir[0]= 0;
props->inifile[0]= 0;
@@ -148,12 +166,9 @@ int get_mysql_service_properties(const wchar_t *bin_path,
{
/*
There are rare cases where service config does not have
- --defaults-filein the binary parth . There services were registered with
+ --defaults-file in the binary parth . There services were registered with
plain mysqld --install, the data directory is next to "bin" in this case.
- Service name (second parameter) must be MySQL.
*/
- if(wcscmp(args[1], L"MySQL") != 0)
- goto end;
have_inifile= FALSE;
}
else if(numargs == 3)
@@ -165,6 +180,9 @@ int get_mysql_service_properties(const wchar_t *bin_path,
goto end;
}
+ /* Last parameter is the service name*/
+ wcstombs(service_name, args[numargs-1], MAX_PATH);
+
if(have_inifile && wcsncmp(args[1], L"--defaults-file=", 16) != 0)
goto end;
@@ -196,8 +214,8 @@ int get_mysql_service_properties(const wchar_t *bin_path,
normalize_path(props->inifile, MAX_PATH);
if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES)
{
- GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir, MAX_PATH,
- props->inifile);
+ get_datadir_from_ini(props->inifile, service_name, props->datadir,
+ sizeof(props->datadir));
}
else
{
@@ -211,7 +229,7 @@ int get_mysql_service_properties(const wchar_t *bin_path,
}
}
- if(!have_inifile)
+ if(!have_inifile || props->datadir[0] == 0)
{
/*
Hard, although a rare case, we're guessing datadir and defaults-file.
@@ -235,22 +253,25 @@ int get_mysql_service_properties(const wchar_t *bin_path,
*p= 0;
}
- /* Look for my.ini, my.cnf in the install root */
- sprintf_s(props->inifile, MAX_PATH, "%s\\my.ini", install_root);
- if (GetFileAttributes(props->inifile) == INVALID_FILE_ATTRIBUTES)
+ if (!have_inifile)
{
- sprintf_s(props->inifile, MAX_PATH, "%s\\my.cnf", install_root);
- }
- if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES)
- {
- /* Ini file found, get datadir from there */
- GetPrivateProfileString("mysqld", "datadir", NULL, props->datadir,
- MAX_PATH, props->inifile);
- }
- else
- {
- /* No ini file */
- props->inifile[0]= 0;
+ /* Look for my.ini, my.cnf in the install root */
+ sprintf_s(props->inifile, MAX_PATH, "%s\\my.ini", install_root);
+ if (GetFileAttributes(props->inifile) == INVALID_FILE_ATTRIBUTES)
+ {
+ sprintf_s(props->inifile, MAX_PATH, "%s\\my.cnf", install_root);
+ }
+ if (GetFileAttributes(props->inifile) != INVALID_FILE_ATTRIBUTES)
+ {
+ /* Ini file found, get datadir from there */
+ get_datadir_from_ini(props->inifile, service_name, props->datadir,
+ sizeof(props->datadir));
+ }
+ else
+ {
+ /* No ini file */
+ props->inifile[0]= 0;
+ }
}
/* Try datadir in install directory.*/
diff --git a/sql/wsrep_dummy.cc b/sql/wsrep_dummy.cc
index 43cea8bad42..364ef2d3e7a 100644
--- a/sql/wsrep_dummy.cc
+++ b/sql/wsrep_dummy.cc
@@ -141,3 +141,7 @@ void wsrep_unlock_rollback()
void wsrep_set_data_home_dir(const char *)
{ }
+
+void wsrep_log(void (*)(const char *, ...), const char *, ...)
+{
+}
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index d8f82b13108..030c4244a30 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -37,6 +37,8 @@ extern "C" int thd_binlog_format(const MYSQL_THD thd);
void wsrep_cleanup_transaction(THD *thd)
{
if (!WSREP(thd)) return;
+ DBUG_ASSERT(thd->wsrep_conflict_state != MUST_REPLAY &&
+ thd->wsrep_conflict_state != REPLAYING);
if (wsrep_emulate_bin_log) thd_binlog_trx_reset(thd);
thd->wsrep_ws_handle.trx_id= WSREP_UNDEFINED_TRX_ID;
@@ -136,7 +138,11 @@ void wsrep_post_commit(THD* thd, bool all)
/* non-InnoDB statements may have populated events in stmt cache
=> cleanup
*/
- WSREP_DEBUG("cleanup transaction for LOCAL_STATE");
+ if (thd->wsrep_conflict_state != MUST_REPLAY)
+ {
+ WSREP_DEBUG("cleanup transaction for LOCAL_STATE: %s",
+ WSREP_QUERY(thd));
+ }
/*
Run post-rollback hook to clean up in the case if
some keys were populated for the transaction in provider
@@ -145,13 +151,18 @@ void wsrep_post_commit(THD* thd, bool all)
rolls back to savepoint after first operation.
*/
if (all && thd->wsrep_conflict_state != MUST_REPLAY &&
- wsrep && wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
+ thd->wsrep_conflict_state != REPLAYING &&
+ wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
{
WSREP_WARN("post_rollback fail: %llu %d",
(long long)thd->thread_id, thd->get_stmt_da()->status());
}
- wsrep_cleanup_transaction(thd);
- break;
+ if (thd->wsrep_conflict_state != MUST_REPLAY &&
+ thd->wsrep_conflict_state != REPLAYING)
+ {
+ wsrep_cleanup_transaction(thd);
+ }
+ break;
}
default: break;
}
@@ -575,7 +586,8 @@ wsrep_run_wsrep_commit(THD *thd, bool all)
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
/* fall through */
case WSREP_TRX_FAIL:
- WSREP_DEBUG("commit failed for reason: %d", rcode);
+ WSREP_DEBUG("commit failed for reason: %d conf %d",
+ rcode, thd->wsrep_conflict_state);
DBUG_PRINT("wsrep", ("replicating commit fail"));
thd->wsrep_query_state= QUERY_EXEC;
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 0627127c6e0..38f8ca413db 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -233,6 +233,17 @@ static void wsrep_log_cb(wsrep_log_level_t level, const char *msg) {
}
}
+void wsrep_log(void (*fun)(const char *, ...), const char *format, ...)
+{
+ va_list args;
+ char msg[1024];
+ va_start(args, format);
+ vsnprintf(msg, sizeof(msg) - 1, format, args);
+ va_end(args);
+ (fun)("WSREP: %s", msg);
+}
+
+
static void wsrep_log_states (wsrep_log_level_t const level,
const wsrep_uuid_t* const group_uuid,
wsrep_seqno_t const group_seqno,
@@ -599,7 +610,6 @@ int wsrep_init()
{
// enable normal operation in case no provider is specified
wsrep_ready_set(TRUE);
- wsrep_inited= 1;
global_system_variables.wsrep_on = 0;
wsrep_init_args args;
args.logger_cb = wsrep_log_cb;
@@ -610,10 +620,15 @@ int wsrep_init()
{
DBUG_PRINT("wsrep",("wsrep::init() failed: %d", rcode));
WSREP_ERROR("wsrep::init() failed: %d, must shutdown", rcode);
+ wsrep_ready_set(FALSE);
wsrep->free(wsrep);
free(wsrep);
wsrep = NULL;
}
+ else
+ {
+ wsrep_inited= 1;
+ }
return rcode;
}
else
@@ -1555,7 +1570,6 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
case SQLCOM_CREATE_TRIGGER:
- DBUG_ASSERT(!table_list);
DBUG_ASSERT(first_table);
if (find_temporary_table(thd, first_table))
@@ -1564,6 +1578,14 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
}
return true;
+ case SQLCOM_DROP_TRIGGER:
+ DBUG_ASSERT(table_list);
+ if (find_temporary_table(thd, table_list))
+ {
+ return false;
+ }
+ return true;
+
default:
if (table && !find_temporary_table(thd, db, table))
{
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 0f0a65f97b6..1531abe78f8 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -179,13 +179,7 @@ extern void wsrep_prepend_PATH (const char* path);
/* Other global variables */
extern wsrep_seqno_t wsrep_locked_seqno;
-#define WSREP_ON \
- (global_system_variables.wsrep_on)
-
-#define WSREP_ON_NEW \
- ((global_system_variables.wsrep_on) && \
- wsrep_provider && \
- strcmp(wsrep_provider, WSREP_NONE))
+#define WSREP_ON unlikely(global_system_variables.wsrep_on)
#define WSREP(thd) \
(WSREP_ON && thd->variables.wsrep_on)
@@ -201,13 +195,8 @@ extern wsrep_seqno_t wsrep_locked_seqno;
? wsrep_forced_binlog_format : (ulong)(my_format))
// prefix all messages with "WSREP"
-#define WSREP_LOG(fun, ...) \
- do { \
- char msg[1024] = {'\0'}; \
- snprintf(msg, sizeof(msg) - 1, ## __VA_ARGS__); \
- fun("WSREP: %s", msg); \
- } while(0)
-
+void wsrep_log(void (*fun)(const char *, ...), const char *format, ...);
+#define WSREP_LOG(fun, ...) wsrep_log(fun, ## __VA_ARGS__)
#define WSREP_LOG_CONFLICT_THD(thd, role) \
WSREP_LOG(sql_print_information, \
"%s: \n " \
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index af4e02b9e55..c9a88cc30c8 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -1667,24 +1667,65 @@ static int sst_donate_other (const char* method,
return arg.err;
}
+/* return true if character can be a part of a filename */
+static bool filename_char(int const c)
+{
+ return isalnum(c) || (c == '-') || (c == '_') || (c == '.');
+}
+
+/* return true if character can be a part of an address string */
+static bool address_char(int const c)
+{
+ return filename_char(c) ||
+ (c == ':') || (c == '[') || (c == ']') || (c == '/');
+}
+
+static bool check_request_str(const char* const str,
+ bool (*check) (int c))
+{
+ for (size_t i(0); str[i] != '\0'; ++i)
+ {
+ if (!check(str[i]))
+ {
+ WSREP_WARN("Illegal character in state transfer request: %i (%c).",
+ str[i], str[i]);
+ return true;
+ }
+ }
+
+ return false;
+}
+
wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx,
const void* msg, size_t msg_len,
const wsrep_gtid_t* current_gtid,
const char* state, size_t state_len,
bool bypass)
{
- /* This will be reset when sync callback is called.
- * Should we set wsrep_ready to FALSE here too? */
-
- wsrep_config_state.set(WSREP_MEMBER_DONOR);
-
const char* method = (char*)msg;
size_t method_len = strlen (method);
+
+ if (check_request_str(method, filename_char))
+ {
+ WSREP_ERROR("Bad SST method name. SST canceled.");
+ return WSREP_CB_FAILURE;
+ }
+
const char* data = method + method_len + 1;
+ if (check_request_str(data, address_char))
+ {
+ WSREP_ERROR("Bad SST address string. SST canceled.");
+ return WSREP_CB_FAILURE;
+ }
+
char uuid_str[37];
wsrep_uuid_print (&current_gtid->uuid, uuid_str, sizeof(uuid_str));
+ /* This will be reset when sync callback is called.
+ * Should we set wsrep_ready to FALSE here too? */
+ wsrep_config_state.set(WSREP_MEMBER_DONOR);
+
wsp::env env(NULL);
if (env.error())
{
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index fad9e3f70c8..d37af157783 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -90,10 +90,10 @@ void wsrep_client_rollback(THD *thd)
#define NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR 1
#define NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER 2
-static rpl_group_info* wsrep_relay_group_init(const char* log_fname)
+static rpl_group_info* wsrep_relay_group_init(THD *thd, const char* log_fname)
{
Relay_log_info* rli= new Relay_log_info(false);
-
+ WSREP_DEBUG("wsrep_relay_group_init %s", log_fname);
rli->no_storage= true;
if (!rli->relay_log.description_event_for_exec)
{
@@ -123,7 +123,7 @@ static rpl_group_info* wsrep_relay_group_init(const char* log_fname)
rli->mi = new Master_info(&connection_name, false);
struct rpl_group_info *rgi= new rpl_group_info(rli);
- rgi->thd= rli->sql_driver_thd= current_thd;
+ rgi->thd= rli->sql_driver_thd= thd;
if ((rgi->deferred_events_collecting= rli->mi->rpl_filter->is_on()))
{
@@ -148,7 +148,7 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow)
else
thd->variables.option_bits&= ~(OPTION_BIN_LOG);
- if (!thd->wsrep_rgi) thd->wsrep_rgi= wsrep_relay_group_init("wsrep_relay");
+ if (!thd->wsrep_rgi) thd->wsrep_rgi= wsrep_relay_group_init(thd, "wsrep_relay");
/* thd->system_thread_info.rpl_sql_info isn't initialized. */
thd->system_thread_info.rpl_sql_info=
@@ -189,6 +189,109 @@ static void wsrep_return_from_bf_mode(THD *thd, struct wsrep_thd_shadow* shadow)
thd->set_row_count_func(shadow->row_count_func);
}
+void wsrep_replay_sp_transaction(THD* thd)
+{
+ DBUG_ENTER("wsrep_replay_sp_transaction");
+ mysql_mutex_assert_owner(&thd->LOCK_thd_data);
+ DBUG_ASSERT(thd->wsrep_conflict_state == MUST_REPLAY);
+ DBUG_ASSERT(wsrep_thd_trx_seqno(thd) > 0);
+
+ WSREP_DEBUG("replaying SP transaction %llu", thd->thread_id);
+ close_thread_tables(thd);
+ if (thd->locked_tables_mode && thd->lock)
+ {
+ WSREP_DEBUG("releasing table lock for replaying (%u)",
+ thd->thread_id);
+ thd->locked_tables_list.unlock_locked_tables(thd);
+ thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
+ }
+ thd->mdl_context.release_transactional_locks();
+
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
+ THD *replay_thd= new THD(true);
+ replay_thd->thread_stack= thd->thread_stack;
+
+ struct wsrep_thd_shadow shadow;
+ wsrep_prepare_bf_thd(replay_thd, &shadow);
+ WSREP_DEBUG("replaying set for %p rgi %p", replay_thd, replay_thd->wsrep_rgi); replay_thd->wsrep_trx_meta= thd->wsrep_trx_meta;
+ replay_thd->wsrep_ws_handle= thd->wsrep_ws_handle;
+ replay_thd->wsrep_ws_handle.trx_id= WSREP_UNDEFINED_TRX_ID;
+ replay_thd->wsrep_conflict_state= REPLAYING;
+
+ replay_thd->variables.option_bits|= OPTION_BEGIN;
+ replay_thd->server_status|= SERVER_STATUS_IN_TRANS;
+
+ thd->reset_globals();
+ replay_thd->store_globals();
+ wsrep_status_t rcode= wsrep->replay_trx(wsrep,
+ &replay_thd->wsrep_ws_handle,
+ (void*) replay_thd);
+
+ wsrep_return_from_bf_mode(replay_thd, &shadow);
+ replay_thd->reset_globals();
+ delete replay_thd;
+
+ mysql_mutex_lock(&thd->LOCK_thd_data);
+
+ thd->store_globals();
+
+ switch (rcode)
+ {
+ case WSREP_OK:
+ {
+ thd->wsrep_conflict_state= NO_CONFLICT;
+ thd->killed= NOT_KILLED;
+ wsrep_status_t rcode= wsrep->post_commit(wsrep, &thd->wsrep_ws_handle);
+ if (rcode != WSREP_OK)
+ {
+ WSREP_WARN("Post commit failed for SP replay: thd: %u error: %d",
+ thd->thread_id, rcode);
+ }
+ /* As replaying the transaction was successful, an error must not
+ be returned to client, so we need to reset the error state of
+ the diagnostics area */
+ thd->get_stmt_da()->reset_diagnostics_area();
+ break;
+ }
+ case WSREP_TRX_FAIL:
+ {
+ thd->wsrep_conflict_state= ABORTED;
+ wsrep_status_t rcode= wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle);
+ if (rcode != WSREP_OK)
+ {
+ WSREP_WARN("Post rollback failed for SP replay: thd: %u error: %d",
+ thd->thread_id, rcode);
+ }
+ if (thd->get_stmt_da()->is_set())
+ {
+ thd->get_stmt_da()->reset_diagnostics_area();
+ }
+ my_error(ER_LOCK_DEADLOCK, MYF(0));
+ break;
+ }
+ default:
+ WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s",
+ rcode,
+ (thd->db ? thd->db : "(null)"),
+ WSREP_QUERY(thd));
+ /* we're now in inconsistent state, must abort */
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
+ unireg_abort(1);
+ break;
+ }
+
+ wsrep_cleanup_transaction(thd);
+
+ mysql_mutex_lock(&LOCK_wsrep_replaying);
+ wsrep_replaying--;
+ WSREP_DEBUG("replaying decreased: %d, thd: %u",
+ wsrep_replaying, thd->thread_id);
+ mysql_cond_broadcast(&COND_wsrep_replaying);
+ mysql_mutex_unlock(&LOCK_wsrep_replaying);
+
+ DBUG_VOID_RETURN;
+}
+
void wsrep_replay_transaction(THD *thd)
{
DBUG_ENTER("wsrep_replay_transaction");
diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h
index 6ce14a4eb0e..8e82a0fbe21 100644
--- a/sql/wsrep_thd.h
+++ b/sql/wsrep_thd.h
@@ -25,6 +25,7 @@
int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff,
enum enum_var_type scope);
void wsrep_client_rollback(THD *thd);
+void wsrep_replay_sp_transaction(THD* thd);
void wsrep_replay_transaction(THD *thd);
void wsrep_create_appliers(long threads);
void wsrep_create_rollbacker();
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 7b2fbfa0f0e..8e1a7200ab3 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3,7 +3,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1433,17 +1433,23 @@ fail_err:
}
ulint max_size = page_get_max_insert_size_after_reorganize(page, 1);
+ if (max_size < rec_size) {
+ goto fail;
+ }
+
+ const ulint n_recs = page_get_n_recs(page);
+ if (UNIV_UNLIKELY(n_recs >= 8189)) {
+ ut_ad(srv_page_size == 65536);
+ goto fail;
+ }
if (page_has_garbage(page)) {
- if ((max_size < rec_size
- || max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT)
- && page_get_n_recs(page) > 1
+ if (max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
+ && n_recs > 1
&& page_get_max_insert_size(page, 1) < rec_size) {
goto fail;
}
- } else if (max_size < rec_size) {
- goto fail;
}
/* If there have been many consecutive inserts to the
diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc
index 070f6a9cc0a..f679f22dfe4 100644
--- a/storage/innobase/btr/btr0defragment.cc
+++ b/storage/innobase/btr/btr0defragment.cc
@@ -38,6 +38,9 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com
#include <list>
+using std::list;
+using std::min;
+
/* When there's no work, either because defragment is disabled, or because no
query is submitted, thread checks state every BTR_DEFRAGMENT_SLEEP_IN_USECS.*/
#define BTR_DEFRAGMENT_SLEEP_IN_USECS 1000000
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 136d46b7027..0fa569e0254 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -4931,9 +4931,8 @@ buf_page_io_complete(buf_page_t* bpage, bool evict)
err = buf_page_check_corrupt(bpage, space);
-database_corrupted:
-
if (err != DB_SUCCESS) {
+database_corrupted:
/* Not a real corruption if it was triggered by
error injection */
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
@@ -4948,6 +4947,11 @@ database_corrupted:
goto page_not_corrupt;
);
+ if (uncompressed && bpage->zip.data) {
+ memset(reinterpret_cast<buf_block_t*>(bpage)
+ ->frame, 0, srv_page_size);
+ }
+
if (err == DB_PAGE_CORRUPTED) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Database page corruption on disk"
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 36054dbf9fe..8afed48b8c1 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -554,12 +554,18 @@ buf_dblwr_process()
continue;
}
- if (!fil_check_adress_in_tablespace(space_id, page_no)) {
+ if (!space()->size) {
+ fil_space_get_size(space_id);
+ }
+
+ if (UNIV_UNLIKELY(space()->size <= page_no)) {
ib_logf(IB_LOG_LEVEL_WARN,
- "A copy of page " ULINTPF ":" ULINTPF
+ "A copy of page " ULINTPF
" in the doublewrite buffer slot " ULINTPF
- " is not within space bounds",
- space_id, page_no, page_no_dblwr);
+ " is beyond the end of the tablespace "
+ " %s (" ULINTPF " pages)",
+ page_no, page_no_dblwr,
+ space()->name, space()->size);
continue;
}
@@ -963,6 +969,7 @@ try_again:
ib_int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
}
@@ -1096,6 +1103,7 @@ try_again:
checkpoint. */
ib_int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc
index eabc554036a..a45a37a4b3c 100644
--- a/storage/innobase/buf/buf0dump.cc
+++ b/storage/innobase/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -176,7 +176,7 @@ get_buf_dump_dir()
/* The dump file should be created in the default data directory if
innodb_data_home_dir is set as an empty string. */
- if (strcmp(srv_data_home, "") == 0) {
+ if (!*srv_data_home) {
dump_dir = fil_path_to_mysql_datadir;
} else {
dump_dir = srv_data_home;
@@ -207,9 +207,11 @@ buf_dump(
ulint i;
int ret;
+ mysql_mutex_lock(&LOCK_global_system_variables);
ut_snprintf(full_filename, sizeof(full_filename),
"%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR,
srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
ut_snprintf(tmp_filename, sizeof(tmp_filename),
"%s.incomplete", full_filename);
@@ -513,9 +515,11 @@ buf_load()
/* Ignore any leftovers from before */
buf_load_abort_flag = FALSE;
+ mysql_mutex_lock(&LOCK_global_system_variables);
ut_snprintf(full_filename, sizeof(full_filename),
"%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR,
srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
buf_load_status(STATUS_NOTICE,
"Loading buffer pool(s) from %s", full_filename);
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index 1325a938dd6..9df58e760e6 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@@ -1241,8 +1241,11 @@ buf_flush_try_neighbors(
/* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */
#endif
- if (high > fil_space_get_size(space)) {
- high = fil_space_get_size(space);
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ high = s->max_page_number_for_io(high);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
ulint count = 0;
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 29fe81dc920..28f1a41f9bf 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -981,7 +981,7 @@ buf_LRU_check_size_of_non_data_objects(
+ UT_LIST_GET_LEN(buf_pool->LRU))
< buf_pool->curr_size / 3) {
- if (!buf_lru_switched_on_innodb_mon) {
+ if (!buf_lru_switched_on_innodb_mon && srv_monitor_event) {
/* Over 67 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index 3b4d21f7507..a22b1523608 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -292,19 +292,22 @@ buf_read_ahead_random(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ /* Remember the tablespace version along with the
+ tablespace size: if DISCARD + IMPORT changes the
+ actual .ibd file meanwhile, we do not try to read
+ outside the bounds of the tablespace! */
+ tablespace_version = s->tablespace_version;
- tablespace_version = fil_space_get_version(space);
-
- low = (offset / buf_read_ahead_random_area)
- * buf_read_ahead_random_area;
- high = (offset / buf_read_ahead_random_area + 1)
- * buf_read_ahead_random_area;
- if (high > fil_space_get_size(space)) {
+ low = (offset / buf_read_ahead_random_area)
+ * buf_read_ahead_random_area;
+ high = (offset / buf_read_ahead_random_area + 1)
+ * buf_read_ahead_random_area;
+ high = s->max_page_number_for_io(high);
- high = fil_space_get_size(space);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
buf_pool_mutex_enter(buf_pool);
@@ -435,22 +438,16 @@ buf_read_page(
ulint zip_size,
ulint offset)
{
- ib_int64_t tablespace_version;
- ulint count;
dberr_t err = DB_SUCCESS;
- tablespace_version = fil_space_get_version(space_id);
-
FilSpace space(space_id, true);
if (space()) {
-
- /* We do the i/o in the synchronous aio mode to save thread
- switches: hence TRUE */
- count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space_id,
- zip_size, FALSE,
- tablespace_version, offset);
-
+ ulint count = buf_read_page_low(&err, /*sync=*/true,
+ BUF_READ_ANY_PAGE,
+ space_id, zip_size, FALSE,
+ space()->tablespace_version,
+ offset);
srv_stats.buf_pool_reads.add(count);
}
@@ -619,21 +616,30 @@ buf_read_ahead_linear(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
+ uint32_t space_high_limit = 0;
- tablespace_version = fil_space_get_version(space);
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ /* Remember the tablespace version along with the
+ tablespace size: if DISCARD + IMPORT changes the
+ actual .ibd file meanwhile, we do not try to read
+ outside the bounds of the tablespace! */
+ tablespace_version = s->tablespace_version;
- buf_pool_mutex_enter(buf_pool);
+ space_high_limit = s->max_page_number_for_io(ULINT_UNDEFINED);
- if (high > fil_space_get_size(space)) {
- buf_pool_mutex_exit(buf_pool);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
+ }
+
+ if (high > space_high_limit) {
/* The area is not whole, return */
return(0);
}
+ buf_pool_mutex_enter(buf_pool);
+
if (buf_pool->n_pend_reads
> buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
buf_pool_mutex_exit(buf_pool);
@@ -754,7 +760,7 @@ buf_read_ahead_linear(
return(0);
}
- if (high > fil_space_get_size(space)) {
+ if (high > space_high_limit) {
/* The area is not whole, return */
return(0);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 6bd5de85b08..faa804220d3 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -604,7 +604,10 @@ dict_table_close(
mutex_exit(&dict_sys->mutex);
- if (drop_aborted) {
+ /* dict_table_try_drop_aborted() can generate undo logs.
+ So it should be avoided after shutdown of background
+ threads */
+ if (drop_aborted && !srv_undo_sources) {
dict_table_try_drop_aborted(NULL, table_id, 0);
}
}
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index c5f845d14b1..157e695f696 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -415,15 +415,14 @@ dict_mem_table_col_rename_low(
}
}
- dict_index_t* new_index = dict_foreign_find_index(
+ /* New index can be null if InnoDB already dropped
+ the foreign index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->foreign_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
- /* There must be an equivalent index in this case. */
- ut_ad(new_index != NULL);
-
- foreign->foreign_index = new_index;
} else {
@@ -446,7 +445,41 @@ dict_mem_table_col_rename_low(
foreign = *it;
- ut_ad(foreign->referenced_index != NULL);
+ if (!foreign->referenced_index) {
+ /* Referenced index could have been dropped
+ when foreign_key_checks is disabled. In that case,
+ rename the corresponding referenced_col_names and
+ find the equivalent referenced index also */
+ for (unsigned f = 0; f < foreign->n_fields; f++) {
+
+ const char*& rc =
+ foreign->referenced_col_names[f];
+ if (strcmp(rc, from)) {
+ continue;
+ }
+
+ if (to_len <= strlen(rc)) {
+ memcpy(const_cast<char*>(rc), to,
+ to_len + 1);
+ } else {
+ rc = static_cast<char*>(
+ mem_heap_dup(
+ foreign->heap,
+ to, to_len + 1));
+ }
+ }
+
+ /* New index can be null if InnoDB already dropped
+ the referenced index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->referenced_index = dict_foreign_find_index(
+ foreign->referenced_table, NULL,
+ foreign->referenced_col_names,
+ foreign->n_fields, NULL, true, false,
+ NULL, NULL, NULL);
+ return;
+ }
+
for (unsigned f = 0; f < foreign->n_fields; f++) {
/* foreign->referenced_col_names[] need to be
@@ -819,3 +852,22 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set)
return(out);
}
+/** Check whether fulltext index gets affected by foreign
+key constraint. */
+bool dict_foreign_t::affects_fulltext() const
+{
+ if (foreign_table == referenced_table || !foreign_table->fts)
+ return false;
+
+ for (ulint i = 0; i < n_fields; i++)
+ {
+ if (dict_table_is_fts_column(
+ foreign_table->fts->indexes,
+ dict_index_get_nth_col_no(foreign_index, i))
+ != ULINT_UNDEFINED)
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 43a3bd8ff29..fc7ef41786e 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "ha_prototypes.h" // IB_LOG_
#include <my_crypt.h>
-/** Mutex for keys */
-static ib_mutex_t fil_crypt_key_mutex;
-
static bool fil_crypt_threads_inited = false;
-#ifdef UNIV_PFS_MUTEX
-static mysql_pfs_key_t fil_crypt_key_mutex_key;
-#endif
-
/** Is encryption enabled/disabled */
UNIV_INTERN ulong srv_encrypt_tables = 0;
@@ -133,9 +126,6 @@ UNIV_INTERN
void
fil_space_crypt_init()
{
- mutex_create(fil_crypt_key_mutex_key,
- &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK);
-
fil_crypt_throttle_sleep_event = os_event_create();
mutex_create(fil_crypt_stat_mutex_key,
@@ -152,7 +142,6 @@ fil_space_crypt_cleanup()
{
os_event_free(fil_crypt_throttle_sleep_event);
fil_crypt_throttle_sleep_event = NULL;
- mutex_free(&fil_crypt_key_mutex);
mutex_free(&crypt_stat_mutex);
}
@@ -706,47 +695,8 @@ fil_space_encrypt(
fil_space_crypt_t* crypt_data = space->crypt_data;
ut_ad(space->n_pending_ios > 0);
ulint zip_size = fsp_flags_get_zip_size(space->flags);
- byte* tmp = fil_encrypt_buf(crypt_data, space->id, offset, lsn, src_frame, zip_size, dst_frame);
-
-#ifdef UNIV_DEBUG
- if (tmp) {
- /* Verify that encrypted buffer is not corrupted */
- dberr_t err = DB_SUCCESS;
- byte* src = src_frame;
- bool page_compressed_encrypted = (mach_read_from_2(tmp+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
- byte uncomp_mem[UNIV_PAGE_SIZE_MAX];
- byte tmp_mem[UNIV_PAGE_SIZE_MAX];
- ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
-
- if (page_compressed_encrypted) {
- memcpy(uncomp_mem, src, srv_page_size);
- ulint unzipped1 = fil_page_decompress(
- tmp_mem, uncomp_mem);
- ut_ad(unzipped1);
- if (unzipped1 != srv_page_size) {
- src = uncomp_mem;
- }
- }
-
- ut_ad(!buf_page_is_corrupted(true, src, zip_size, space));
- ut_ad(fil_space_decrypt(crypt_data, tmp_mem, size, tmp, &err));
- ut_ad(err == DB_SUCCESS);
-
- /* Need to decompress the page if it was also compressed */
- if (page_compressed_encrypted) {
- byte buf[UNIV_PAGE_SIZE_MAX];
- memcpy(buf, tmp_mem, srv_page_size);
- ulint unzipped2 = fil_page_decompress(tmp_mem, buf);
- ut_ad(unzipped2);
- }
-
- memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8);
- ut_ad(!memcmp(src, tmp_mem, size));
- }
-#endif /* UNIV_DEBUG */
-
- return tmp;
+ return fil_encrypt_buf(crypt_data, space->id, offset, lsn,
+ src_frame, zip_size, dst_frame);
}
/******************************************************************
@@ -1490,6 +1440,109 @@ fil_crypt_return_iops(
fil_crypt_update_total_stat(state);
}
+/** Remove space from key rotation list if there are no pending operations. */
+static void fil_space_remove_from_keyrotation(fil_space_t *space)
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ if (space->n_pending_ops == 0 && space->is_in_rotation_list)
+ {
+ space->is_in_rotation_list= false;
+ ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
+ UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
+ }
+}
+
+/** Return the next tablespace from key rotation list.
+@param space previous tablespace (NULL to start from the beginning)
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_keyrotate_next(fil_space_t *space)
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0)
+ {
+ if (space)
+ {
+ space->n_pending_ops--;
+ fil_space_remove_from_keyrotation(space);
+ }
+
+ return NULL;
+ }
+
+ if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->rotation_list);
+ /* We can trust that space is not NULL because we
+ checked list length above */
+ }
+ else
+ {
+ space->n_pending_ops--;
+ fil_space_t *old = space;
+ space= UT_LIST_GET_NEXT(rotation_list, space);
+ fil_space_remove_from_keyrotation(old);
+ }
+
+ /* Skip spaces that are being created by fil_ibd_create(),
+ or dropped. Note that rotation_list contains only
+ space->purpose == FIL_TABLESPACE. */
+ while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping()))
+ {
+ fil_space_t *old = space;
+ space= UT_LIST_GET_NEXT(rotation_list, space);
+ fil_space_remove_from_keyrotation(old);
+ }
+
+ if (space)
+ space->n_pending_ops++;
+
+ return space;
+}
+
+/** Return the next tablespace.
+@param space previous tablespace (NULL to start from the beginning)
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_next(fil_space_t *space)
+{
+ mutex_enter(&fil_system->mutex);
+ ut_ad(!space || space->n_pending_ops);
+
+ if (!srv_fil_crypt_rotate_key_age)
+ space= fil_space_keyrotate_next(space);
+ else if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->space_list);
+ /* We can trust that space is not NULL because at least the
+ system tablespace is always present and loaded first. */
+ space->n_pending_ops++;
+ }
+ else
+ {
+ ut_ad(space->n_pending_ops > 0);
+ /* Move on to the next fil_space_t */
+ space->n_pending_ops--;
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ /* Skip abnormal tablespaces or those that are being created by
+ fil_ibd_create(), or being dropped. */
+ while (space &&
+ (UT_LIST_GET_LEN(space->chain) == 0 ||
+ space->is_stopping() || space->purpose != FIL_TABLESPACE))
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ if (space)
+ space->n_pending_ops++;
+ }
+
+ mutex_exit(&fil_system->mutex);
+
+ return space;
+}
+
/***********************************************************************
Search for a space needing rotation
@param[in,out] key_state Key state
@@ -1524,14 +1577,7 @@ fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- /* If key rotation is enabled (default) we iterate all tablespaces.
- If key rotation is not enabled we iterate only the tablespaces
- added to keyrotation list. */
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_space_keyrotate_next(state->space);
- }
+ state->space = fil_space_next(state->space);
while (!state->should_shutdown() && state->space) {
fil_crypt_read_crypt_data(state->space);
@@ -1544,14 +1590,15 @@ fil_crypt_find_space_to_rotate(
return true;
}
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_space_keyrotate_next(state->space);
- }
+ state->space = fil_space_next(state->space);
+ }
+
+ if (state->space) {
+ fil_space_release(state->space);
+ state->space = NULL;
}
- /* if we didn't find any space return iops */
+ /* no work to do; release our allocation of I/O capacity */
fil_crypt_return_iops(state);
return false;
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 7234a6c4102..e3ba8dc7dac 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -676,7 +676,7 @@ fil_node_open_file(
#ifdef UNIV_HOTBACKUP
add_size:
#endif /* UNIV_HOTBACKUP */
- space->size += node->size;
+ space->committed_size = space->size += node->size;
}
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(space->flags);
@@ -1151,6 +1151,9 @@ retry:
ut_a(success);
/* InnoDB data files cannot shrink. */
ut_a(space->size >= size);
+ if (size > space->committed_size) {
+ space->committed_size = size;
+ }
/* There could be multiple concurrent I/O requests for
this tablespace (multiple threads trying to extend
@@ -1775,25 +1778,6 @@ fil_space_get_zip_size(
return(flags);
}
-/*******************************************************************//**
-Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache.
-@return TRUE if the address is meaningful */
-UNIV_INTERN
-ibool
-fil_check_adress_in_tablespace(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint page_no)/*!< in: page number */
-{
- if (fil_space_get_size(id) > page_no) {
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
@@ -6492,137 +6476,3 @@ fil_space_release_for_io(fil_space_t* space)
space->n_pending_ios--;
mutex_exit(&fil_system->mutex);
}
-
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_next(fil_space_t* prev_space)
-{
- fil_space_t* space=prev_space;
-
- mutex_enter(&fil_system->mutex);
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->space_list);
-
- /* We can trust that space is not NULL because at least the
- system tablespace is always present and loaded first. */
- space->n_pending_ops++;
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
- space = UT_LIST_GET_NEXT(space_list, space);
-
- /* Skip spaces that are being created by
- fil_ibd_create(), or dropped, or !tablespace. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping()
- || space->purpose != FIL_TABLESPACE)) {
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
-
-/**
-Remove space from key rotation list if there are no more
-pending operations.
-@param[in] space Tablespace */
-static
-void
-fil_space_remove_from_keyrotation(
- fil_space_t* space)
-{
- ut_ad(mutex_own(&fil_system->mutex));
- ut_ad(space);
-
- if (space->n_pending_ops == 0 && space->is_in_rotation_list) {
- space->is_in_rotation_list = false;
- ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
- UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
- }
-}
-
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_keyrotate_next(
- fil_space_t* prev_space)
-{
- fil_space_t* space = prev_space;
- fil_space_t* old = NULL;
-
- mutex_enter(&fil_system->mutex);
-
- if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
- if (space) {
- ut_ad(space->n_pending_ops > 0);
- space->n_pending_ops--;
- fil_space_remove_from_keyrotation(space);
- }
- mutex_exit(&fil_system->mutex);
- return(NULL);
- }
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->rotation_list);
-
- /* We can trust that space is not NULL because we
- checked list length above */
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
-
- old = space;
- space = UT_LIST_GET_NEXT(rotation_list, space);
-
- fil_space_remove_from_keyrotation(old);
- }
-
- /* Skip spaces that are being created by fil_ibd_create(),
- or dropped. Note that rotation_list contains only
- space->purpose == FIL_TABLESPACE. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping())) {
-
- old = space;
- space = UT_LIST_GET_NEXT(rotation_list, space);
- fil_space_remove_from_keyrotation(old);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index edc1fa913e7..656d1d46a6a 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2018, MariaDB Corporation.
+Copyright (C) 2013, 2020, MariaDB Corporation.
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,24 +243,12 @@ success:
/* Set up the actual payload lenght */
mach_write_to_2(out_buf+FIL_PAGE_DATA, write_size);
-#ifdef UNIV_DEBUG
- /* Verify */
ut_ad(fil_page_is_compressed(out_buf) || fil_page_is_compressed_encrypted(out_buf));
ut_ad(mach_read_from_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM) == BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf+FIL_PAGE_DATA) == write_size);
ut_ad(mach_read_from_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) == (ulint)comp_method ||
mach_read_from_2(out_buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE) == (ulint)comp_method);
- /* Verify that page can be decompressed */
- {
- page_t tmp_buf[UNIV_PAGE_SIZE_MAX];
- page_t page[UNIV_PAGE_SIZE_MAX];
- memcpy(page, out_buf, srv_page_size);
- ut_ad(fil_page_decompress(tmp_buf, page));
- ut_ad(!buf_page_is_corrupted(false, page, 0, NULL));
- }
-#endif /* UNIV_DEBUG */
-
write_size+=header_len;
if (block_size <= 0) {
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 13ac923eb3f..3796ab6d144 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -447,7 +447,7 @@ xdes_get_descriptor_with_space_hdr(
page_t* descr_page;
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
/* Read free limit and space size */
@@ -531,7 +531,7 @@ xdes_lst_get_descriptor(
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
descr = fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr)
- XDES_FLST_NODE;
@@ -687,7 +687,7 @@ fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
ut_ad(mtr);
- mtr_x_lock(fil_space_get_latch(space_id, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space_id, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
block = buf_page_create(space_id, 0, zip_size, mtr);
@@ -814,7 +814,7 @@ fsp_header_inc_size(
ut_ad(mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
header = fsp_get_space_header(space,
fsp_flags_get_zip_size(flags),
@@ -843,7 +843,7 @@ fsp_header_get_tablespace_size(void)
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(0, NULL), &mtr);
header = fsp_get_space_header(0, 0, &mtr);
@@ -1070,7 +1070,6 @@ fsp_fill_free_list(
ulint frag_n_used;
ulint actual_increase;
ulint i;
- mtr_t ibuf_mtr;
ut_ad(page_offset(header) == FSP_HEADER_OFFSET);
@@ -1138,26 +1137,17 @@ fsp_fill_free_list(
MLOG_2BYTES, mtr);
}
- /* Initialize the ibuf bitmap page in a separate
- mini-transaction because it is low in the latching
- order, and we must be able to release its latch
- before returning from the fsp routine */
-
- mtr_start(&ibuf_mtr);
-
block = buf_page_create(space,
- i + FSP_IBUF_BITMAP_OFFSET,
- zip_size, &ibuf_mtr);
+ i + FSP_IBUF_BITMAP_OFFSET,
+ zip_size, mtr);
buf_page_get(space, zip_size,
i + FSP_IBUF_BITMAP_OFFSET,
- RW_X_LATCH, &ibuf_mtr);
+ RW_X_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
- fsp_init_file_page(block, &ibuf_mtr);
+ fsp_init_file_page(block, mtr);
- ibuf_bitmap_page_init(block, &ibuf_mtr);
-
- mtr_commit(&ibuf_mtr);
+ ibuf_bitmap_page_init(block, mtr);
}
descr = xdes_get_descriptor_with_space_hdr(header, space, i,
@@ -2038,7 +2028,7 @@ fseg_create_general(
header = byte_offset + buf_block_get_frame(block);
}
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
if (!has_done_reservation) {
success = fsp_reserve_free_extents(&n_reserved, space, 2,
@@ -2185,7 +2175,7 @@ fseg_n_reserved_pages(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -2608,7 +2598,7 @@ fseg_alloc_free_page_general(
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(seg_header, space, zip_size, mtr);
@@ -2725,7 +2715,7 @@ fsp_reserve_free_extents(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
space_header = fsp_get_space_header(space, zip_size, mtr);
try_again:
@@ -2865,7 +2855,7 @@ fsp_get_available_space_in_free_extents(
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
mutex_exit(&dict_sys->mutex);
@@ -3155,7 +3145,7 @@ fseg_free_page(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
@@ -3189,7 +3179,7 @@ fseg_page_is_free(
zip_size = dict_tf_get_zip_size(flags);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode = fseg_inode_get(seg_header, space, zip_size, &mtr);
@@ -3314,7 +3304,7 @@ fseg_free_step(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
@@ -3395,7 +3385,7 @@ fseg_free_step_not_header(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3515,7 +3505,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3538,7 +3528,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3564,7 +3554,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3602,7 +3592,7 @@ fseg_validate(
space = page_get_space_id(page_align(header));
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3678,7 +3668,7 @@ fseg_print(
space = page_get_space_id(page_align(header));
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3727,10 +3717,10 @@ fsp_validate(
/* Start first a mini-transaction mtr2 to lock out all other threads
from the fsp system */
mtr_start(&mtr2);
- mtr_x_lock(latch, &mtr2);
+ mtr_x_space_lock(latch, &mtr2);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3757,7 +3747,7 @@ fsp_validate(
/* Validate FSP_FREE list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FREE, &mtr);
@@ -3766,7 +3756,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3781,7 +3771,7 @@ fsp_validate(
/* Validate FSP_FREE_FRAG list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr);
@@ -3790,7 +3780,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3808,7 +3798,7 @@ fsp_validate(
/* Validate FSP_FULL_FRAG list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr);
@@ -3817,7 +3807,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3832,7 +3822,7 @@ fsp_validate(
/* Validate segments */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3847,7 +3837,7 @@ fsp_validate(
n = 0;
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -3876,7 +3866,7 @@ fsp_validate(
}
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3892,7 +3882,7 @@ fsp_validate(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -3976,11 +3966,11 @@ fsp_print(
mtr_start(&mtr2);
- mtr_x_lock(latch, &mtr2);
+ mtr_x_space_lock(latch, &mtr2);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4012,7 +4002,7 @@ fsp_print(
/* Print segments */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4027,7 +4017,7 @@ fsp_print(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4049,7 +4039,7 @@ fsp_print(
}
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4064,7 +4054,7 @@ fsp_print(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4121,7 +4111,8 @@ fsp_page_is_free_func(
ut_ad(mtr);
- mtr_x_lock_func(fil_space_get_latch(space, &flags), file, line, mtr);
+ mtr_x_space_lock_func(fil_space_get_latch(space, &flags), file, line,
+ mtr);
ulint zip_size = fsp_flags_get_zip_size(flags);
xdes_t* descr = xdes_get_descriptor(space, zip_size, page_no, mtr);
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 6dbe5e0e2a0..2a1341c4cf0 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -443,9 +443,9 @@ fts_read_stopword(
/******************************************************************//**
Load user defined stopword from designated user table
-@return TRUE if load operation is successful */
+@return whether the operation is successful */
static
-ibool
+bool
fts_load_user_stopword(
/*===================*/
fts_t* fts, /*!< in: FTS struct */
@@ -453,27 +453,26 @@ fts_load_user_stopword(
name */
fts_stopword_t* stopword_info) /*!< in: Stopword info */
{
- pars_info_t* info;
- que_t* graph;
- dberr_t error = DB_SUCCESS;
- ibool ret = TRUE;
- trx_t* trx;
- ibool has_lock = fts->dict_locked;
-
- trx = trx_allocate_for_background();
- trx->op_info = "Load user stopword table into FTS cache";
-
- if (!has_lock) {
+ if (!fts->dict_locked) {
mutex_enter(&dict_sys->mutex);
}
- /* Validate the user table existence and in the right
- format */
+ /* Validate the user table existence in the right format */
+ bool ret= false;
stopword_info->charset = fts_valid_stopword_table(stopword_table_name);
if (!stopword_info->charset) {
- ret = FALSE;
- goto cleanup;
- } else if (!stopword_info->cached_stopword) {
+cleanup:
+ if (!fts->dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
+
+ return ret;
+ }
+
+ trx_t* trx = trx_allocate_for_background();
+ trx->op_info = "Load user stopword table into FTS cache";
+
+ if (!stopword_info->cached_stopword) {
/* Create the stopword RB tree with the stopword column
charset. All comparison will use this charset */
stopword_info->cached_stopword = rbt_create_arg_cmp(
@@ -482,14 +481,14 @@ fts_load_user_stopword(
}
- info = pars_info_create();
+ pars_info_t* info = pars_info_create();
pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name);
pars_info_bind_function(info, "my_func", fts_read_stopword,
stopword_info);
- graph = fts_parse_sql_no_dict_lock(
+ que_t* graph = fts_parse_sql_no_dict_lock(
NULL,
info,
"DECLARE FUNCTION my_func;\n"
@@ -508,14 +507,13 @@ fts_load_user_stopword(
"CLOSE c;");
for (;;) {
- error = fts_eval_sql(trx, graph);
+ dberr_t error = fts_eval_sql(trx, graph);
if (error == DB_SUCCESS) {
fts_sql_commit(trx);
stopword_info->status = STOPWORD_USER_TABLE;
break;
} else {
-
fts_sql_rollback(trx);
ut_print_timestamp(stderr);
@@ -537,14 +535,9 @@ fts_load_user_stopword(
}
que_graph_free(graph);
-
-cleanup:
- if (!has_lock) {
- mutex_exit(&dict_sys->mutex);
- }
-
trx_free_for_background(trx);
- return(ret);
+ ret = true;
+ goto cleanup;
}
/******************************************************************//**
@@ -1134,14 +1127,14 @@ fts_cache_clear(
index_cache->doc_stats = NULL;
}
- mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
- cache->sync_heap->arg = NULL;
-
cache->total_size = 0;
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = NULL;
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
+
+ mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
+ cache->sync_heap->arg = NULL;
}
/*********************************************************************//**
@@ -3495,8 +3488,8 @@ fts_add_doc_by_id(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL,
- NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL,
+ NULL, true, true);
}
fts_cache_add_doc(
@@ -7244,21 +7237,19 @@ This function loads the stopword into the FTS cache. It also
records/fetches stopword configuration to/from FTS configure
table, depending on whether we are creating or reloading the
FTS.
-@return TRUE if load operation is successful */
+@return true if load operation is successful */
UNIV_INTERN
-ibool
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transactions */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload) /*!< in: Whether it is
+ bool reload) /*!< in: Whether it is
for reloading FTS table */
{
fts_table_t fts_table;
@@ -7274,9 +7265,8 @@ fts_load_stopword(
cache = table->fts->cache;
- if (!reload && !(cache->stopword_info.status
- & STOPWORD_NOT_INIT)) {
- return(TRUE);
+ if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) {
+ return true;
}
if (!trx) {
@@ -7321,12 +7311,11 @@ fts_load_stopword(
goto cleanup;
}
- if (strlen((char*) str.f_str) > 0) {
+ if (*str.f_str) {
stopword_to_use = (const char*) str.f_str;
}
} else {
- stopword_to_use = (session_stopword_table)
- ? session_stopword_table : global_stopword_table;
+ stopword_to_use = session_stopword_table;
}
if (stopword_to_use
@@ -7363,7 +7352,7 @@ cleanup:
sizeof(fts_tokenizer_word_t), fts_utf8_string_cmp);
}
- return(error == DB_SUCCESS);
+ return error == DB_SUCCESS;
}
/**********************************************************************//**
@@ -7569,7 +7558,7 @@ fts_init_index(
} else {
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL, NULL, true, true);
}
for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) {
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index ce6151e63b8..f1a5b4ccbe4 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -146,6 +146,8 @@ struct fts_query_t {
fts_word_freq_t */
bool multi_exist; /*!< multiple FTS_EXIST oper */
+ byte visiting_sub_exp; /*!< count of nested
+ fts_ast_visit_sub_exp() */
};
/** For phrase matching, first we collect the documents and the positions
@@ -2836,6 +2838,8 @@ fts_query_get_token(
return(new_ptr);
}
+static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*);
+
/*****************************************************************//**
Visit every node of the AST. */
static
@@ -2925,7 +2929,7 @@ Process (nested) sub-expression, create a new result set to store the
sub-expression result by processing nodes under current sub-expression
list. Merge the sub-expression result with that of parent expression list.
@return DB_SUCCESS if all well */
-UNIV_INTERN
+static
dberr_t
fts_ast_visit_sub_exp(
/*==================*/
@@ -2945,6 +2949,14 @@ fts_ast_visit_sub_exp(
ut_a(node->type == FTS_AST_SUBEXP_LIST);
+ /* To avoid stack overflow, we limit the mutual recursion
+ depth between fts_ast_visit(), fts_query_visitor() and
+ fts_ast_visit_sub_exp(). */
+ if (query->visiting_sub_exp++ > 31) {
+ query->error = DB_OUT_OF_MEMORY;
+ DBUG_RETURN(query->error);
+ }
+
cur_oper = query->oper;
/* Save current result set */
@@ -2967,6 +2979,7 @@ fts_ast_visit_sub_exp(
/* Reinstate parent node state */
query->multi_exist = multi_exist;
query->oper = cur_oper;
+ query->visiting_sub_exp--;
/* Merge the sub-expression result with the parent result set. */
subexpr_doc_ids = query->doc_ids;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 4de2cdbeaec..8960f42b4a3 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1,10 +1,10 @@
/*****************************************************************************
-Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2000, 2020, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1671,8 +1671,7 @@ innobase_srv_conc_enter_innodb(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1710,8 +1709,7 @@ innobase_srv_conc_exit_innodb(
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
#endif /* UNIV_SYNC_DEBUG */
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
@@ -2638,6 +2636,9 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
+#ifdef WITH_WSREP
+ trx->wsrep = wsrep_on(thd);
+#endif
DBUG_VOID_RETURN;
}
@@ -4185,20 +4186,9 @@ innobase_commit_low(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0;
- if (thd && wsrep_on(thd)) {
-#ifdef WSREP_PROC_INFO
- char info[64];
- info[sizeof(info) - 1] = '\0';
- snprintf(info, sizeof(info) - 1,
- "innobase_commit_low():trx_commit_for_mysql(%lld)",
- (long long) wsrep_thd_trx_seqno(thd));
- tmp = thd_proc_info(thd, info);
-
-#else
- tmp = thd_proc_info(thd, "innobase_commit_low()");
-#endif /* WSREP_PROC_INFO */
+ if (trx->is_wsrep()) {
+ tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
}
#endif /* WITH_WSREP */
if (trx_is_started(trx)) {
@@ -4206,7 +4196,7 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
#ifdef WITH_WSREP
- if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); }
+ if (trx->is_wsrep()) { thd_proc_info(trx->mysql_thd, tmp); }
#endif /* WITH_WSREP */
}
@@ -8151,19 +8141,19 @@ ha_innobase::write_row(
sql_command = thd_sql_command(user_thd);
- if ((sql_command == SQLCOM_ALTER_TABLE
- || sql_command == SQLCOM_OPTIMIZE
- || sql_command == SQLCOM_CREATE_INDEX
+ if (num_write_row >= 10000
+ && (sql_command == SQLCOM_ALTER_TABLE
+ || sql_command == SQLCOM_OPTIMIZE
+ || sql_command == SQLCOM_CREATE_INDEX
#ifdef WITH_WSREP
- || (wsrep_on(user_thd) && wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
- !thd_test_options(
- user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ || (sql_command == SQLCOM_LOAD &&
+ trx->is_wsrep() && wsrep_load_data_splitting &&
+ !thd_test_options(
+ user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
#endif /* WITH_WSREP */
- || sql_command == SQLCOM_DROP_INDEX)
- && num_write_row >= 10000) {
+ || sql_command == SQLCOM_DROP_INDEX)) {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) && sql_command == SQLCOM_LOAD) {
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep()) {
WSREP_DEBUG("forced trx split for LOAD: %s",
wsrep_thd_query(user_thd));
}
@@ -8202,9 +8192,8 @@ no_commit:
;
} else if (src_table == prebuilt->table) {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep() &&
+ wsrep_load_data_splitting &&
!thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
@@ -8234,9 +8223,8 @@ no_commit:
prebuilt->sql_stat_start = TRUE;
} else {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep() &&
+ wsrep_load_data_splitting &&
!thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
@@ -8377,21 +8365,19 @@ no_commit:
prebuilt->autoinc_offset,
prebuilt->autoinc_increment);
- if (wsrep_on(current_thd) &&
+ if (trx->is_wsrep() &&
auto_inc_inserted &&
wsrep_drupal_282555_workaround &&
- wsrep_thd_retry_counter(current_thd) == 0 &&
- !thd_test_options(current_thd,
+ wsrep_thd_retry_counter(user_thd) == 0 &&
+ !thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
WSREP_DEBUG(
"retrying insert: %s",
- (*wsrep_thd_query(current_thd)) ?
- wsrep_thd_query(current_thd) :
- (char *)"void");
+ wsrep_thd_query(user_thd));
error= DB_SUCCESS;
wsrep_thd_set_conflict_state(
- current_thd, MUST_ABORT);
+ user_thd, MUST_ABORT);
innobase_srv_conc_exit_innodb(prebuilt->trx);
/* jump straight to func exit over
* later wsrep hooks */
@@ -8429,7 +8415,7 @@ set_max_autoinc:
prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
- if (wsrep_on(user_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == REPL_RECV)
{
wsrep_thd_auto_increment_variables(
@@ -8478,8 +8464,7 @@ report_error:
user_thd);
#ifdef WITH_WSREP
- if (!error_result
- && wsrep_on(user_thd)
+ if (!error_result && trx->is_wsrep()
&& wsrep_thd_exec_mode(user_thd) == LOCAL_STATE
&& !wsrep_consistency_check(user_thd)
&& !wsrep_thd_ignore_table(user_thd)) {
@@ -8487,10 +8472,9 @@ report_error:
NULL)) {
DBUG_PRINT("wsrep", ("row key failed"));
error_result = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ goto func_exit;
}
}
-wsrep_error:
#endif /* WITH_WSREP */
if (error_result == HA_FTS_INVALID_DOCID) {
@@ -8973,7 +8957,7 @@ ha_innobase::update_row(
prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
- if (wsrep_on(user_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == REPL_RECV)
{
wsrep_thd_auto_increment_variables(
@@ -9018,9 +9002,8 @@ func_exit:
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == LOCAL_STATE &&
- wsrep_on(user_thd) &&
!wsrep_thd_ignore_table(user_thd))
{
DBUG_PRINT("wsrep", ("update row key"));
@@ -9029,14 +9012,11 @@ func_exit:
new_row)) {
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
DBUG_PRINT("wsrep", ("row key failed"));
- err = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
-
DBUG_RETURN(err);
}
@@ -9085,19 +9065,16 @@ ha_innobase::delete_row(
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == LOCAL_STATE &&
- wsrep_on(user_thd) &&
!wsrep_thd_ignore_table(user_thd))
{
if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record,
NULL)) {
DBUG_PRINT("wsrep", ("delete fail"));
- error = (dberr_t) HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
DBUG_RETURN(convert_error_code_to_mysql(
error, prebuilt->table->flags, user_thd));
@@ -10370,8 +10347,7 @@ wsrep_append_foreign_key(
int cache_key_len;
bool const copy = true;
- if (!wsrep_on(trx->mysql_thd) ||
- wsrep_thd_exec_mode(thd) != LOCAL_STATE)
+ if (!trx->is_wsrep() || wsrep_thd_exec_mode(thd) != LOCAL_STATE)
return DB_SUCCESS;
if (!thd || !foreign ||
@@ -11523,10 +11499,17 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */
{
- return(fts_load_stopword(table, trx,
- innobase_server_stopword_table,
- THDVAR(thd, ft_user_stopword_table),
- THDVAR(thd, ft_enable_stopword), FALSE));
+ const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
+ if (!stopword_table)
+ {
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ if (innobase_server_stopword_table)
+ stopword_table= thd_strdup(thd, innobase_server_stopword_table);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ }
+
+ return fts_load_stopword(table, trx, stopword_table,
+ THDVAR(thd, ft_enable_stopword), false);
}
/*****************************************************************//**
@@ -14921,12 +14904,11 @@ ha_innobase::external_lock(
THD* thd, /*!< in: handle to the user thread */
int lock_type) /*!< in: lock type */
{
- trx_t* trx;
-
DBUG_ENTER("ha_innobase::external_lock");
DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd);
+ trx_t* trx = prebuilt->trx;
/* Statement based binlogging does not work in isolation level
READ UNCOMMITTED and READ COMMITTED since the necessary
@@ -14940,22 +14922,19 @@ ha_innobase::external_lock(
&& thd_binlog_format(thd) == BINLOG_FORMAT_STMT
&& thd_binlog_filter_ok(thd)
&& thd_sqlcom_can_generate_row_events(thd)) {
- bool skip = 0;
+ bool skip = false;
+#ifdef WITH_WSREP
+ skip = trx->is_wsrep()
+ && wsrep_thd_exec_mode(thd) != LOCAL_STATE;
+#endif /* WITH_WSREP */
/* used by test case */
DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;);
if (!skip) {
-#ifdef WITH_WSREP
- if (!wsrep_on(thd) || wsrep_thd_exec_mode(thd) == LOCAL_STATE)
- {
-#endif /* WITH_WSREP */
my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
" InnoDB is limited to row-logging when "
"transaction isolation level is "
"READ COMMITTED or READ UNCOMMITTED.");
DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
-#ifdef WITH_WSREP
- }
-#endif /* WITH_WSREP */
}
}
@@ -14986,8 +14965,6 @@ ha_innobase::external_lock(
}
- trx = prebuilt->trx;
-
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
@@ -17075,7 +17052,6 @@ innodb_stopword_table_validate(
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
trx_t* trx;
- int ret = 1;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -17088,14 +17064,22 @@ innodb_stopword_table_validate(
/* Validate the stopword table's (if supplied) existence and
of the right format */
- if (!stopword_table_name
- || fts_valid_stopword_table(stopword_table_name)) {
- *static_cast<const char**>(save) = stopword_table_name;
- ret = 0;
- }
+ int ret = stopword_table_name && !fts_valid_stopword_table(
+ stopword_table_name);
row_mysql_unlock_data_dictionary(trx);
+ if (!ret) {
+ if (stopword_table_name == buff) {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ stopword_table_name = thd_strmake(thd,
+ stopword_table_name,
+ len);
+ }
+
+ *static_cast<const char**>(save) = stopword_table_name;
+ }
+
return(ret);
}
@@ -17103,9 +17087,10 @@ innodb_stopword_table_validate(
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
+@param[in,out] thd connection
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
-static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
+static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
char buf[STRING_BUFFER_USUAL_SIZE];
@@ -17119,6 +17104,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
+ if (table_name == buf) {
+ ut_ad(static_cast<size_t>(len)
+ < sizeof buf);
+ table_name = thd_strmake(thd,
+ table_name,
+ len);
+ }
+
+
*static_cast<const char**>(save) = table_name;
return 0;
}
@@ -17817,52 +17811,43 @@ exit:
return;
}
-#ifdef __WIN__
-/*************************************************************//**
-Validate if passed-in "value" is a valid value for
-innodb_buffer_pool_filename. On Windows, file names with colon (:)
-are not allowed.
-
+/** Validate SET GLOBAL innodb_buffer_pool_filename.
+On Windows, file names with colon (:) are not allowed.
+@param thd connection
+@param save &srv_buf_dump_filename
+@param value new value to be validated
@return 0 for valid name */
-static
-int
-innodb_srv_buf_dump_filename_validate(
-/*==================================*/
- THD* thd, /*!< in: thread handle */
- struct st_mysql_sys_var* var, /*!< in: pointer to system
- variable */
- void* save, /*!< out: immediate result
- for update function */
- struct st_mysql_value* value) /*!< in: incoming string */
+static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
+ void *save,
+ st_mysql_value *value)
{
- const char* buf_name;
- char buff[OS_FILE_MAX_PATH];
- int len= sizeof(buff);
+ char buff[OS_FILE_MAX_PATH];
+ int len= sizeof buff;
- ut_a(save != NULL);
- ut_a(value != NULL);
-
- buf_name = value->val_str(value, buff, &len);
-
- if (buf_name) {
- if (is_filename_allowed(buf_name, len, FALSE)){
- *static_cast<const char**>(save) = buf_name;
- return(0);
- } else {
- push_warning_printf(thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_ARGUMENTS,
- "InnoDB: innodb_buffer_pool_filename "
- "cannot have colon (:) in the file name.");
-
- }
- }
+ if (const char *buf_name= value->val_str(value, buff, &len))
+ {
+#ifdef __WIN__
+ if (!is_filename_allowed(buf_name, len, FALSE))
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: innodb_buffer_pool_filename "
+ "cannot have colon (:) in the file name.");
+ return 1;
+ }
+#endif /* __WIN__ */
+ if (buf_name == buff)
+ {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ buf_name= thd_strmake(thd, buf_name, len);
+ }
+
+ *static_cast<const char**>(save)= buf_name;
+ return 0;
+ }
- return(1);
+ return 1;
}
-#else /* __WIN__ */
-# define innodb_srv_buf_dump_filename_validate NULL
-#endif /* __WIN__ */
#ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict;
@@ -17871,10 +17856,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 MY_ATTRIBUTE((warn_unused_result))
-bool
-innodb_buffer_pool_evict_uncompressed(void)
-/*=======================================*/
+static bool innodb_buffer_pool_evict_uncompressed()
{
bool all_evicted = true;
@@ -17895,9 +17877,13 @@ innodb_buffer_pool_evict_uncompressed(void)
if (!buf_LRU_free_page(&block->page, false)) {
all_evicted = false;
+ block = prev_block;
+ } else {
+ /* Because buf_LRU_free_page() may release
+ and reacquire buf_pool_t::mutex, prev_block
+ may be invalid. */
+ block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
}
-
- block = prev_block;
}
buf_pool_mutex_exit(buf_pool);
@@ -18485,11 +18471,14 @@ static
void
innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save)
{
- *static_cast<my_bool*>(var) = *static_cast<const my_bool*>(save);
- mysql_mutex_unlock(&LOCK_global_system_variables);
- /* Wakeup server monitor thread. */
- os_event_set(srv_monitor_event);
- mysql_mutex_lock(&LOCK_global_system_variables);
+ *static_cast<my_bool*>(var)= *static_cast<const my_bool*>(save);
+ if (srv_monitor_event)
+ {
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ /* Wakeup server monitor thread. */
+ os_event_set(srv_monitor_event);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ }
}
/** Update the system variable innodb_encryption_threads.
@@ -19836,7 +19825,7 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug,
srv_sys_space_size_debug,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"InnoDB system tablespace size to be set in recovery.",
- NULL, NULL, 0, 0, UINT_MAX32, 0);
+ NULL, NULL, 0, 0, 256U << 20, 0);
static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug,
srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG,
@@ -19873,7 +19862,7 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy",
innodb_compression_algorithm_validate, NULL,
/* We use here the largest number of supported compression method to
enable all those methods that are available. Availability of compression
@@ -19924,7 +19913,7 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
"scrubbing",
NULL,
innodb_encryption_threads_update,
- srv_n_fil_crypt_threads, 0, UINT_MAX32, 0);
+ 0, 0, 255, 0);
static MYSQL_SYSVAR_UINT(encryption_rotate_key_age,
srv_fil_crypt_rotate_key_age,
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 682f09992a4..e2c7c4421c6 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -3376,6 +3376,12 @@ err_exit:
trx_free_for_mysql(ctx->trx);
trx_commit_for_mysql(ctx->prebuilt->trx);
+ for (uint i = 0; i < ctx->num_to_add_fk; i++) {
+ if (ctx->add_fk[i]) {
+ dict_foreign_free(ctx->add_fk[i]);
+ }
+ }
+
delete ctx;
ha_alter_info->handler_ctx = NULL;
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 2729a755570..145a5708423 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -2557,7 +2557,7 @@ i_s_metrics_fill(
time_diff = 0;
}
- /* Unless MONITOR__NO_AVERAGE is marked, we will need
+ /* Unless MONITOR_NO_AVERAGE is set, we must
to calculate the average value. If this is a monitor set
owner marked by MONITOR_SET_OWNER, divide
the value by another counter (number of calls) designated
@@ -2565,8 +2565,9 @@ i_s_metrics_fill(
Otherwise average the counter value by the time between the
time that the counter is enabled and time it is disabled
or time it is sampled. */
- if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && (monitor_info->monitor_type & MONITOR_SET_OWNER)
+ if ((monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE | MONITOR_SET_OWNER))
+ == MONITOR_SET_OWNER
&& monitor_info->monitor_related_id) {
mon_type_t value_start
= MONITOR_VALUE_SINCE_START(
@@ -2582,18 +2583,18 @@ i_s_metrics_fill(
fields[METRIC_AVG_VALUE_START]->set_null();
}
- if (MONITOR_VALUE(monitor_info->monitor_related_id)) {
- OK(fields[METRIC_AVG_VALUE_RESET]->store(
- MONITOR_VALUE(count)
- / MONITOR_VALUE(
- monitor_info->monitor_related_id),
- FALSE));
+ if (mon_type_t related_value =
+ MONITOR_VALUE(monitor_info->monitor_related_id)) {
+ OK(fields[METRIC_AVG_VALUE_RESET]
+ ->store(MONITOR_VALUE(count)
+ / related_value, false));
+ fields[METRIC_AVG_VALUE_RESET]->set_notnull();
} else {
fields[METRIC_AVG_VALUE_RESET]->set_null();
}
- } else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && !(monitor_info->monitor_type
- & MONITOR_DISPLAY_CURRENT)) {
+ } else if (!(monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE
+ | MONITOR_DISPLAY_CURRENT))) {
if (time_diff) {
OK(fields[METRIC_AVG_VALUE_START]->store(
(double) MONITOR_VALUE_SINCE_START(
@@ -3375,6 +3376,8 @@ no_fts:
conv_str.f_len = sizeof word;
conv_str.f_str = word;
+ rw_lock_s_lock(&cache->lock);
+
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
fts_index_cache_t* index_cache;
@@ -3385,6 +3388,7 @@ no_fts:
index_cache, thd, &conv_str, tables));
}
+ rw_lock_s_unlock(&cache->lock);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
@@ -8288,7 +8292,7 @@ i_s_tablespaces_encryption_fill_table(
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* deny access to user without PROCESS_ACL privilege */
- if (check_global_access(thd, SUPER_ACL)) {
+ if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 74d73379fbb..9427ade1ce4 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -62,6 +62,7 @@ UNIV_INTERN my_bool srv_ibuf_disable_background_merge;
#include "que0que.h"
#include "srv0start.h" /* srv_shutdown_state */
#include "ha_prototypes.h"
+#include "ut0crc32.h"
#include "rem0cmp.h"
/* STRUCTURE OF AN INSERT BUFFER RECORD
@@ -547,7 +548,7 @@ ibuf_init_at_db_start(void)
mutex_enter(&ibuf_mutex);
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
header_page = ibuf_header_page_get(&mtr);
@@ -2097,7 +2098,7 @@ ibuf_add_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
header_page = ibuf_header_page_get(&mtr);
@@ -2181,7 +2182,7 @@ ibuf_remove_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
header_page = ibuf_header_page_get(&mtr);
@@ -2885,42 +2886,28 @@ ibuf_contract_after_insert(
} while (size > 0 && sum_sizes < entry_size);
}
-/*********************************************************************//**
-Determine if an insert buffer record has been encountered already.
-@return TRUE if a new record, FALSE if possible duplicate */
-static
-ibool
-ibuf_get_volume_buffered_hash(
-/*==========================*/
- const rec_t* rec, /*!< in: ibuf record in post-4.1 format */
- const byte* types, /*!< in: fields */
- const byte* data, /*!< in: start of user record data */
- ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT,
- nonzero=ROW_FORMAT=COMPACT */
- ulint* hash, /*!< in/out: hash array */
- ulint size) /*!< in: number of elements in hash array */
+/** Determine if a change buffer record has been encountered already.
+@param rec change buffer record in the MySQL 5.5 format
+@param hash hash table of encountered records
+@param size number of elements in hash
+@retval true if a distinct record
+@retval false if this may be duplicating an earlier record */
+static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash,
+ ulint size)
{
- ulint len;
- ulint fold;
- ulint bitmask;
-
- len = ibuf_rec_get_size(
- rec, types,
- rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp);
- fold = ut_fold_binary(data, len);
-
- hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
- bitmask = static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
-
- if (*hash & bitmask) {
-
- return(FALSE);
- }
-
- /* We have not seen this record yet. Insert it. */
- *hash |= bitmask;
-
- return(TRUE);
+ ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER);
+ const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER);
+ const ulint len= rec_get_data_size_old(rec) - start;
+ const uint32_t fold= ut_crc32(rec + start, len);
+ hash+= (fold / (CHAR_BIT * sizeof *hash)) % size;
+ ulint bitmask= static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
+
+ if (*hash & bitmask)
+ return false;
+
+ /* We have not seen this record yet. Remember it. */
+ *hash|= bitmask;
+ return true;
}
#ifdef UNIV_DEBUG
@@ -3012,11 +2999,7 @@ ibuf_get_volume_buffered_count_func(
case IBUF_OP_DELETE_MARK:
/* There must be a record to delete-mark.
See if this record has been already buffered. */
- if (n_recs && ibuf_get_volume_buffered_hash(
- rec, types + IBUF_REC_INFO_SIZE,
- types + len,
- types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT,
- hash, size)) {
+ if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) {
(*n_recs)++;
}
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index bcb2252e7dc..b6ad0b85b19 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -1504,7 +1504,7 @@ buf_page_encrypt_before_write(
NOTE! The definition appears here only for other modules of this
directory (buf) to see it. Do not use from outside! */
-typedef struct {
+struct buf_tmp_buffer_t {
private:
int32 reserved; /*!< true if this slot is reserved
*/
@@ -1534,7 +1534,7 @@ public:
return !my_atomic_fas32_explicit(&reserved, true,
MY_MEMORY_ORDER_RELAXED);
}
-} buf_tmp_buffer_t;
+};
/** The common buffer control block structure
for compressed and uncompressed frames */
diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic
index bd1d529f753..93a6c4a7cc1 100644
--- a/storage/innobase/include/dict0dict.ic
+++ b/storage/innobase/include/dict0dict.ic
@@ -1026,16 +1026,18 @@ dict_table_x_lock_indexes(
/*======================*/
dict_table_t* table) /*!< in: table */
{
- dict_index_t* index;
-
ut_ad(mutex_own(&dict_sys->mutex));
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+
/* Loop through each index of the table and lock them */
- for (index = dict_table_get_first_index(table);
+ for (dict_index_t* index = dict_table_get_next_index(clust_index);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
}
+
+ rw_lock_x_lock(dict_index_get_lock(clust_index));
}
/*********************************************************************//**
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index 505d4925324..7c59789d313 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -848,6 +848,10 @@ struct dict_foreign_t{
does not generate new indexes
implicitly */
dict_index_t* referenced_index;/*!< referenced index */
+
+ /** Check whether the fulltext index gets affected by
+ foreign key constraint */
+ bool affects_fulltext() const;
};
std::ostream&
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 4bd394ff94d..74d0673ccfc 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -306,6 +306,8 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
+ /** the committed size of the tablespace in pages */
+ ulint committed_size;
ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
see fsp0fsp.h,
fsp_flags_is_valid(),
@@ -365,6 +367,15 @@ struct fil_space_t {
{
return stop_new_ops;
}
+
+ /** Clamp a page number for batched I/O, such as read-ahead.
+ @param offset page number limit
+ @return offset clamped to the tablespace size */
+ ulint max_page_number_for_io(ulint offset) const
+ {
+ const ulint limit= committed_size;
+ return limit > offset ? offset : limit;
+ }
};
/** Value of fil_space_t::magic_n */
@@ -568,16 +579,6 @@ ulint
fil_space_get_zip_size(
/*===================*/
ulint id); /*!< in: space id */
-/*******************************************************************//**
-Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache.
-@return TRUE if the address is meaningful */
-UNIV_INTERN
-ibool
-fil_check_adress_in_tablespace(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint page_no);/*!< in: page number */
/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
@@ -698,34 +699,6 @@ UNIV_INTERN
void
fil_space_release_for_io(fil_space_t* space);
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-UNIV_INTERN
-fil_space_t*
-fil_space_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_keyrotate_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
/** Wrapper with reference-counting for a fil_space_t. */
class FilSpace
{
diff --git a/storage/innobase/include/fts0ast.h b/storage/innobase/include/fts0ast.h
index b7d467e0082..b7870cbc7bc 100644
--- a/storage/innobase/include/fts0ast.h
+++ b/storage/innobase/include/fts0ast.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -204,19 +204,6 @@ fts_ast_visit(
operator, currently we only
ignore FTS_IGNORE operator */
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
-list. Merge the sub-expression result with that of parent expression list.
-@return DB_SUCCESS if all went well */
-UNIV_INTERN
-dberr_t
-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 */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************
Create a lex instance.*/
UNIV_INTERN
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 3beddd68722..886ac257f01 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -899,21 +899,19 @@ fts_valid_stopword_table(
name */
/****************************************************************//**
This function loads specified stopword into FTS cache
-@return TRUE if success */
+@return true if success */
UNIV_INTERN
-ibool
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transaction */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload); /*!< in: Whether it is during
+ bool reload); /*!< in: Whether it is during
reload of FTS table */
/****************************************************************//**
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 2628cdfc461..d1ad4c403d4 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -1008,10 +1009,6 @@ std::string
lock_get_info(
const lock_t*);
-/*******************************************************************//**
-@return whether wsrep_on is true on trx->mysql_thd*/
-#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd))
-
#endif /* WITH_WSREP */
#ifndef UNIV_NONINL
#include "lock0lock.ic"
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 6c0ee2c7ac7..d28c52237b2 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2016, MariaDB Corporation
+Copyright (c) 2013, 2020, MariaDB Corporation.
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,6 +58,7 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#endif /* UNIV_DEBUG */
#define MTR_MEMO_S_LOCK 55
#define MTR_MEMO_X_LOCK 56
+#define MTR_MEMO_SPACE_X_LOCK 57
/** @name Log item types
The log items are declared 'byte' so that the compiler can warn if val
@@ -295,6 +296,8 @@ This macro locks an rw-lock in s-mode. */
This macro locks an rw-lock in x-mode. */
#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\
(MTR))
+#define mtr_x_space_lock(B, MTR) mtr_x_space_lock_func(B, __FILE__, __LINE__,\
+ MTR)
/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in s-mode. */
@@ -317,6 +320,14 @@ mtr_x_lock_func(
const char* file, /*!< in: file name */
ulint line, /*!< in: line number */
mtr_t* mtr); /*!< in: mtr */
+
+/** Acquire exclusive tablespace latch.
+@param lock fil_space_t::latch
+@param file source code file name of the caller
+@param line source code line number of the caller
+@param mtr mini-transaction */
+inline void mtr_x_space_lock_func(rw_lock_t *lock,
+ const char *file, ulint line, mtr_t *mtr);
#endif /* !UNIV_HOTBACKUP */
/***************************************************//**
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index 5763c054a8f..a0f4779fb10 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -78,7 +79,7 @@ mtr_memo_push(
ut_ad(object);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
- ut_ad(type <= MTR_MEMO_X_LOCK);
+ ut_ad(type <= MTR_MEMO_SPACE_X_LOCK);
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
@@ -293,4 +294,16 @@ mtr_x_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}
+
+/** Acquire exclusive tablespace latch.
+@param lock fil_space_t::latch
+@param file source code file name of the caller
+@param line source code line number of the caller
+@param mtr mini-transaction */
+inline void mtr_x_space_lock_func(rw_lock_t *lock,
+ const char *file, ulint line, mtr_t *mtr)
+{
+ rw_lock_x_lock_inline(lock, 0, file, line);
+ mtr_memo_push(mtr, lock, MTR_MEMO_SPACE_X_LOCK);
+}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
index 64ae31905b4..5e9081476ce 100644
--- a/storage/innobase/include/page0page.h
+++ b/storage/innobase/include/page0page.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -759,21 +759,6 @@ page_mem_alloc_free(
free record list */
ulint need); /*!< in: number of bytes allocated */
/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-UNIV_INTERN
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no);/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-/************************************************************//**
Puts a record to free list. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/page0types.h b/storage/innobase/include/page0types.h
index cba2d7a7a8b..3f7a653f8f8 100644
--- a/storage/innobase/include/page0types.h
+++ b/storage/innobase/include/page0types.h
@@ -26,8 +26,6 @@ Created 2/2/1994 Heikki Tuuri
#ifndef page0types_h
#define page0types_h
-using namespace std;
-
#include <map>
#include "univ.i"
@@ -110,7 +108,7 @@ struct page_zip_stat_t {
};
/** Compression statistics types */
-typedef map<index_id_t, page_zip_stat_t> page_zip_stat_per_index_t;
+typedef std::map<index_id_t, page_zip_stat_t> page_zip_stat_per_index_t;
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
extern page_zip_stat_t page_zip_stat[PAGE_ZIP_SSIZE_MAX];
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index 54b6d46c58d..fba53a3f575 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -620,13 +621,6 @@ struct rw_lock_t {
/* last s-lock file/line is not guaranteed to be correct */
const char* last_s_file_name;/*!< File name where last s-locked */
const char* last_x_file_name;/*!< File name where last x-locked */
- ibool writer_is_wait_ex;
- /*!< This is TRUE if the writer field is
- RW_LOCK_WAIT_EX; this field is located far
- from the memory update hotspot fields which
- are at the start of this struct, thus we can
- peek this field without causing much memory
- bus traffic */
unsigned cline:14; /*!< Line where created */
unsigned last_s_line:14; /*!< Line number where last time s-locked */
unsigned last_x_line:14; /*!< Line number where last time x-locked */
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 0291140a982..9aa3daea4e1 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -769,15 +769,21 @@ struct trx_t{
ro_trx_list the first time they try to acquire a lock ie. by default
we treat all read-only transactions as non-locking. */
trx_state_t state;
-
trx_lock_t lock; /*!< Information about the transaction
locks and state. Protected by
trx->mutex or lock_sys->mutex
or both */
- ulint is_recovered; /*!< 0=normal transaction,
- 1=recovered, must be rolled back,
+ bool is_recovered; /*!< false=normal transaction,
+ true=recovered, must be rolled back,
protected by trx_sys->mutex when
trx->in_rw_trx_list holds */
+#ifdef WITH_WSREP
+ /** whether wsrep_on(mysql_thd) held at the start of transaction */
+ bool wsrep;
+ bool is_wsrep() const { return UNIV_UNLIKELY(wsrep); }
+#else /* WITH_WSREP */
+ bool is_wsrep() const { return false; }
+#endif /* WITH_WSREP */
/* These fields are not protected by any mutex. */
const char* op_info; /*!< English text describing the
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 02ab9e8b94f..77c01ccaa15 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -45,7 +45,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 45
+#define INNODB_VERSION_BUGFIX 50
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 0fade62e7aa..0c4e40067d1 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -1759,7 +1759,7 @@ wsrep_kill_victim(
ut_ad(trx_mutex_own(lock->trx));
/* quit for native mysql */
- if (!wsrep_on(trx->mysql_thd)) return;
+ if (!trx->is_wsrep()) return;
my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
@@ -1845,7 +1845,7 @@ lock_rec_other_has_conflicting(
#ifdef WITH_WSREP
if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) {
- if (wsrep_on_trx(trx)) {
+ if (trx->is_wsrep()) {
trx_mutex_enter(lock->trx);
/* Below function will roll back either trx
or lock->trx depending on priority of the
@@ -2179,8 +2179,7 @@ lock_rec_create(
ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
- if (c_lock &&
- wsrep_on_trx(trx) &&
+ if (c_lock && trx->is_wsrep() &&
wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
@@ -4973,7 +4972,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock && wsrep_on_trx(trx)) {
+ if (c_lock && trx->is_wsrep()) {
if (wsrep_thd_is_wsrep(trx->mysql_thd)
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
UT_LIST_INSERT_AFTER(
@@ -5212,7 +5211,7 @@ lock_table_enqueue_waiting(
/* Enqueue the lock request that will wait to be granted */
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
+ if (trx->lock.was_chosen_as_deadlock_victim && trx->is_wsrep()) {
return(DB_DEADLOCK);
}
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index ca697ab8be5..8f39c555c6a 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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,8 +200,7 @@ wsrep_is_BF_lock_timeout(
const trx_t* trx,
bool locked = true)
{
- if (wsrep_on_trx(trx)
- && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id);
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
@@ -390,7 +389,7 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout) {
#ifdef WITH_WSREP
- if (!wsrep_on_trx(trx) ||
+ if (!trx->is_wsrep() ||
(!wsrep_is_BF_lock_timeout(trx) &&
trx->error_state != DB_DEADLOCK)) {
#endif /* WITH_WSREP */
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 2db6e62cbed..1388da713b0 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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 +88,16 @@ mtr_memo_slot_release_func(
case MTR_MEMO_X_LOCK:
rw_lock_x_unlock((rw_lock_t*) object);
break;
+ case MTR_MEMO_SPACE_X_LOCK:
+ {
+ fil_space_t* space = reinterpret_cast<fil_space_t*>(
+ static_cast<char*>(object)
+ - reinterpret_cast<char*>(
+ &static_cast<fil_space_t*>(0)->latch));
+ space->committed_size = space->size;
+ rw_lock_x_unlock(&space->latch);
+ }
+ break;
#ifdef UNIV_DEBUG
default:
ut_ad(slot->type == MTR_MEMO_MODIFY);
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 3a403f880c1..9987544c6a1 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -2427,6 +2427,7 @@ os_file_set_size(
errno = err;
return false;
case EINVAL:
+ case EOPNOTSUPP:
/* fall back to the code below */
break;
}
diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc
index e9ac4b4bb04..94e861ab554 100644
--- a/storage/innobase/page/page0cur.cc
+++ b/storage/innobase/page/page0cur.cc
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -941,6 +942,52 @@ page_cur_parse_insert_rec(
return(ptr + end_seg_len);
}
+/************************************************************//**
+Allocates a block of memory from the heap of an index page.
+@return pointer to start of allocated buffer, or NULL if allocation fails */
+static
+byte*
+page_mem_alloc_heap(
+/*================*/
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
+ space available for inserting the record,
+ or NULL */
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no)/*!< out: this contains the heap number
+ of the allocated record
+ if allocation succeeds */
+{
+ byte* block;
+ ulint avl_space;
+
+ ut_ad(page && heap_no);
+
+ avl_space = page_get_max_insert_size(page, 1);
+
+ if (avl_space >= need) {
+ const ulint h = page_dir_get_n_heap(page);
+ if (UNIV_UNLIKELY(h >= 8191)) {
+ /* At the minimum record size of 5+2 bytes,
+ we can only reach this condition when using
+ innodb_page_size=64k. */
+ ut_ad(srv_page_size == 65536);
+ return(NULL);
+ }
+ *heap_no = h;
+
+ block = page_header_get_ptr(page, PAGE_HEAP_TOP);
+
+ page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
+ block + need);
+ page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
+
+ return(block);
+ }
+
+ return(NULL);
+}
+
/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc
index ac16d71322a..1d9e4a97782 100644
--- a/storage/innobase/page/page0page.cc
+++ b/storage/innobase/page/page0page.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
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
@@ -235,44 +235,6 @@ page_set_max_trx_id(
}
}
-/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-UNIV_INTERN
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no)/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-{
- byte* block;
- ulint avl_space;
-
- ut_ad(page && heap_no);
-
- avl_space = page_get_max_insert_size(page, 1);
-
- if (avl_space >= need) {
- block = page_header_get_ptr(page, PAGE_HEAP_TOP);
-
- page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
- block + need);
- *heap_no = page_dir_get_n_heap(page);
-
- page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
-
- return(block);
- }
-
- return(NULL);
-}
-
#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Writes a log record of page creation. */
diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc
index 233ccaa6a90..6f1c19799b5 100644
--- a/storage/innobase/page/page0zip.cc
+++ b/storage/innobase/page/page0zip.cc
@@ -28,9 +28,6 @@ Created June 2005 by Marko Makela
// First include (the generated) my_config.h, to get correct platform defines.
#include "my_config.h"
-#include <map>
-using namespace std;
-
#define THIS_MODULE
#include "page0zip.h"
#ifdef UNIV_NONINL
@@ -4921,35 +4918,28 @@ page_zip_verify_checksum(
ib_uint32_t crc32 = 0 /* silence bogus warning */;
ib_uint32_t innodb = 0 /* silence bogus warning */;
- stored = static_cast<ib_uint32_t>(mach_read_from_4(
- static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+ const srv_checksum_algorithm_t curr_algo =
+ static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-#if FIL_PAGE_LSN % 8
-#error "FIL_PAGE_LSN must be 64 bit aligned"
-#endif
+ if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
+ return true;
+ }
- /* Check if page is empty */
- if (stored == 0
- && *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
- data)
- + FIL_PAGE_LSN) == 0) {
- /* make sure that the page is really empty */
- for (ulint i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0) {
- return(FALSE);
- }
+ bool all_zeroes = true;
+ for (size_t i = 0; i < size; i++) {
+ if (static_cast<const byte*>(data)[i] != 0) {
+ all_zeroes = false;
+ break;
}
- /* Empty page */
- return(TRUE);
}
- const srv_checksum_algorithm_t curr_algo =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(TRUE);
+ if (all_zeroes) {
+ return true;
}
+ stored = static_cast<ib_uint32_t>(mach_read_from_4(
+ static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+
calc = static_cast<ib_uint32_t>(page_zip_calc_checksum(
data, size, curr_algo));
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index e1554949127..2121b00d009 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -561,14 +561,6 @@ protected:
/** Space id of the file being iterated over. */
ulint m_space;
- /** Minimum page number for which the free list has not been
- initialized: the pages >= this limit are, by definition, free;
- note that in a single-table tablespace where size < 64 pages,
- this number is 64, i.e., we have initialized the space about
- the first extent, but have not physically allocted those pages
- to the file. @see FSP_LIMIT. */
- ulint m_free_limit;
-
/** Current size of the space in pages */
ulint m_size;
@@ -647,7 +639,6 @@ AbstractCallback::init(
ut_a(m_space == ULINT_UNDEFINED);
m_size = mach_read_from_4(page + FSP_SIZE);
- m_free_limit = mach_read_from_4(page + FSP_FREE_LIMIT);
m_space = mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID);
return set_current_xdes(0, page);
@@ -1924,6 +1915,23 @@ PageConverter::update_index_page(
return(DB_SUCCESS);
}
+ if (m_index && block->page.offset == m_index->m_page_no) {
+ byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE
+ + page;
+ mach_write_to_4(b, block->page.space);
+
+ memcpy(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + FSEG_HDR_SPACE
+ + page, b, 4);
+ if (UNIV_LIKELY_NULL(block->page.zip.data)) {
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_TOP
+ + FSEG_HDR_SPACE], b, 4);
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_LEAF
+ + FSEG_HDR_SPACE], b, 4);
+ }
+ }
+
#ifdef UNIV_ZIP_DEBUG
ut_a(!is_compressed_table()
|| page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index));
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 4a4c5112f88..4d86b0f333c 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -510,7 +510,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- *fts_col_affected = FALSE;
+ *fts_col_affected = foreign->affects_fulltext();
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -631,16 +631,6 @@ row_ins_cascade_calc_update_vec(
padded_data, min_size);
}
- /* Check whether the current column has
- FTS index on it */
- if (table->fts
- && dict_table_is_fts_column(
- table->fts->indexes,
- dict_col_get_no(col))
- != ULINT_UNDEFINED) {
- *fts_col_affected = TRUE;
- }
-
/* If Doc ID is updated, check whether the
Doc ID is valid */
if (table->fts
@@ -977,7 +967,6 @@ row_ins_foreign_check_on_constraint(
upd_t* update;
ulint n_to_update;
dberr_t err;
- ulint i;
trx_t* trx;
mem_heap_t* tmp_heap = NULL;
doc_id_t doc_id = FTS_NULL_DOC_ID;
@@ -1191,7 +1180,7 @@ row_ins_foreign_check_on_constraint(
UNIV_MEM_INVALID(update->fields,
update->n_fields * sizeof *update->fields);
- for (i = 0; i < foreign->n_fields; i++) {
+ for (ulint i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
ufield->field_no = dict_table_get_nth_col_pos(
@@ -1200,32 +1189,14 @@ row_ins_foreign_check_on_constraint(
ufield->orig_len = 0;
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
-
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i))
- != ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
- }
}
- if (fts_col_affacted) {
- fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
- }
- } else if (table->fts && cascade->is_delete) {
- /* DICT_FOREIGN_ON_DELETE_CASCADE case */
- for (i = 0; i < foreign->n_fields; i++) {
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i))
- != ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
- }
- }
-
- if (fts_col_affacted) {
+ if (foreign->affects_fulltext()) {
fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
+ } else if (table->fts && cascade->is_delete
+ && foreign->affects_fulltext()) {
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (!node->is_delete
@@ -1639,7 +1610,7 @@ run_again:
if (check_ref) {
err = DB_SUCCESS;
#ifdef WITH_WSREP
- if (!wsrep_on(trx->mysql_thd)) {
+ if (!trx->is_wsrep()) {
goto end_scan;
}
enum wsrep_key_type key_type;
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index c6d9909a6fc..999e8d882ec 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -807,7 +807,7 @@ row_create_prebuilt(
temp_index->fields[i].fixed_len;
}
}
- srch_key_len = max(srch_key_len,temp_len);
+ srch_key_len = std::max(srch_key_len,temp_len);
}
ut_a(srch_key_len <= MAX_SRCH_KEY_VAL_BUFFER);
@@ -1125,7 +1125,7 @@ row_update_statistics_if_needed(
&& dict_stats_auto_recalc_is_enabled(table)) {
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
WSREP_DEBUG("Avoiding background statistics"
" calculation for table %s",
@@ -3205,6 +3205,16 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
} else {
+ bool fts_exist = (dict_table_has_fts_index(table)
+ || DICT_TF2_FLAG_IS_SET(
+ table, DICT_TF2_FTS_HAS_DOC_ID));
+
+ if (fts_exist) {
+ row_mysql_unlock_data_dictionary(trx);
+ fts_optimize_remove_table(table);
+ row_mysql_lock_data_dictionary(trx);
+ }
+
/* Do foreign key constraint checks. */
err = row_discard_tablespace_foreign_key_checks(trx, table);
@@ -3212,6 +3222,10 @@ row_discard_tablespace_for_mysql(
if (err == DB_SUCCESS) {
err = row_discard_tablespace(trx, table);
}
+
+ if (fts_exist && err != DB_SUCCESS) {
+ fts_optimize_add_table(table);
+ }
}
return(row_discard_tablespace_end(trx, table, err));
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 936b0eccfb7..a6654a603db 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -3588,7 +3588,7 @@ row_sel_try_search_shortcut_for_mysql(
/*********************************************************************//**
Check a pushed-down index condition.
-@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+@return ICP_ABORTED_BY_USER, ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
static
enum icp_result
row_search_idx_cond_check(
@@ -3723,9 +3723,16 @@ bool row_search_with_covering_prefix(
return false;
}
+ /* We can avoid a clustered index lookup if
+ all of the following hold:
+ (1) all columns are in the secondary index
+ (2) all values for columns that are prefix-only
+ indexes are shorter than the prefix size
+ This optimization can avoid many IOs for certain schemas. */
for (ulint i = 0; i < prebuilt->n_template; i++) {
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
ulint j = templ->rec_prefix_field_no;
+ ut_ad(!templ->mbminlen == !templ->mbmaxlen);
/** Condition (1) : is the field in the index. */
if (j == ULINT_UNDEFINED) {
@@ -3735,33 +3742,29 @@ bool row_search_with_covering_prefix(
/** Condition (2): If this is a prefix index then
row's value size shorter than prefix length. */
- if (!templ->rec_field_is_prefix) {
+ if (!templ->rec_field_is_prefix
+ || rec_offs_nth_sql_null(offsets, j)) {
continue;
}
- ulint rec_size = rec_offs_nth_size(offsets, j);
const dict_field_t* field = dict_index_get_nth_field(index, j);
- ulint max_chars = field->prefix_len / templ->mbmaxlen;
- ut_a(field->prefix_len > 0);
-
- if (rec_size < max_chars) {
- /* Record in bytes shorter than the index
- prefix length in char. */
+ if (!field->prefix_len) {
continue;
}
- if (rec_size * templ->mbminlen >= field->prefix_len) {
+ const ulint rec_size = rec_offs_nth_size(offsets, j);
+
+ if (rec_size >= field->prefix_len) {
/* Shortest representation string by the
byte length of the record is longer than the
maximum possible index prefix. */
return false;
}
- size_t num_chars = rec_field_len_in_chars(
- field->col, j, rec, offsets);
-
- if (num_chars >= max_chars) {
+ if (templ->mbminlen != templ->mbmaxlen
+ && rec_field_len_in_chars(field->col, j, rec, offsets)
+ >= field->prefix_len / templ->mbmaxlen) {
/* No of chars to store the record exceeds
the index prefix character length. */
return false;
@@ -4107,10 +4110,13 @@ row_search_for_mysql(
switch (row_search_idx_cond_check(
buf, prebuilt,
rec, offsets)) {
- case ICP_NO_MATCH:
- case ICP_OUT_OF_RANGE:
case ICP_ABORTED_BY_USER:
+ mtr_commit(&mtr);
+ err = DB_INTERRUPTED;
+ goto release_search_latch_if_needed;
case ICP_ERROR:
+ case ICP_NO_MATCH:
+ case ICP_OUT_OF_RANGE:
goto shortcut_mismatch;
case ICP_MATCH:
goto shortcut_match;
@@ -4846,8 +4852,10 @@ no_gap_lock:
buf, prebuilt, rec, offsets)) {
case ICP_NO_MATCH:
goto next_rec;
- case ICP_OUT_OF_RANGE:
case ICP_ABORTED_BY_USER:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
+ case ICP_OUT_OF_RANGE:
case ICP_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
@@ -4901,9 +4909,11 @@ locks_ok_del_marked:
row_unlock_for_mysql(prebuilt, TRUE);
}
goto next_rec;
+ case ICP_ABORTED_BY_USER:
+ err = DB_INTERRUPTED;
+ goto idx_cond_failed;
case ICP_OUT_OF_RANGE:
- case ICP_ABORTED_BY_USER:
- case ICP_ERROR:
+ case ICP_ERROR:
err = DB_RECORD_NOT_FOUND;
goto idx_cond_failed;
case ICP_MATCH:
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 435eb065d7a..6bb97e917bb 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
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
@@ -1811,7 +1811,7 @@ row_upd_store_row(
inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
{
- if (!wsrep_on_trx(trx)) {
+ if (!trx->is_wsrep()) {
return false;
}
return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
diff --git a/storage/innobase/srv/srv0conc.cc b/storage/innobase/srv/srv0conc.cc
index 8a1ece92ba4..bf57c308acf 100644
--- a/storage/innobase/srv/srv0conc.cc
+++ b/storage/innobase/srv/srv0conc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -213,8 +213,7 @@ srv_conc_enter_innodb_with_atomics(
for (;;) {
ulint sleep_in_us;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
if (wsrep_debug)
fprintf(stderr,
"srv_conc_enter due to MUST_ABORT");
@@ -421,8 +420,7 @@ retry:
return;
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_thd_is_brute_force(trx->mysql_thd)) {
srv_conc_force_enter_innodb(trx);
return;
}
@@ -504,8 +502,7 @@ retry:
srv_conc.n_waiting++;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
os_fast_mutex_unlock(&srv_conc_mutex);
if (wsrep_debug)
fprintf(stderr, "srv_conc_enter due to MUST_ABORT");
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index af9474dd9b3..f933442f036 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -527,7 +527,6 @@ current_time % 60 == 0 and no tasks will be performed when
current_time % 5 != 0. */
# define SRV_MASTER_CHECKPOINT_INTERVAL (7)
-# define SRV_MASTER_PURGE_INTERVAL (10)
#ifdef MEM_PERIODIC_CHECK
# define SRV_MASTER_MEM_VALIDATE_INTERVAL (13)
#endif /* MEM_PERIODIC_CHECK */
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index a73e67e9f5b..05f29d60411 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1203,6 +1203,10 @@ check_first_page:
}
}
+ if (fil_space_t* s = fil_space_get(0)) {
+ s->committed_size = s->size;
+ }
+
return(DB_SUCCESS);
}
@@ -1371,6 +1375,10 @@ srv_undo_tablespace_open(
if (fil_node_create(name, (ulint) n_pages, space, FALSE)) {
err = DB_SUCCESS;
}
+
+ if (fil_space_t* s = fil_space_get(space)) {
+ s->committed_size = n_pages;
+ }
}
return(err);
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc
index 9af6cfe5f0c..f3eaa1fbf86 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1077,7 +1077,7 @@ sync_array_print_long_waits(
sync_array_exit(arr);
}
- if (noticed) {
+ if (noticed && srv_monitor_event) {
ibool old_val;
fprintf(stderr,
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index 944e2353de8..e73e20737f6 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -65,7 +65,7 @@ trx_rseg_header_create(
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
/* Allocate a new file segment for the rollback segment */
block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
@@ -310,7 +310,7 @@ trx_rseg_create(ulint space)
/* To obey the latching order, acquire the file space
x-latch before the trx_sys->mutex. */
- mtr_x_lock(fil_space_get_latch(space, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, NULL), &mtr);
slot_no = trx_sysf_rseg_find_free(&mtr);
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 13fd37f4e50..6f348a2b13e 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -550,7 +550,7 @@ trx_sysf_create(
then enter the kernel: we must do it in this order to conform
to the latching order rules. */
- mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
+ mtr_x_space_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
/* Create the trx sys file block in a new allocated file segment */
block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 76d501aad53..53c5d1ca82d 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -1331,11 +1331,7 @@ trx_commit_in_memory(
ut_ad(!trx->in_ro_trx_list);
ut_ad(!trx->in_rw_trx_list);
-#ifdef WITH_WSREP
- if (trx->mysql_thd && wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif
+ trx->lock.was_chosen_as_deadlock_victim = FALSE;
trx->dict_operation = TRX_DICT_OP_NONE;
trx->error_state = DB_SUCCESS;
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 5f73a1dc1af..6355781e19c 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -296,7 +296,7 @@ static MYSQL_SYSVAR_BOOL(encrypt_tables, maria_encrypt_tables, PLUGIN_VAR_OPCMDA
"and not FIXED/DYNAMIC)",
0, 0, 0);
-#ifdef HAVE_PSI_INTERFACE
+#if defined HAVE_PSI_INTERFACE && !defined EMBEDDED_LIBRARY
static PSI_mutex_info all_aria_mutexes[]=
{
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 789a4d0d5b6..8231cd47913 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -3198,6 +3198,7 @@ static int write_page(MARIA_SHARE *share, File file,
args.page= buff;
args.pageno= (pgcache_page_no_t) (pos / share->block_size);
args.data= (uchar*) share;
+ args.crypt_buf= NULL;
(* share->kfile.pre_write_hook)(&args);
res= my_pwrite(file, args.page, block_size, pos, myf_rw);
(* share->kfile.post_write_hook)(res, &args);
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 263d8a307b1..e1d2d89020d 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -322,7 +322,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
options|= HA_OPTION_TMP_TABLE;
tmp_table= TRUE;
- create_mode|= O_NOFOLLOW;
+ create_mode|= O_NOFOLLOW | (internal_table ? 0 : O_EXCL);
/* "CREATE TEMPORARY" tables are not crash-safe (dropped at restart) */
ci->transactional= FALSE;
flags&= ~HA_CREATE_PAGE_CHECKSUM;
@@ -887,8 +887,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
char *iext= strrchr(name, '.');
int have_iext= iext && !strcmp(iext, MARIA_NAME_IEXT);
- fn_format(kfilename, name, "", MARIA_NAME_IEXT,
- MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
+ fn_format(kfilename, name, "", MARIA_NAME_IEXT, MY_UNPACK_FILENAME |
+ (internal_table ? 0 : MY_RETURN_REAL_PATH) |
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
klinkname_ptr= NullS;
/*
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 7067421b51a..e1d41d1a1d8 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -1,4 +1,5 @@
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+ Copyright (c) 2020, MariaDB Corporation.
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
@@ -112,7 +113,7 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
if (lock != PAGECACHE_LOCK_LEFT_UNLOCKED)
{
- DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE || PAGECACHE_LOCK_READ);
+ DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE || lock == PAGECACHE_LOCK_READ);
page_link.unlock= (lock == PAGECACHE_LOCK_WRITE ?
PAGECACHE_LOCK_WRITE_UNLOCK :
PAGECACHE_LOCK_READ_UNLOCK);
diff --git a/storage/maria/ma_pagecrc.c b/storage/maria/ma_pagecrc.c
index b0c02e60929..4d73ced3b11 100644
--- a/storage/maria/ma_pagecrc.c
+++ b/storage/maria/ma_pagecrc.c
@@ -251,7 +251,8 @@ my_bool maria_page_crc_check_index(int res, PAGECACHE_IO_HOOK_ARGS *args)
if (length > share->block_size - CRC_SIZE)
{
DBUG_PRINT("error", ("Wrong page length: %u", length));
- return (my_errno= HA_ERR_WRONG_CRC);
+ my_errno= HA_ERR_WRONG_CRC;
+ return 1;
}
return maria_page_crc_check(page, (uint32) page_no, share,
MARIA_NO_CRC_NORMAL_PAGE,
diff --git a/storage/mroonga/mrn_table.cpp b/storage/mroonga/mrn_table.cpp
index 8653092e45f..8fd48ffca17 100644
--- a/storage/mroonga/mrn_table.cpp
+++ b/storage/mroonga/mrn_table.cpp
@@ -932,7 +932,7 @@ MRN_SHARE *mrn_get_share(const char *table_name, TABLE *table, int *error)
share->wrap_key_info = NULL;
share->wrap_primary_key = MAX_KEY;
}
- memcpy(wrap_table_share, table->s, sizeof(*wrap_table_share));
+ *wrap_table_share= *table->s;
mrn_init_sql_alloc(current_thd, &(wrap_table_share->mem_root));
wrap_table_share->keys = share->wrap_keys;
wrap_table_share->key_info = share->wrap_key_info;
diff --git a/storage/myisam/ftbench/Ecompare.pl b/storage/myisam/ftbench/Ecompare.pl
index 07132ef9001..a97f126e64e 100755
--- a/storage/myisam/ftbench/Ecompare.pl
+++ b/storage/myisam/ftbench/Ecompare.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/ftbench/Ecreate.pl b/storage/myisam/ftbench/Ecreate.pl
index 86af9f9c0a5..78962466c80 100755
--- a/storage/myisam/ftbench/Ecreate.pl
+++ b/storage/myisam/ftbench/Ecreate.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/ftbench/Ereport.pl b/storage/myisam/ftbench/Ereport.pl
index d3f8961ec85..a8c7c57e1be 100755
--- a/storage/myisam/ftbench/Ereport.pl
+++ b/storage/myisam/ftbench/Ereport.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2003, 2005 MySQL AB
# Use is subject to license terms
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 855ac8337b9..7d6095b8a09 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -184,7 +184,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
if (flags & HA_CREATE_TMP_TABLE)
{
options|= HA_OPTION_TMP_TABLE;
- create_mode|= O_NOFOLLOW;
+ create_mode|= O_NOFOLLOW | (internal_table ? 0 : O_EXCL);
}
if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM))
{
@@ -618,8 +618,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
{
char *iext= strrchr(name, '.');
int have_iext= iext && !strcmp(iext, MI_NAME_IEXT);
- fn_format(kfilename, name, "", MI_NAME_IEXT,
- MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH |
+ fn_format(kfilename, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME |
+ (internal_table ? 0 : MY_RETURN_REAL_PATH) |
(have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT));
klinkname_ptr= 0;
/* Replace the current file */
diff --git a/storage/myisammrg/myrg_extra.c b/storage/myisammrg/myrg_extra.c
index 43dfc18c710..2b3861b9f7f 100644
--- a/storage/myisammrg/myrg_extra.c
+++ b/storage/myisammrg/myrg_extra.c
@@ -31,7 +31,7 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function,
DBUG_PRINT("info",("function: %lu", (ulong) function));
if (!info->children_attached)
- DBUG_RETURN(1);
+ DBUG_RETURN(0);
if (function == HA_EXTRA_CACHE)
{
info->cache_in_use=1;
diff --git a/storage/perfschema/CMakeLists.txt b/storage/perfschema/CMakeLists.txt
index 7db67700fac..e1839bc5b00 100644
--- a/storage/perfschema/CMakeLists.txt
+++ b/storage/perfschema/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2019, 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 Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/cursor_by_account.cc b/storage/perfschema/cursor_by_account.cc
index 2e75b8d51bd..f26318c42fc 100644
--- a/storage/perfschema/cursor_by_account.cc
+++ b/storage/perfschema/cursor_by_account.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_account.h b/storage/perfschema/cursor_by_account.h
index 150615b9c54..c14a563b712 100644
--- a/storage/perfschema/cursor_by_account.h
+++ b/storage/perfschema/cursor_by_account.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_host.cc b/storage/perfschema/cursor_by_host.cc
index d16f8b24b8e..c3397234e2e 100644
--- a/storage/perfschema/cursor_by_host.cc
+++ b/storage/perfschema/cursor_by_host.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_host.h b/storage/perfschema/cursor_by_host.h
index db33bbad808..ac68acf3945 100644
--- a/storage/perfschema/cursor_by_host.h
+++ b/storage/perfschema/cursor_by_host.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_thread.cc b/storage/perfschema/cursor_by_thread.cc
index 2fa9202fcf0..afdc9010b1f 100644
--- a/storage/perfschema/cursor_by_thread.cc
+++ b/storage/perfschema/cursor_by_thread.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_thread.h b/storage/perfschema/cursor_by_thread.h
index 5a77edf325f..db130088920 100644
--- a/storage/perfschema/cursor_by_thread.h
+++ b/storage/perfschema/cursor_by_thread.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_thread_connect_attr.cc b/storage/perfschema/cursor_by_thread_connect_attr.cc
index 2d5399cdac1..90a200b809a 100644
--- a/storage/perfschema/cursor_by_thread_connect_attr.cc
+++ b/storage/perfschema/cursor_by_thread_connect_attr.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/cursor_by_thread_connect_attr.h b/storage/perfschema/cursor_by_thread_connect_attr.h
index b5059918f7f..69d1b5ec0c0 100644
--- a/storage/perfschema/cursor_by_thread_connect_attr.h
+++ b/storage/perfschema/cursor_by_thread_connect_attr.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/cursor_by_user.cc b/storage/perfschema/cursor_by_user.cc
index 37ecbf17fee..273d186b01c 100644
--- a/storage/perfschema/cursor_by_user.cc
+++ b/storage/perfschema/cursor_by_user.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/cursor_by_user.h b/storage/perfschema/cursor_by_user.h
index d6e997766b6..06554ebb228 100644
--- a/storage/perfschema/cursor_by_user.h
+++ b/storage/perfschema/cursor_by_user.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/gen_pfs_lex_token.cc b/storage/perfschema/gen_pfs_lex_token.cc
index dcf25c79706..5a51a8aeb2f 100644
--- a/storage/perfschema/gen_pfs_lex_token.cc
+++ b/storage/perfschema/gen_pfs_lex_token.cc
@@ -2,13 +2,20 @@
Copyright (c) 2011, 2014, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc
index 42b452ca4dd..2591ec2a568 100644
--- a/storage/perfschema/ha_perfschema.cc
+++ b/storage/perfschema/ha_perfschema.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2014, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/ha_perfschema.h b/storage/perfschema/ha_perfschema.h
index 9c56fc1928e..0fbfdeba325 100644
--- a/storage/perfschema/ha_perfschema.h
+++ b/storage/perfschema/ha_perfschema.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2014, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc
index fa19f89f9d6..295a7f8c665 100644
--- a/storage/perfschema/pfs.cc
+++ b/storage/perfschema/pfs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs.h b/storage/perfschema/pfs.h
index da5e11edab7..8e0d9b760ed 100644
--- a/storage/perfschema/pfs.h
+++ b/storage/perfschema/pfs.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_account.cc b/storage/perfschema/pfs_account.cc
index 6f949d44065..6dcf44bc994 100644
--- a/storage/perfschema/pfs_account.cc
+++ b/storage/perfschema/pfs_account.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_account.h b/storage/perfschema/pfs_account.h
index 544abf913ae..cd7b1520df5 100644
--- a/storage/perfschema/pfs_account.h
+++ b/storage/perfschema/pfs_account.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_atomic.h b/storage/perfschema/pfs_atomic.h
index def9339d06d..00d1197970b 100644
--- a/storage/perfschema/pfs_atomic.h
+++ b/storage/perfschema/pfs_atomic.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2009, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_autosize.cc b/storage/perfschema/pfs_autosize.cc
index d099a3f1836..2219d43b8c7 100644
--- a/storage/perfschema/pfs_autosize.cc
+++ b/storage/perfschema/pfs_autosize.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_column_types.h b/storage/perfschema/pfs_column_types.h
index ef657b38707..09fce551402 100644
--- a/storage/perfschema/pfs_column_types.h
+++ b/storage/perfschema/pfs_column_types.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_column_values.cc b/storage/perfschema/pfs_column_values.cc
index 87fa9f0b639..697010e46b8 100644
--- a/storage/perfschema/pfs_column_values.cc
+++ b/storage/perfschema/pfs_column_values.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_column_values.h b/storage/perfschema/pfs_column_values.h
index eb25a5977e3..55ffa139fe0 100644
--- a/storage/perfschema/pfs_column_values.h
+++ b/storage/perfschema/pfs_column_values.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_con_slice.cc b/storage/perfschema/pfs_con_slice.cc
index bce4918ae9e..9f9deb0919c 100644
--- a/storage/perfschema/pfs_con_slice.cc
+++ b/storage/perfschema/pfs_con_slice.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_con_slice.h b/storage/perfschema/pfs_con_slice.h
index f83764339c3..ed17de5f2b0 100644
--- a/storage/perfschema/pfs_con_slice.h
+++ b/storage/perfschema/pfs_con_slice.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_defaults.cc b/storage/perfschema/pfs_defaults.cc
index ec2da41e30b..f879c527b4f 100644
--- a/storage/perfschema/pfs_defaults.cc
+++ b/storage/perfschema/pfs_defaults.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_defaults.h b/storage/perfschema/pfs_defaults.h
index d95c4914e9d..7751b55b83b 100644
--- a/storage/perfschema/pfs_defaults.h
+++ b/storage/perfschema/pfs_defaults.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_digest.cc b/storage/perfschema/pfs_digest.cc
index 1362ef2676b..7d66731ce3a 100644
--- a/storage/perfschema/pfs_digest.cc
+++ b/storage/perfschema/pfs_digest.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_digest.h b/storage/perfschema/pfs_digest.h
index 543fa7858a4..352f495a80c 100644
--- a/storage/perfschema/pfs_digest.h
+++ b/storage/perfschema/pfs_digest.h
@@ -1,13 +1,20 @@
/* 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_engine_table.cc b/storage/perfschema/pfs_engine_table.cc
index 289eb034e03..38fc44efff1 100644
--- a/storage/perfschema/pfs_engine_table.cc
+++ b/storage/perfschema/pfs_engine_table.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_engine_table.h b/storage/perfschema/pfs_engine_table.h
index d3c4a0e43e6..c53cd205d71 100644
--- a/storage/perfschema/pfs_engine_table.h
+++ b/storage/perfschema/pfs_engine_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events.h b/storage/perfschema/pfs_events.h
index 09c3935816f..ca2fd8582ad 100644
--- a/storage/perfschema/pfs_events.h
+++ b/storage/perfschema/pfs_events.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_events_stages.cc b/storage/perfschema/pfs_events_stages.cc
index 673d2cb95f5..a68b0729e96 100644
--- a/storage/perfschema/pfs_events_stages.cc
+++ b/storage/perfschema/pfs_events_stages.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events_stages.h b/storage/perfschema/pfs_events_stages.h
index ea879bcd211..f61a7c3c077 100644
--- a/storage/perfschema/pfs_events_stages.h
+++ b/storage/perfschema/pfs_events_stages.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_events_statements.cc b/storage/perfschema/pfs_events_statements.cc
index 66a98e3f7d8..1942787665a 100644
--- a/storage/perfschema/pfs_events_statements.cc
+++ b/storage/perfschema/pfs_events_statements.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events_statements.h b/storage/perfschema/pfs_events_statements.h
index a56423d3863..e47e2e79280 100644
--- a/storage/perfschema/pfs_events_statements.h
+++ b/storage/perfschema/pfs_events_statements.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_events_waits.cc b/storage/perfschema/pfs_events_waits.cc
index f99a1f31bd9..c3961461f34 100644
--- a/storage/perfschema/pfs_events_waits.cc
+++ b/storage/perfschema/pfs_events_waits.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_events_waits.h b/storage/perfschema/pfs_events_waits.h
index 79bd3383241..be4fb36619a 100644
--- a/storage/perfschema/pfs_events_waits.h
+++ b/storage/perfschema/pfs_events_waits.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_global.cc b/storage/perfschema/pfs_global.cc
index 25dd817b149..afa31ffa903 100644
--- a/storage/perfschema/pfs_global.cc
+++ b/storage/perfschema/pfs_global.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_global.h b/storage/perfschema/pfs_global.h
index 8ca12883f9d..d4451cd112e 100644
--- a/storage/perfschema/pfs_global.h
+++ b/storage/perfschema/pfs_global.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_host.cc b/storage/perfschema/pfs_host.cc
index 8ac2b2fd5d9..10eb21125d0 100644
--- a/storage/perfschema/pfs_host.cc
+++ b/storage/perfschema/pfs_host.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_host.h b/storage/perfschema/pfs_host.h
index 4e6b24bf6c6..d52207d3571 100644
--- a/storage/perfschema/pfs_host.h
+++ b/storage/perfschema/pfs_host.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc
index 1ea4fcd901b..e4ce1ff8e13 100644
--- a/storage/perfschema/pfs_instr.cc
+++ b/storage/perfschema/pfs_instr.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_instr.h b/storage/perfschema/pfs_instr.h
index 76eeabb99da..12447c0c4e7 100644
--- a/storage/perfschema/pfs_instr.h
+++ b/storage/perfschema/pfs_instr.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_instr_class.cc b/storage/perfschema/pfs_instr_class.cc
index 0d06ac025f2..8209f6e0db2 100644
--- a/storage/perfschema/pfs_instr_class.cc
+++ b/storage/perfschema/pfs_instr_class.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_instr_class.h b/storage/perfschema/pfs_instr_class.h
index 038814b07e2..9d256fac78a 100644
--- a/storage/perfschema/pfs_instr_class.h
+++ b/storage/perfschema/pfs_instr_class.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_lock.h b/storage/perfschema/pfs_lock.h
index 4011cba2070..b74131c79e1 100644
--- a/storage/perfschema/pfs_lock.h
+++ b/storage/perfschema/pfs_lock.h
@@ -1,13 +1,20 @@
/* 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_server.cc b/storage/perfschema/pfs_server.cc
index 9dd6fbf4762..77574f1ce49 100644
--- a/storage/perfschema/pfs_server.cc
+++ b/storage/perfschema/pfs_server.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_server.h b/storage/perfschema/pfs_server.h
index aea86a576cc..0532dcb7eba 100644
--- a/storage/perfschema/pfs_server.h
+++ b/storage/perfschema/pfs_server.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_setup_actor.cc b/storage/perfschema/pfs_setup_actor.cc
index f3b6bc1791f..9b2e282a08d 100644
--- a/storage/perfschema/pfs_setup_actor.cc
+++ b/storage/perfschema/pfs_setup_actor.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_setup_actor.h b/storage/perfschema/pfs_setup_actor.h
index 92a1617c304..613d5454a9c 100644
--- a/storage/perfschema/pfs_setup_actor.h
+++ b/storage/perfschema/pfs_setup_actor.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_setup_object.cc b/storage/perfschema/pfs_setup_object.cc
index 3cc14d9a14e..78234966647 100644
--- a/storage/perfschema/pfs_setup_object.cc
+++ b/storage/perfschema/pfs_setup_object.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_setup_object.h b/storage/perfschema/pfs_setup_object.h
index 0d343f552b2..ee40742941c 100644
--- a/storage/perfschema/pfs_setup_object.h
+++ b/storage/perfschema/pfs_setup_object.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_stat.h b/storage/perfschema/pfs_stat.h
index 9e4da7957f6..8a049e3013b 100644
--- a/storage/perfschema/pfs_stat.h
+++ b/storage/perfschema/pfs_stat.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_timer.cc b/storage/perfschema/pfs_timer.cc
index 5e2c27c217b..8533dffcb27 100644
--- a/storage/perfschema/pfs_timer.cc
+++ b/storage/perfschema/pfs_timer.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_timer.h b/storage/perfschema/pfs_timer.h
index a4f55c20994..738e0b365fb 100644
--- a/storage/perfschema/pfs_timer.h
+++ b/storage/perfschema/pfs_timer.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_user.cc b/storage/perfschema/pfs_user.cc
index f9f6782cd75..099b7eba4d7 100644
--- a/storage/perfschema/pfs_user.cc
+++ b/storage/perfschema/pfs_user.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_user.h b/storage/perfschema/pfs_user.h
index f2b1c4409c7..3d0457eae59 100644
--- a/storage/perfschema/pfs_user.h
+++ b/storage/perfschema/pfs_user.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/pfs_visitor.cc b/storage/perfschema/pfs_visitor.cc
index 3df7ef91bb3..097965fde17 100644
--- a/storage/perfschema/pfs_visitor.cc
+++ b/storage/perfschema/pfs_visitor.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/pfs_visitor.h b/storage/perfschema/pfs_visitor.h
index c3ada2f4e0b..120b5928045 100644
--- a/storage/perfschema/pfs_visitor.h
+++ b/storage/perfschema/pfs_visitor.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_accounts.cc b/storage/perfschema/table_accounts.cc
index 007fcb25550..708f8269a69 100644
--- a/storage/perfschema/table_accounts.cc
+++ b/storage/perfschema/table_accounts.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_accounts.h b/storage/perfschema/table_accounts.h
index f72eb39ed39..dfc2cc322e0 100644
--- a/storage/perfschema/table_accounts.h
+++ b/storage/perfschema/table_accounts.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_all_instr.cc b/storage/perfschema/table_all_instr.cc
index 05ec9f09c11..d48028b1539 100644
--- a/storage/perfschema/table_all_instr.cc
+++ b/storage/perfschema/table_all_instr.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_all_instr.h b/storage/perfschema/table_all_instr.h
index 7c9d5d9b0d6..072221ba86e 100644
--- a/storage/perfschema/table_all_instr.h
+++ b/storage/perfschema/table_all_instr.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_esgs_by_account_by_event_name.cc b/storage/perfschema/table_esgs_by_account_by_event_name.cc
index 3bc76f899ad..22e4e0040f1 100644
--- a/storage/perfschema/table_esgs_by_account_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_account_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_account_by_event_name.h b/storage/perfschema/table_esgs_by_account_by_event_name.h
index 5afd68cd7d9..ee855d42818 100644
--- a/storage/perfschema/table_esgs_by_account_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_account_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_host_by_event_name.cc b/storage/perfschema/table_esgs_by_host_by_event_name.cc
index bbef6a8d16d..86cc2eb1b86 100644
--- a/storage/perfschema/table_esgs_by_host_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_host_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_host_by_event_name.h b/storage/perfschema/table_esgs_by_host_by_event_name.h
index afc6d529428..6042e6396af 100644
--- a/storage/perfschema/table_esgs_by_host_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_host_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_thread_by_event_name.cc b/storage/perfschema/table_esgs_by_thread_by_event_name.cc
index 57ef634acad..dfda9702abb 100644
--- a/storage/perfschema/table_esgs_by_thread_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_thread_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_thread_by_event_name.h b/storage/perfschema/table_esgs_by_thread_by_event_name.h
index 7db8d1be408..6ff677a95e2 100644
--- a/storage/perfschema/table_esgs_by_thread_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_thread_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_user_by_event_name.cc b/storage/perfschema/table_esgs_by_user_by_event_name.cc
index f8e8518bde3..af73c1fc5fd 100644
--- a/storage/perfschema/table_esgs_by_user_by_event_name.cc
+++ b/storage/perfschema/table_esgs_by_user_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_by_user_by_event_name.h b/storage/perfschema/table_esgs_by_user_by_event_name.h
index 8f48747c8c8..bc545c2438a 100644
--- a/storage/perfschema/table_esgs_by_user_by_event_name.h
+++ b/storage/perfschema/table_esgs_by_user_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_global_by_event_name.cc b/storage/perfschema/table_esgs_global_by_event_name.cc
index 83a4dbf43fd..6c5f0866671 100644
--- a/storage/perfschema/table_esgs_global_by_event_name.cc
+++ b/storage/perfschema/table_esgs_global_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esgs_global_by_event_name.h b/storage/perfschema/table_esgs_global_by_event_name.h
index 2b0ac8b6218..b8884355676 100644
--- a/storage/perfschema/table_esgs_global_by_event_name.h
+++ b/storage/perfschema/table_esgs_global_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_account_by_event_name.cc b/storage/perfschema/table_esms_by_account_by_event_name.cc
index d8f04d7af23..7afdabcbbfe 100644
--- a/storage/perfschema/table_esms_by_account_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_account_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_account_by_event_name.h b/storage/perfschema/table_esms_by_account_by_event_name.h
index ff212291760..64f2053cff6 100644
--- a/storage/perfschema/table_esms_by_account_by_event_name.h
+++ b/storage/perfschema/table_esms_by_account_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_digest.cc b/storage/perfschema/table_esms_by_digest.cc
index ae648378b2a..5295c29dc40 100644
--- a/storage/perfschema/table_esms_by_digest.cc
+++ b/storage/perfschema/table_esms_by_digest.cc
@@ -1,13 +1,20 @@
/* 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_digest.h b/storage/perfschema/table_esms_by_digest.h
index 682dc70ab10..903b86110f6 100644
--- a/storage/perfschema/table_esms_by_digest.h
+++ b/storage/perfschema/table_esms_by_digest.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_host_by_event_name.cc b/storage/perfschema/table_esms_by_host_by_event_name.cc
index 7233b340bd2..42629ab6c09 100644
--- a/storage/perfschema/table_esms_by_host_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_host_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_host_by_event_name.h b/storage/perfschema/table_esms_by_host_by_event_name.h
index def5e19ecdc..a6985b48149 100644
--- a/storage/perfschema/table_esms_by_host_by_event_name.h
+++ b/storage/perfschema/table_esms_by_host_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_thread_by_event_name.cc b/storage/perfschema/table_esms_by_thread_by_event_name.cc
index f62d974aa76..0a7cf46986c 100644
--- a/storage/perfschema/table_esms_by_thread_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_thread_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_thread_by_event_name.h b/storage/perfschema/table_esms_by_thread_by_event_name.h
index 7c50307c483..72645d03389 100644
--- a/storage/perfschema/table_esms_by_thread_by_event_name.h
+++ b/storage/perfschema/table_esms_by_thread_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_user_by_event_name.cc b/storage/perfschema/table_esms_by_user_by_event_name.cc
index 66afe288f12..f8708ac9a14 100644
--- a/storage/perfschema/table_esms_by_user_by_event_name.cc
+++ b/storage/perfschema/table_esms_by_user_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_by_user_by_event_name.h b/storage/perfschema/table_esms_by_user_by_event_name.h
index 65284122043..d1d1e5df85d 100644
--- a/storage/perfschema/table_esms_by_user_by_event_name.h
+++ b/storage/perfschema/table_esms_by_user_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_global_by_event_name.cc b/storage/perfschema/table_esms_global_by_event_name.cc
index 96957bf028e..7d9584752b0 100644
--- a/storage/perfschema/table_esms_global_by_event_name.cc
+++ b/storage/perfschema/table_esms_global_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_esms_global_by_event_name.h b/storage/perfschema/table_esms_global_by_event_name.h
index 7453d635848..b90c14c0c0f 100644
--- a/storage/perfschema/table_esms_global_by_event_name.h
+++ b/storage/perfschema/table_esms_global_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_events_stages.cc b/storage/perfschema/table_events_stages.cc
index 757c42b59c4..0a09d2c83fa 100644
--- a/storage/perfschema/table_events_stages.cc
+++ b/storage/perfschema/table_events_stages.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_stages.h b/storage/perfschema/table_events_stages.h
index cbc0f9a42bb..ae8760cd953 100644
--- a/storage/perfschema/table_events_stages.h
+++ b/storage/perfschema/table_events_stages.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc
index 9dc8c329b96..2a238e6aff5 100644
--- a/storage/perfschema/table_events_statements.cc
+++ b/storage/perfschema/table_events_statements.cc
@@ -1,13 +1,20 @@
/* 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_statements.h b/storage/perfschema/table_events_statements.h
index 6f8bc1621d0..cec28628f3e 100644
--- a/storage/perfschema/table_events_statements.h
+++ b/storage/perfschema/table_events_statements.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc
index c77d35811c8..385382b2208 100644
--- a/storage/perfschema/table_events_waits.cc
+++ b/storage/perfschema/table_events_waits.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits.h b/storage/perfschema/table_events_waits.h
index 3e09fa487ad..90c1d341e5d 100644
--- a/storage/perfschema/table_events_waits.h
+++ b/storage/perfschema/table_events_waits.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits_summary.cc b/storage/perfschema/table_events_waits_summary.cc
index 2f5c83d57d3..03477f6d542 100644
--- a/storage/perfschema/table_events_waits_summary.cc
+++ b/storage/perfschema/table_events_waits_summary.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_events_waits_summary.h b/storage/perfschema/table_events_waits_summary.h
index a4f063bb66a..53f1bed7987 100644
--- a/storage/perfschema/table_events_waits_summary.h
+++ b/storage/perfschema/table_events_waits_summary.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_ews_by_account_by_event_name.cc b/storage/perfschema/table_ews_by_account_by_event_name.cc
index 0b86a4ac1dc..fa6258ec9ac 100644
--- a/storage/perfschema/table_ews_by_account_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_account_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_account_by_event_name.h b/storage/perfschema/table_ews_by_account_by_event_name.h
index b46008e2675..7cde09183e3 100644
--- a/storage/perfschema/table_ews_by_account_by_event_name.h
+++ b/storage/perfschema/table_ews_by_account_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_host_by_event_name.cc b/storage/perfschema/table_ews_by_host_by_event_name.cc
index e82c734431c..e3ef7ca3720 100644
--- a/storage/perfschema/table_ews_by_host_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_host_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_host_by_event_name.h b/storage/perfschema/table_ews_by_host_by_event_name.h
index c631da36ec5..8ce44a96617 100644
--- a/storage/perfschema/table_ews_by_host_by_event_name.h
+++ b/storage/perfschema/table_ews_by_host_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_thread_by_event_name.cc b/storage/perfschema/table_ews_by_thread_by_event_name.cc
index 7b3e220e973..33f9765310b 100644
--- a/storage/perfschema/table_ews_by_thread_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_thread_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_thread_by_event_name.h b/storage/perfschema/table_ews_by_thread_by_event_name.h
index cf94e7a81a2..b67664bfced 100644
--- a/storage/perfschema/table_ews_by_thread_by_event_name.h
+++ b/storage/perfschema/table_ews_by_thread_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_user_by_event_name.cc b/storage/perfschema/table_ews_by_user_by_event_name.cc
index 577a9ef6676..cb99f749a9c 100644
--- a/storage/perfschema/table_ews_by_user_by_event_name.cc
+++ b/storage/perfschema/table_ews_by_user_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_by_user_by_event_name.h b/storage/perfschema/table_ews_by_user_by_event_name.h
index e987cf1bcec..f4f29534be4 100644
--- a/storage/perfschema/table_ews_by_user_by_event_name.h
+++ b/storage/perfschema/table_ews_by_user_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_ews_global_by_event_name.cc b/storage/perfschema/table_ews_global_by_event_name.cc
index 9a5ba4f2375..7420c6351fd 100644
--- a/storage/perfschema/table_ews_global_by_event_name.cc
+++ b/storage/perfschema/table_ews_global_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_ews_global_by_event_name.h b/storage/perfschema/table_ews_global_by_event_name.h
index 57e3459e373..8157d274112 100644
--- a/storage/perfschema/table_ews_global_by_event_name.h
+++ b/storage/perfschema/table_ews_global_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_instances.cc b/storage/perfschema/table_file_instances.cc
index 7914664e2e0..b323df83ad2 100644
--- a/storage/perfschema/table_file_instances.cc
+++ b/storage/perfschema/table_file_instances.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_instances.h b/storage/perfschema/table_file_instances.h
index e07017911de..5b44e63028e 100644
--- a/storage/perfschema/table_file_instances.h
+++ b/storage/perfschema/table_file_instances.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_event_name.cc b/storage/perfschema/table_file_summary_by_event_name.cc
index e98bc528995..459b2bf99a6 100644
--- a/storage/perfschema/table_file_summary_by_event_name.cc
+++ b/storage/perfschema/table_file_summary_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_event_name.h b/storage/perfschema/table_file_summary_by_event_name.h
index 7a13fcdc4d9..b8cb293cb07 100644
--- a/storage/perfschema/table_file_summary_by_event_name.h
+++ b/storage/perfschema/table_file_summary_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_instance.cc b/storage/perfschema/table_file_summary_by_instance.cc
index b80811d0a5b..3a30984405c 100644
--- a/storage/perfschema/table_file_summary_by_instance.cc
+++ b/storage/perfschema/table_file_summary_by_instance.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_file_summary_by_instance.h b/storage/perfschema/table_file_summary_by_instance.h
index 872698f8e58..0e7ce6958b2 100644
--- a/storage/perfschema/table_file_summary_by_instance.h
+++ b/storage/perfschema/table_file_summary_by_instance.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_helper.cc b/storage/perfschema/table_helper.cc
index 0dbeeb259c1..d6bdd894483 100644
--- a/storage/perfschema/table_helper.cc
+++ b/storage/perfschema/table_helper.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_helper.h b/storage/perfschema/table_helper.h
index b57abe9c4e6..62f94826754 100644
--- a/storage/perfschema/table_helper.h
+++ b/storage/perfschema/table_helper.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_host_cache.cc b/storage/perfschema/table_host_cache.cc
index 758a2c6dea6..430dcf2763d 100644
--- a/storage/perfschema/table_host_cache.cc
+++ b/storage/perfschema/table_host_cache.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_host_cache.h b/storage/perfschema/table_host_cache.h
index 47abb42444e..8add0b5049c 100644
--- a/storage/perfschema/table_host_cache.h
+++ b/storage/perfschema/table_host_cache.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_hosts.cc b/storage/perfschema/table_hosts.cc
index 2c5377db4ac..8bc5310817c 100644
--- a/storage/perfschema/table_hosts.cc
+++ b/storage/perfschema/table_hosts.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_hosts.h b/storage/perfschema/table_hosts.h
index 60b70ae803e..422b6449b25 100644
--- a/storage/perfschema/table_hosts.h
+++ b/storage/perfschema/table_hosts.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_os_global_by_type.cc b/storage/perfschema/table_os_global_by_type.cc
index cd2ace50c85..b549b0c22e7 100644
--- a/storage/perfschema/table_os_global_by_type.cc
+++ b/storage/perfschema/table_os_global_by_type.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_os_global_by_type.h b/storage/perfschema/table_os_global_by_type.h
index a434961b65b..2b9293ece06 100644
--- a/storage/perfschema/table_os_global_by_type.h
+++ b/storage/perfschema/table_os_global_by_type.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_performance_timers.cc b/storage/perfschema/table_performance_timers.cc
index 8d31c017832..a77f005ab62 100644
--- a/storage/perfschema/table_performance_timers.cc
+++ b/storage/perfschema/table_performance_timers.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_performance_timers.h b/storage/perfschema/table_performance_timers.h
index e1dc93fcbe4..93210ac9882 100644
--- a/storage/perfschema/table_performance_timers.h
+++ b/storage/perfschema/table_performance_timers.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_account_connect_attrs.cc b/storage/perfschema/table_session_account_connect_attrs.cc
index c00f72e36b4..59a36e1cdb0 100644
--- a/storage/perfschema/table_session_account_connect_attrs.cc
+++ b/storage/perfschema/table_session_account_connect_attrs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_account_connect_attrs.h b/storage/perfschema/table_session_account_connect_attrs.h
index d56d571fb79..483001fcb91 100644
--- a/storage/perfschema/table_session_account_connect_attrs.h
+++ b/storage/perfschema/table_session_account_connect_attrs.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect.cc b/storage/perfschema/table_session_connect.cc
index 737ff514555..47dd63a9f49 100644
--- a/storage/perfschema/table_session_connect.cc
+++ b/storage/perfschema/table_session_connect.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect.h b/storage/perfschema/table_session_connect.h
index 91d24ab7075..ee1019fe7f2 100644
--- a/storage/perfschema/table_session_connect.h
+++ b/storage/perfschema/table_session_connect.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, 2013, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect_attrs.cc b/storage/perfschema/table_session_connect_attrs.cc
index 859c6f2f8b8..a4bb651f291 100644
--- a/storage/perfschema/table_session_connect_attrs.cc
+++ b/storage/perfschema/table_session_connect_attrs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_session_connect_attrs.h b/storage/perfschema/table_session_connect_attrs.h
index de18085d8ac..927c3a92af2 100644
--- a/storage/perfschema/table_session_connect_attrs.h
+++ b/storage/perfschema/table_session_connect_attrs.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_actors.cc b/storage/perfschema/table_setup_actors.cc
index fcb32b9cb35..305cfd32169 100644
--- a/storage/perfschema/table_setup_actors.cc
+++ b/storage/perfschema/table_setup_actors.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_actors.h b/storage/perfschema/table_setup_actors.h
index 550e196c8d1..3082c9c3922 100644
--- a/storage/perfschema/table_setup_actors.h
+++ b/storage/perfschema/table_setup_actors.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_consumers.cc b/storage/perfschema/table_setup_consumers.cc
index f00e1fff48d..afd7f41260a 100644
--- a/storage/perfschema/table_setup_consumers.cc
+++ b/storage/perfschema/table_setup_consumers.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_consumers.h b/storage/perfschema/table_setup_consumers.h
index b27c8873550..608ee880435 100644
--- a/storage/perfschema/table_setup_consumers.h
+++ b/storage/perfschema/table_setup_consumers.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_instruments.cc b/storage/perfschema/table_setup_instruments.cc
index 8adea1d3604..4741e944ee0 100644
--- a/storage/perfschema/table_setup_instruments.cc
+++ b/storage/perfschema/table_setup_instruments.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_instruments.h b/storage/perfschema/table_setup_instruments.h
index b2711578d7f..433fdaf056b 100644
--- a/storage/perfschema/table_setup_instruments.h
+++ b/storage/perfschema/table_setup_instruments.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_objects.cc b/storage/perfschema/table_setup_objects.cc
index 8049fcdf48c..168c51cfdda 100644
--- a/storage/perfschema/table_setup_objects.cc
+++ b/storage/perfschema/table_setup_objects.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_objects.h b/storage/perfschema/table_setup_objects.h
index 943cc4a1ad5..66f9fb2c8e8 100644
--- a/storage/perfschema/table_setup_objects.h
+++ b/storage/perfschema/table_setup_objects.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_timers.cc b/storage/perfschema/table_setup_timers.cc
index 26539da2e27..be1ac58cc3e 100644
--- a/storage/perfschema/table_setup_timers.cc
+++ b/storage/perfschema/table_setup_timers.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_setup_timers.h b/storage/perfschema/table_setup_timers.h
index 9eb2f95836c..667c1d94889 100644
--- a/storage/perfschema/table_setup_timers.h
+++ b/storage/perfschema/table_setup_timers.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_instances.cc b/storage/perfschema/table_socket_instances.cc
index 419e19349f4..920531136d5 100644
--- a/storage/perfschema/table_socket_instances.cc
+++ b/storage/perfschema/table_socket_instances.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_instances.h b/storage/perfschema/table_socket_instances.h
index b5e5edb36ed..41b5ee3fd21 100644
--- a/storage/perfschema/table_socket_instances.h
+++ b/storage/perfschema/table_socket_instances.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_event_name.cc b/storage/perfschema/table_socket_summary_by_event_name.cc
index 2da45c0d2cd..c813d45b732 100644
--- a/storage/perfschema/table_socket_summary_by_event_name.cc
+++ b/storage/perfschema/table_socket_summary_by_event_name.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_event_name.h b/storage/perfschema/table_socket_summary_by_event_name.h
index 9bdeb3104b4..4f679d89b09 100644
--- a/storage/perfschema/table_socket_summary_by_event_name.h
+++ b/storage/perfschema/table_socket_summary_by_event_name.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_instance.cc b/storage/perfschema/table_socket_summary_by_instance.cc
index 693f65e4843..a4b1477aa90 100644
--- a/storage/perfschema/table_socket_summary_by_instance.cc
+++ b/storage/perfschema/table_socket_summary_by_instance.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_socket_summary_by_instance.h b/storage/perfschema/table_socket_summary_by_instance.h
index deb8ffab554..a9eab8d18b6 100644
--- a/storage/perfschema/table_socket_summary_by_instance.h
+++ b/storage/perfschema/table_socket_summary_by_instance.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_sync_instances.cc b/storage/perfschema/table_sync_instances.cc
index 6e48468e6c3..f0c7800d24a 100644
--- a/storage/perfschema/table_sync_instances.cc
+++ b/storage/perfschema/table_sync_instances.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_sync_instances.h b/storage/perfschema/table_sync_instances.h
index c6a2ed8adaa..6f7e1bf5523 100644
--- a/storage/perfschema/table_sync_instances.h
+++ b/storage/perfschema/table_sync_instances.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_threads.cc b/storage/perfschema/table_threads.cc
index 1f198ba1378..fc29d711812 100644
--- a/storage/perfschema/table_threads.cc
+++ b/storage/perfschema/table_threads.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2014, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_threads.h b/storage/perfschema/table_threads.h
index 823f66bf713..927438eec61 100644
--- a/storage/perfschema/table_threads.h
+++ b/storage/perfschema/table_threads.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_tiws_by_index_usage.cc b/storage/perfschema/table_tiws_by_index_usage.cc
index 5d24fcc689b..b49e9280469 100644
--- a/storage/perfschema/table_tiws_by_index_usage.cc
+++ b/storage/perfschema/table_tiws_by_index_usage.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tiws_by_index_usage.h b/storage/perfschema/table_tiws_by_index_usage.h
index f6d935365b2..a284bc7f0bc 100644
--- a/storage/perfschema/table_tiws_by_index_usage.h
+++ b/storage/perfschema/table_tiws_by_index_usage.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tiws_by_table.cc b/storage/perfschema/table_tiws_by_table.cc
index 78535fd6512..db00fd2409e 100644
--- a/storage/perfschema/table_tiws_by_table.cc
+++ b/storage/perfschema/table_tiws_by_table.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tiws_by_table.h b/storage/perfschema/table_tiws_by_table.h
index 9a86d39196c..7427ca797fa 100644
--- a/storage/perfschema/table_tiws_by_table.h
+++ b/storage/perfschema/table_tiws_by_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tlws_by_table.cc b/storage/perfschema/table_tlws_by_table.cc
index 5299e7f6a56..d802127d10d 100644
--- a/storage/perfschema/table_tlws_by_table.cc
+++ b/storage/perfschema/table_tlws_by_table.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_tlws_by_table.h b/storage/perfschema/table_tlws_by_table.h
index 757adc3f5f5..b5872a07762 100644
--- a/storage/perfschema/table_tlws_by_table.h
+++ b/storage/perfschema/table_tlws_by_table.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2012, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/table_users.cc b/storage/perfschema/table_users.cc
index 6d6bfc5bfaf..883ebd36633 100644
--- a/storage/perfschema/table_users.cc
+++ b/storage/perfschema/table_users.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/table_users.h b/storage/perfschema/table_users.h
index 1b24dfb9039..912f0f43714 100644
--- a/storage/perfschema/table_users.h
+++ b/storage/perfschema/table_users.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/CMakeLists.txt b/storage/perfschema/unittest/CMakeLists.txt
index b449640b374..7b8c906a4e6 100644
--- a/storage/perfschema/unittest/CMakeLists.txt
+++ b/storage/perfschema/unittest/CMakeLists.txt
@@ -1,13 +1,20 @@
-# Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2019, 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 Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/conf.txt b/storage/perfschema/unittest/conf.txt
index 8a14b9ed14b..f84ba3317b1 100644
--- a/storage/perfschema/unittest/conf.txt
+++ b/storage/perfschema/unittest/conf.txt
@@ -1,13 +1,20 @@
# Copyright (c) 2009, 2010, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
+# it under the terms of the GNU General Public License, version 2.0,
+# as published by the Free Software Foundation.
+#
+# This program is also distributed with certain software (including
+# but not limited to OpenSSL) that is licensed under separate terms,
+# as designated in a particular file or component or in included license
+# documentation. The authors of MySQL hereby grant you an additional
+# permission to link the program and your derivative works with the
+# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
+# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs-t.cc b/storage/perfschema/unittest/pfs-t.cc
index e2ff73699ec..6e46d772380 100644
--- a/storage/perfschema/unittest/pfs-t.cc
+++ b/storage/perfschema/unittest/pfs-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2018, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_account-oom-t.cc b/storage/perfschema/unittest/pfs_account-oom-t.cc
index 71c089ab0f5..1ca66445e0c 100644
--- a/storage/perfschema/unittest/pfs_account-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_account-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_connect_attr-t.cc b/storage/perfschema/unittest/pfs_connect_attr-t.cc
index 3dd62ca5662..7ebfb0c8294 100644
--- a/storage/perfschema/unittest/pfs_connect_attr-t.cc
+++ b/storage/perfschema/unittest/pfs_connect_attr-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_host-oom-t.cc b/storage/perfschema/unittest/pfs_host-oom-t.cc
index e2eba7e6aff..14af1af0352 100644
--- a/storage/perfschema/unittest/pfs_host-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_host-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr-oom-t.cc b/storage/perfschema/unittest/pfs_instr-oom-t.cc
index a18902dc3db..231fd1e100b 100644
--- a/storage/perfschema/unittest/pfs_instr-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_instr-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr-t.cc b/storage/perfschema/unittest/pfs_instr-t.cc
index 47a91d9bb9a..c9f4bac1171 100644
--- a/storage/perfschema/unittest/pfs_instr-t.cc
+++ b/storage/perfschema/unittest/pfs_instr-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc
index bdb2648c2f3..7eb21a33bd7 100644
--- a/storage/perfschema/unittest/pfs_instr_class-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_instr_class-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_instr_class-t.cc b/storage/perfschema/unittest/pfs_instr_class-t.cc
index 0d8ec38525d..f1e246dc387 100644
--- a/storage/perfschema/unittest/pfs_instr_class-t.cc
+++ b/storage/perfschema/unittest/pfs_instr_class-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_misc-t.cc b/storage/perfschema/unittest/pfs_misc-t.cc
index c308cf4b82d..7d274c0820d 100644
--- a/storage/perfschema/unittest/pfs_misc-t.cc
+++ b/storage/perfschema/unittest/pfs_misc-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2015, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_server_stubs.cc b/storage/perfschema/unittest/pfs_server_stubs.cc
index 3c4b864d742..db1600faf9f 100644
--- a/storage/perfschema/unittest/pfs_server_stubs.cc
+++ b/storage/perfschema/unittest/pfs_server_stubs.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/unittest/pfs_timer-t.cc b/storage/perfschema/unittest/pfs_timer-t.cc
index 9ef111f531c..139454b8649 100644
--- a/storage/perfschema/unittest/pfs_timer-t.cc
+++ b/storage/perfschema/unittest/pfs_timer-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/pfs_user-oom-t.cc b/storage/perfschema/unittest/pfs_user-oom-t.cc
index 6e81df8d5e2..ca451f3e457 100644
--- a/storage/perfschema/unittest/pfs_user-oom-t.cc
+++ b/storage/perfschema/unittest/pfs_user-oom-t.cc
@@ -1,13 +1,20 @@
/* Copyright (c) 2011, 2017, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/stub_pfs_defaults.h b/storage/perfschema/unittest/stub_pfs_defaults.h
index 6b4ee3f0e15..951508733e2 100644
--- a/storage/perfschema/unittest/stub_pfs_defaults.h
+++ b/storage/perfschema/unittest/stub_pfs_defaults.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2010, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
diff --git a/storage/perfschema/unittest/stub_pfs_global.h b/storage/perfschema/unittest/stub_pfs_global.h
index a665ed39704..8a1f9216ba2 100644
--- a/storage/perfschema/unittest/stub_pfs_global.h
+++ b/storage/perfschema/unittest/stub_pfs_global.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/perfschema/unittest/stub_print_error.h b/storage/perfschema/unittest/stub_print_error.h
index 476a6c0e901..2cd2ad5b03c 100644
--- a/storage/perfschema/unittest/stub_print_error.h
+++ b/storage/perfschema/unittest/stub_print_error.h
@@ -1,13 +1,20 @@
/* Copyright (c) 2008, 2015, 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 Foundation; version 2 of the License.
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
+ GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc
index 6b105200c55..851ac35557b 100644
--- a/storage/spider/ha_spider.cc
+++ b/storage/spider/ha_spider.cc
@@ -2257,6 +2257,7 @@ int ha_spider::index_read_map_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -2264,6 +2265,11 @@ int ha_spider::index_read_map_internal(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -2285,11 +2291,15 @@ int ha_spider::index_read_map_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2324,6 +2334,8 @@ int ha_spider::index_read_map_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -2350,6 +2362,8 @@ int ha_spider::index_read_map_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -2748,6 +2762,7 @@ int ha_spider::index_read_last_map_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -2755,6 +2770,11 @@ int ha_spider::index_read_last_map_internal(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -2773,11 +2793,15 @@ int ha_spider::index_read_last_map_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2812,6 +2836,8 @@ int ha_spider::index_read_last_map_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -2838,6 +2864,8 @@ int ha_spider::index_read_last_map_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -3213,6 +3241,7 @@ int ha_spider::index_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -3221,6 +3250,11 @@ int ha_spider::index_first_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -3239,11 +3273,15 @@ int ha_spider::index_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -3278,6 +3316,8 @@ int ha_spider::index_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -3304,6 +3344,8 @@ int ha_spider::index_first_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -3596,6 +3638,7 @@ int ha_spider::index_last_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -3604,6 +3647,11 @@ int ha_spider::index_last_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -3622,11 +3670,15 @@ int ha_spider::index_last_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -3661,6 +3713,8 @@ int ha_spider::index_last_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -3687,6 +3741,8 @@ int ha_spider::index_last_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4039,6 +4095,7 @@ int ha_spider::read_range_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4046,6 +4103,11 @@ int ha_spider::read_range_first_internal(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -4064,11 +4126,15 @@ int ha_spider::read_range_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4103,6 +4169,8 @@ int ha_spider::read_range_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4129,6 +4197,8 @@ int ha_spider::read_range_first_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4665,6 +4735,7 @@ int ha_spider::read_multi_range_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4673,6 +4744,11 @@ int ha_spider::read_multi_range_first_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -4697,11 +4773,15 @@ int ha_spider::read_multi_range_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4737,6 +4817,8 @@ int ha_spider::read_multi_range_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4765,6 +4847,8 @@ int ha_spider::read_multi_range_first_internal(
if (!error_num)
{
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -5458,6 +5542,7 @@ int ha_spider::read_multi_range_first_internal(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -5466,6 +5551,11 @@ int ha_spider::read_multi_range_first_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -5491,11 +5581,15 @@ int ha_spider::read_multi_range_first_internal(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5537,6 +5631,8 @@ int ha_spider::read_multi_range_first_internal(
-1,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -5572,6 +5668,8 @@ int ha_spider::read_multi_range_first_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -5598,6 +5696,8 @@ int ha_spider::read_multi_range_first_internal(
break;
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -6105,6 +6205,7 @@ int ha_spider::read_multi_range_next(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -6113,6 +6214,11 @@ int ha_spider::read_multi_range_next(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -6137,11 +6243,15 @@ int ha_spider::read_multi_range_next(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6177,6 +6287,8 @@ int ha_spider::read_multi_range_next(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6205,6 +6317,8 @@ int ha_spider::read_multi_range_next(
if (!error_num)
{
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -6902,6 +7016,7 @@ int ha_spider::read_multi_range_next(
}
#endif
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -6910,6 +7025,11 @@ int ha_spider::read_multi_range_next(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -6935,11 +7055,15 @@ int ha_spider::read_multi_range_next(
} else {
#endif
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6981,6 +7105,8 @@ int ha_spider::read_multi_range_next(
-1,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7016,6 +7142,8 @@ int ha_spider::read_multi_range_next(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7042,6 +7170,8 @@ int ha_spider::read_multi_range_next(
break;
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -7519,6 +7649,7 @@ int ha_spider::rnd_next_internal(
sql_type = SPIDER_SQL_TYPE_HANDLER;
}
spider_db_handler *dbton_hdl = dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -7527,6 +7658,11 @@ int ha_spider::rnd_next_internal(
if ((error_num =
dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -7536,11 +7672,15 @@ int ha_spider::rnd_next_internal(
}
DBUG_PRINT("info",("spider sql_type=%lu", sql_type));
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn,
roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7575,6 +7715,8 @@ int ha_spider::rnd_next_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7601,6 +7743,8 @@ int ha_spider::rnd_next_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -8111,6 +8255,7 @@ int ha_spider::ft_read_internal(
uint dbton_id = share->use_sql_dbton_ids[roop_count];
spider_db_handler *dbton_hdl = dbton_handler[dbton_id];
SPIDER_CONN *conn = conns[roop_count];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_SELECT_SQL))
{
@@ -8120,6 +8265,12 @@ int ha_spider::ft_read_internal(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_SELECT_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_SELECT_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -8129,10 +8280,14 @@ int ha_spider::ft_read_internal(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(this, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -8166,6 +8321,8 @@ int ha_spider::ft_read_internal(
result_list.quick_mode,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -8192,6 +8349,8 @@ int ha_spider::ft_read_internal(
DBUG_RETURN(check_error_mode_eof(error_num));
}
connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -10453,9 +10612,12 @@ void ha_spider::bulk_req_exec()
if (conn->bulk_access_requests)
{
spider_bg_conn_wait(conn);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
/* currently only used for HS */
@@ -10473,6 +10635,8 @@ void ha_spider::bulk_req_exec()
conn->bulk_access_sended += conn->bulk_access_requests;
*/
conn->bulk_access_requests = 0;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -12140,6 +12304,7 @@ int ha_spider::drop_tmp_tables()
uint dbton_id = share->use_sql_dbton_ids[roop_count];
spider_db_handler *dbton_hdl = dbton_handler[dbton_id];
SPIDER_CONN *conn = conns[roop_count];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_TMP_SQL))
{
@@ -12149,6 +12314,12 @@ int ha_spider::drop_tmp_tables()
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_TMP_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_TMP_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -12158,10 +12329,14 @@ int ha_spider::drop_tmp_tables()
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_set_names(this, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -12198,6 +12373,8 @@ int ha_spider::drop_tmp_tables()
-1,
&need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
tmp_error_num = spider_db_errorno(conn);
@@ -12223,6 +12400,8 @@ int ha_spider::drop_tmp_tables()
}
error_num = tmp_error_num;
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
diff --git a/storage/spider/spd_conn.cc b/storage/spider/spd_conn.cc
index 99599bca1be..aef3d1df991 100644
--- a/storage/spider/spd_conn.cc
+++ b/storage/spider/spd_conn.cc
@@ -2390,6 +2390,7 @@ void *spider_bg_conn_action(
sql_type = SPIDER_SQL_TYPE_SELECT_HS;
}
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -2419,6 +2420,8 @@ void *spider_bg_conn_action(
if (!result_list->bgs_error)
{
conn->need_mon = &spider->need_mons[conn->link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
#ifdef HA_CAN_BULK_ACCESS
@@ -2496,6 +2499,8 @@ void *spider_bg_conn_action(
#ifdef HA_CAN_BULK_ACCESS
}
#endif
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -2506,11 +2511,14 @@ void *spider_bg_conn_action(
}
} else {
spider->connection_ids[conn->link_idx] = conn->connection_id;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = TRUE;
result_list->bgs_error =
spider_db_store_result(spider, conn->link_idx, result_list->table);
if ((result_list->bgs_error_with_message = thd->is_error()))
strmov(result_list->bgs_error_msg, spider_stmt_da_message(thd));
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = FALSE;
}
conn->bg_search = FALSE;
@@ -2574,12 +2582,26 @@ void *spider_bg_conn_action(
{
DBUG_PRINT("info",("spider bg exec sql start"));
spider = (ha_spider*) conn->bg_target;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[conn->link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
*conn->bg_error_num = spider_db_query_with_set_names(
conn->bg_sql_type,
spider,
conn,
conn->link_idx
);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
conn->bg_exec_sql = FALSE;
continue;
}
diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc
index efb5e6d8c8c..5e9e53d89ff 100644
--- a/storage/spider/spd_db_conn.cc
+++ b/storage/spider/spd_db_conn.cc
@@ -205,23 +205,14 @@ int spider_db_ping(
DBUG_PRINT("info", ("spider thd->query_id is %lld",
spider->trx->thd->query_id));
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (conn->server_lost || conn->queued_connect)
{
if ((error_num = spider_db_connect(spider->share, conn,
spider->conn_link_idx[link_idx])))
{
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
conn->server_lost = FALSE;
@@ -235,11 +226,7 @@ int spider_db_ping(
{
DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn));
conn->server_lost = TRUE;
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
if((error_num = conn->db_conn->ping()))
@@ -247,20 +234,12 @@ int spider_db_ping(
spider_db_disconnect(conn);
DBUG_PRINT("info", ("spider conn=%p SERVER_LOST", conn));
conn->server_lost = TRUE;
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
conn->ping_time = (time_t) time((time_t*) 0);
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(0);
}
@@ -300,6 +279,7 @@ int spider_db_conn_queue_action(
conn->queued_connect = FALSE;
}
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -548,7 +528,6 @@ int spider_db_before_query(
int *need_mon
) {
int error_num;
- bool tmp_mta_conn_mutex_lock_already;
DBUG_ENTER("spider_db_before_query");
DBUG_ASSERT(need_mon);
#ifndef WITHOUT_SPIDER_BG_SEARCH
@@ -556,25 +535,18 @@ int spider_db_before_query(
spider_bg_conn_break(conn, NULL);
#endif
conn->in_before_query = TRUE;
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = need_mon;
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if ((error_num = spider_db_conn_queue_action(conn)))
{
conn->in_before_query = FALSE;
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
if (conn->server_lost)
{
conn->in_before_query = FALSE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(CR_SERVER_GONE_ERROR);
}
DBUG_PRINT("info", ("spider conn[%p]->quick_target=%p",
@@ -601,6 +573,7 @@ int spider_db_before_query(
) {
conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
conn->in_before_query = FALSE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
@@ -616,6 +589,7 @@ int spider_db_before_query(
}
}
conn->in_before_query = FALSE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_RETURN(0);
}
@@ -628,6 +602,7 @@ int spider_db_query(
) {
int error_num;
DBUG_ENTER("spider_db_query");
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -670,6 +645,7 @@ int spider_db_errorno(
int error_num;
DBUG_ENTER("spider_db_errorno");
DBUG_ASSERT(conn->need_mon);
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -684,6 +660,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -705,6 +682,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -717,6 +695,7 @@ int spider_db_errorno(
conn->error_length = strlen(conn->error_str);
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -741,6 +720,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -761,6 +741,7 @@ int spider_db_errorno(
}
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -777,6 +758,7 @@ int spider_db_errorno(
conn->server_lost = TRUE;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -786,6 +768,7 @@ int spider_db_errorno(
*conn->need_mon = 0;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -808,6 +791,7 @@ int spider_db_errorno(
*conn->need_mon = ER_SPIDER_HS_NUM;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -816,6 +800,7 @@ int spider_db_errorno(
#endif
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -838,33 +823,25 @@ int spider_db_set_names_internal(
int all_link_idx,
int *need_mon
) {
- bool tmp_mta_conn_mutex_lock_already;
DBUG_ENTER("spider_db_set_names_internal");
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = need_mon;
- }
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if (
!conn->access_charset ||
share->access_charset->cset != conn->access_charset->cset
) {
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
spider_db_before_query(conn, need_mon) ||
conn->db_conn->set_character_set(share->access_charset->csname)
) {
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(spider_db_errorno(conn));
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
conn->access_charset = share->access_charset;
}
if (
@@ -879,13 +856,10 @@ int spider_db_set_names_internal(
) {
DBUG_PRINT("info",("spider all_link_idx=%d db=%s", all_link_idx,
share->tgt_dbs[all_link_idx]));
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
spider_db_before_query(conn, need_mon) ||
conn->db_conn->select_db(share->tgt_dbs[all_link_idx])
) {
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(spider_db_errorno(conn));
}
conn->default_database.length(0);
@@ -895,12 +869,6 @@ int spider_db_set_names_internal(
conn->default_database.q_append(share->tgt_dbs[all_link_idx],
share->tgt_dbs_lengths[all_link_idx] + 1);
conn->default_database.length(share->tgt_dbs_lengths[all_link_idx]);
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- }
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
@@ -929,19 +897,11 @@ int spider_db_query_with_set_names(
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_db_query_with_set_names");
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
-*/
- conn->need_mon = &spider->need_mons[link_idx];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
share->monitoring_kind[link_idx] &&
spider->need_mons[link_idx]
@@ -972,8 +932,6 @@ int spider_db_query_with_set_names(
-1,
&spider->need_mons[link_idx])
) {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
if (
share->monitoring_kind[link_idx] &&
@@ -997,10 +955,6 @@ int spider_db_query_with_set_names(
}
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
}
@@ -1014,15 +968,16 @@ int spider_db_query_for_bulk_update(
SPIDER_SHARE *share = spider->share;
DBUG_ENTER("spider_db_query_for_bulk_update");
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
-*/
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -1058,6 +1013,8 @@ int spider_db_query_for_bulk_update(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -1104,6 +1061,8 @@ int spider_db_query_for_bulk_update(
}
if (error_num > 0 && !conn->db_conn->is_dup_entry_error(error_num))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -1130,6 +1089,8 @@ int spider_db_query_for_bulk_update(
}
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -3639,6 +3600,7 @@ int spider_db_store_result(
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3655,6 +3617,7 @@ int spider_db_store_result(
) {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3686,6 +3649,7 @@ int spider_db_store_result(
) {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3729,6 +3693,7 @@ int spider_db_store_result(
) {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3768,6 +3733,7 @@ int spider_db_store_result(
{
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3796,6 +3762,7 @@ int spider_db_store_result(
#endif
if (!conn->mta_conn_mutex_unlock_later && !call_db_errorno)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3803,6 +3770,7 @@ int spider_db_store_result(
} else {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3846,6 +3814,7 @@ int spider_db_store_result(
result_list->limit_num -= current->prev->record_num;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3869,6 +3838,7 @@ int spider_db_store_result(
} else {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -3880,6 +3850,7 @@ int spider_db_store_result(
spider->quick_targets[link_idx] = spider;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4038,6 +4009,7 @@ int spider_db_store_result(
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4063,6 +4035,7 @@ int spider_db_store_result(
} else {
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4073,6 +4046,7 @@ int spider_db_store_result(
result_list->hs_has_result = TRUE;
if (!conn->mta_conn_mutex_unlock_later)
{
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -4158,15 +4132,15 @@ int spider_db_bulk_store_result(
error_num = spider_db_bulk_open_handler(spider, conn, link_idx);
if (!discard_result)
{
- bool tmp_mta_conn_mutex_unlock_later;
- tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_store_result(spider, link_idx,
spider->get_table())))
{
error_num = tmp_error_num;
}
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
+ conn->mta_conn_mutex_unlock_later = FALSE;
} else {
if (spider->connection_ids[link_idx] == conn->connection_id)
spider_db_discard_result(spider, link_idx, conn);
@@ -4376,10 +4350,14 @@ int spider_db_seek_next(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4415,6 +4393,8 @@ int spider_db_seek_next(
result_list->quick_mode,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4442,6 +4422,8 @@ int spider_db_seek_next(
DBUG_RETURN(error_num);
}
spider->connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4482,6 +4464,8 @@ int spider_db_seek_next(
}
} else {
spider->connection_ids[link_idx] = conn->connection_id;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_store_result(spider, link_idx, table)))
{
@@ -4608,6 +4592,7 @@ int spider_db_seek_last(
}
conn = spider->conns[roop_count];
spider_db_handler *dbton_handler = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4615,6 +4600,11 @@ int spider_db_seek_last(
}
if ((error_num = dbton_handler->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
@@ -4624,10 +4614,14 @@ int spider_db_seek_last(
}
DBUG_PRINT("info",("spider sql_type=%lu", sql_type));
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4662,6 +4656,8 @@ int spider_db_seek_last(
result_list->quick_mode,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4688,6 +4684,8 @@ int spider_db_seek_last(
DBUG_RETURN(error_num);
}
spider->connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -4808,6 +4806,7 @@ int spider_db_seek_last(
}
conn = spider->conns[roop_count];
spider_db_handler *dbton_handler = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -4815,6 +4814,11 @@ int spider_db_seek_last(
}
if ((error_num = dbton_handler->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
@@ -4824,10 +4828,14 @@ int spider_db_seek_last(
}
DBUG_PRINT("info",("spider sql_type=%lu", sql_type));
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -4862,6 +4870,8 @@ int spider_db_seek_last(
result_list->quick_mode,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -4888,6 +4898,8 @@ int spider_db_seek_last(
DBUG_RETURN(error_num);
}
spider->connection_ids[roop_count] = conn->connection_id;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (roop_count == link_ok)
@@ -5556,8 +5568,6 @@ int spider_db_bulk_insert(
#endif
SPIDER_SHARE *share = spider->share;
THD *thd = spider->trx->thd;
- bool mta_conn_mutex_lock_already_backup;
- bool mta_conn_mutex_unlock_later_backup;
DBUG_ENTER("spider_db_bulk_insert");
if (!bulk_end)
@@ -5612,61 +5622,50 @@ int spider_db_bulk_insert(
sql_type = SPIDER_SQL_TYPE_INSERT_SQL;
conn = spider->conns[roop_count2];
dbton_handler = spider->dbton_handler[conn->dbton_id];
- mta_conn_mutex_lock_already_backup =
- conn->mta_conn_mutex_lock_already;
- mta_conn_mutex_unlock_later_backup =
- conn->mta_conn_mutex_unlock_later;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
if ((error_num = dbton_handler->set_sql_for_exec(sql_type,
roop_count2)))
{
+ if (dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_handler->need_lock_before_set_sql_for_exec(sql_type))
{
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
} else {
sql_type = SPIDER_SQL_TYPE_INSERT_HS;
conn = spider->hs_w_conns[roop_count2];
dbton_handler = spider->dbton_handler[conn->dbton_id];
- mta_conn_mutex_lock_already_backup =
- conn->mta_conn_mutex_lock_already;
- mta_conn_mutex_unlock_later_backup =
- conn->mta_conn_mutex_unlock_later;
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
#endif
conn->need_mon = &spider->need_mons[roop_count2];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count2)))
{
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
share->monitoring_kind[roop_count2] &&
spider->need_mons[roop_count2]
@@ -5704,15 +5703,12 @@ int spider_db_bulk_insert(
{
conn->db_conn->set_dup_key_idx(spider, roop_count2);
}
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (
error_num != ER_DUP_ENTRY &&
error_num != ER_DUP_KEY &&
@@ -5738,8 +5734,10 @@ int spider_db_bulk_insert(
}
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later = mta_conn_mutex_unlock_later_backup;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind != SPIDER_CONN_KIND_MYSQL)
{
@@ -5775,11 +5773,8 @@ int spider_db_bulk_insert(
}
}
#endif
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (first_insert_link_idx == -1)
{
first_insert_link_idx = roop_count2;
@@ -5788,14 +5783,12 @@ int spider_db_bulk_insert(
}
conn = first_insert_conn;
- mta_conn_mutex_lock_already_backup = conn->mta_conn_mutex_lock_already;
- mta_conn_mutex_unlock_later_backup = conn->mta_conn_mutex_unlock_later;
- if (!mta_conn_mutex_lock_already_backup)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[first_insert_link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if (spider->sql_kinds & SPIDER_SQL_KIND_SQL)
@@ -5817,15 +5810,12 @@ int spider_db_bulk_insert(
else if ((error_num = dbton_handler->
show_last_insert_id(first_insert_link_idx, last_insert_id)))
{
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
table->next_number_field->set_notnull();
@@ -5835,25 +5825,21 @@ int spider_db_bulk_insert(
(error_num = table->next_number_field->store(
last_insert_id, TRUE))
) {
- conn->mta_conn_mutex_lock_already =
- mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later =
- mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
- conn->mta_conn_mutex_lock_already = mta_conn_mutex_lock_already_backup;
- conn->mta_conn_mutex_unlock_later = mta_conn_mutex_unlock_later_backup;
- if (!mta_conn_mutex_unlock_later_backup)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
spider->store_last_insert_id = 0;
#ifdef HA_CAN_BULK_ACCESS
}
@@ -5897,8 +5883,11 @@ int spider_db_bulk_bulk_insert(
conn = spider->hs_w_conns[roop_count2];
}
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_bulk_open_handler(spider, conn,
@@ -5906,6 +5895,8 @@ int spider_db_bulk_bulk_insert(
{
error_num = tmp_error_num;
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -5954,9 +5945,12 @@ int spider_db_bulk_bulk_insert(
}
conn = first_insert_conn;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[first_insert_link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if (table->next_number_field &&
@@ -5983,6 +5977,8 @@ int spider_db_bulk_bulk_insert(
error_num = tmp_error_num;
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6110,6 +6106,7 @@ int spider_db_bulk_update_size_limit(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
{
@@ -6119,6 +6116,12 @@ int spider_db_bulk_update_size_limit(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6129,7 +6132,11 @@ int spider_db_bulk_update_size_limit(
}
if ((error_num = spider_db_query_for_bulk_update(
spider, conn, roop_count, &dup_key_found)))
+ {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
+ }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
}
spider->reset_sql_sql(SPIDER_SQL_TYPE_BULK_UPDATE_SQL);
} else {
@@ -6195,6 +6202,7 @@ int spider_db_bulk_update_end(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
{
@@ -6204,14 +6212,14 @@ int spider_db_bulk_update_end(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
if (error_num == ER_SPIDER_COND_SKIP_NUM)
{
- if (dbton_hdl->need_lock_before_set_sql_for_exec(
- SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
continue;
}
DBUG_RETURN(error_num);
@@ -6224,7 +6232,11 @@ int spider_db_bulk_update_end(
}
if ((error_num = spider_db_query_for_bulk_update(
spider, conn, roop_count, dup_key_found)))
+ {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
goto error_query;
+ }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
}
}
if (error_num != HA_ERR_END_OF_FILE)
@@ -6249,6 +6261,7 @@ int spider_db_bulk_update_end(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
{
@@ -6258,6 +6271,12 @@ int spider_db_bulk_update_end(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_BULK_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_BULK_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6268,7 +6287,11 @@ int spider_db_bulk_update_end(
}
if ((error_num = spider_db_query_for_bulk_update(
spider, conn, roop_count, dup_key_found)))
+ {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
goto error_last_query;
+ }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
}
}
}
@@ -6336,6 +6359,7 @@ int spider_db_update(
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000
conn->ignore_dup_key = spider->ignore_dup_key;
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_UPDATE_SQL))
{
@@ -6345,6 +6369,12 @@ int spider_db_update(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_UPDATE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_UPDATE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6354,10 +6384,14 @@ int spider_db_update(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6392,6 +6426,8 @@ int spider_db_update(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6430,6 +6466,8 @@ int spider_db_update(
if ((error_num = dbton_hdl->append_insert_for_recovery(
SPIDER_SQL_TYPE_INSERT_SQL, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6444,6 +6482,8 @@ int spider_db_update(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6473,6 +6513,8 @@ int spider_db_update(
DBUG_RETURN(error_num);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6661,6 +6703,7 @@ int spider_db_direct_update(
}
#endif
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -6668,6 +6711,11 @@ int spider_db_direct_update(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -6683,10 +6731,14 @@ int spider_db_direct_update(
} else {
#endif
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6724,6 +6776,8 @@ int spider_db_direct_update(
) &&
(error_num != HA_ERR_FOUND_DUPP_KEY || !spider->ignore_dup_key)
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -6790,6 +6844,8 @@ int spider_db_direct_update(
{
error_num = spider_db_errorno(conn);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6798,11 +6854,13 @@ int spider_db_direct_update(
}
}
#endif
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
#ifdef HA_CAN_BULK_ACCESS
}
#endif
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -6847,8 +6905,11 @@ int spider_db_bulk_direct_update(
conn = spider->hs_w_conns[roop_count];
}
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((tmp_error_num = spider_db_bulk_open_handler(spider, conn,
@@ -6894,6 +6955,8 @@ int spider_db_bulk_direct_update(
{
error_num = spider_db_errorno(conn);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6902,6 +6965,8 @@ int spider_db_bulk_direct_update(
}
}
#endif
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -6958,6 +7023,7 @@ int spider_db_delete(
) {
conn = spider->conns[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL))
{
@@ -6967,6 +7033,12 @@ int spider_db_delete(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_DELETE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -6975,9 +7047,27 @@ int spider_db_delete(
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_query_with_set_names(
SPIDER_SQL_TYPE_DELETE_SQL, spider, conn, roop_count)))
+ {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
result_list->update_sqls[roop_count].length(0);
}
if ((error_num = spider->reset_sql_sql(SPIDER_SQL_TYPE_DELETE_SQL)))
@@ -7089,6 +7179,7 @@ int spider_db_direct_delete(
}
#endif
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
{
pthread_mutex_lock(&conn->mta_conn_mutex);
@@ -7096,6 +7187,11 @@ int spider_db_direct_delete(
}
if ((error_num = dbton_hdl->set_sql_for_exec(sql_type, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(sql_type))
@@ -7111,10 +7207,14 @@ int spider_db_direct_delete(
} else {
#endif
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7149,6 +7249,8 @@ int spider_db_direct_delete(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7174,6 +7276,8 @@ int spider_db_direct_delete(
}
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -7266,6 +7370,7 @@ int spider_db_delete_all_rows(
uint dbton_id = share->use_sql_dbton_ids[roop_count];
spider_db_handler *dbton_hdl = spider->dbton_handler[dbton_id];
conn = spider->conns[roop_count];
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
if (dbton_hdl->need_lock_before_set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL))
{
@@ -7275,6 +7380,12 @@ int spider_db_delete_all_rows(
if ((error_num = dbton_hdl->set_sql_for_exec(
SPIDER_SQL_TYPE_DELETE_SQL, roop_count)))
{
+ if (dbton_hdl->need_lock_before_set_sql_for_exec(
+ SPIDER_SQL_TYPE_DELETE_SQL))
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(error_num);
}
if (!dbton_hdl->need_lock_before_set_sql_for_exec(
@@ -7284,6 +7395,8 @@ int spider_db_delete_all_rows(
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
}
conn->need_mon = &spider->need_mons[roop_count];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, roop_count, spider->trx->thd,
@@ -7306,6 +7419,8 @@ int spider_db_delete_all_rows(
/* retry */
if ((error_num = spider_db_ping(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7334,6 +7449,8 @@ int spider_db_delete_all_rows(
}
if ((error_num = spider_db_set_names(spider, conn, roop_count)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7368,6 +7485,8 @@ int spider_db_delete_all_rows(
-1,
&spider->need_mons[roop_count])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -7394,6 +7513,8 @@ int spider_db_delete_all_rows(
DBUG_RETURN(error_num);
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -7421,6 +7542,8 @@ int spider_db_delete_all_rows(
DBUG_RETURN(error_num);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -8802,7 +8925,14 @@ int spider_db_udf_direct_sql(
c_thd->lex->sql_command = SQLCOM_INSERT;
#endif
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (
!(error_num = spider_db_udf_direct_sql_set_names(direct_sql, trx, conn)) &&
!(error_num = spider_db_udf_direct_sql_select_db(direct_sql, conn))
@@ -8825,9 +8955,6 @@ int spider_db_udf_direct_sql(
#endif
DBUG_RETURN(error_num);
}
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
}
#endif
spider_conn_set_timeout_from_direct_sql(conn, thd, direct_sql);
@@ -8846,8 +8973,6 @@ int spider_db_udf_direct_sql(
DBUG_PRINT("info",("spider conn=%p", conn));
if (!direct_sql->table_count)
roop_count = -1;
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
do {
if (roop_count == direct_sql->table_count)
{
@@ -9059,12 +9184,14 @@ int spider_db_udf_direct_sql(
if (roop_count >= 0)
roop_count++;
} while (status == 0);
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
if (need_trx_end && insert_start)
{
if (error_num)
@@ -9094,19 +9221,13 @@ int spider_db_udf_direct_sql_select_db(
SPIDER_CONN *conn
) {
int error_num, need_mon = 0;
- bool tmp_mta_conn_mutex_lock_already;
SPIDER_DB_CONN *db_conn = conn->db_conn;
DBUG_ENTER("spider_db_udf_direct_sql_select_db");
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (direct_sql->access_mode == 0)
{
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &need_mon;
- }
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (
!conn->default_database.length() ||
@@ -9115,8 +9236,6 @@ int spider_db_udf_direct_sql_select_db(
memcmp(direct_sql->tgt_default_db_name, conn->default_database.ptr(),
direct_sql->tgt_default_db_name_length)
) {
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
(
spider_db_before_query(conn, &need_mon) ||
@@ -9130,7 +9249,6 @@ int spider_db_udf_direct_sql_select_db(
)
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(error_num);
}
conn->default_database.length(0);
@@ -9140,12 +9258,6 @@ int spider_db_udf_direct_sql_select_db(
conn->default_database.q_append(direct_sql->tgt_default_db_name,
direct_sql->tgt_default_db_name_length + 1);
conn->default_database.length(direct_sql->tgt_default_db_name_length);
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- }
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
}
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
@@ -9159,25 +9271,17 @@ int spider_db_udf_direct_sql_set_names(
SPIDER_CONN *conn
) {
int error_num, need_mon = 0;
- bool tmp_mta_conn_mutex_lock_already;
DBUG_ENTER("spider_db_udf_direct_sql_set_names");
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (direct_sql->access_mode == 0)
{
#endif
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &need_mon;
- }
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
if (
!conn->access_charset ||
trx->udf_access_charset->cset != conn->access_charset->cset
) {
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
if (
(
spider_db_before_query(conn, &need_mon) ||
@@ -9192,17 +9296,10 @@ int spider_db_udf_direct_sql_set_names(
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
DBUG_RETURN(error_num);
}
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
conn->access_charset = trx->udf_access_charset;
}
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
}
#endif
@@ -9266,13 +9363,18 @@ int spider_db_udf_ping_table(
spider.conn_link_idx = &tmp_conn_link_idx;
spider.db_request_phase = &db_request_phase;
spider.db_request_id = &db_request_id;
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_ping(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9288,6 +9390,8 @@ int spider_db_udf_ping_table(
share->server_names[0]);
DBUG_RETURN(ER_CONNECT_TO_FOREIGN_DATA_SOURCE);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9331,13 +9435,18 @@ int spider_db_udf_ping_table(
my_error(error_num, MYF(0));
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9355,6 +9464,8 @@ int spider_db_udf_ping_table(
-1,
&need_mon)
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
@@ -9363,6 +9474,8 @@ int spider_db_udf_ping_table(
DBUG_PRINT("info",("spider error_num=%d", error_num));
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
spider_db_discard_result(&spider, 0, conn);
@@ -9548,13 +9661,18 @@ int spider_db_udf_ping_table_mon_next(
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_ping(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9565,6 +9683,8 @@ int spider_db_udf_ping_table_mon_next(
}
if ((error_num = spider_db_set_names(&spider, conn, 0)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9579,6 +9699,8 @@ int spider_db_udf_ping_table_mon_next(
-1,
&need_mon)
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
@@ -9591,13 +9713,25 @@ int spider_db_udf_ping_table_mon_next(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
+ {
DBUG_RETURN(error_num);
+ }
my_error(HA_ERR_OUT_OF_MEM, MYF(0));
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -9678,8 +9812,22 @@ int spider_db_udf_copy_tables(
spider_conn_clear_queue_at_commit(tmp_conn);
if (!tmp_conn->trx_start)
{
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
+ pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ tmp_conn->need_mon = &tmp_spider->need_mons[0];
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = TRUE;
+ tmp_conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_ping(tmp_spider, tmp_conn, 0))
{
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
tmp_spider->share->server_names[0]);
error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
@@ -9689,8 +9837,21 @@ int spider_db_udf_copy_tables(
(error_num = spider_db_set_names(tmp_spider, tmp_conn, 0)) ||
(error_num = spider_db_start_transaction(tmp_conn,
tmp_spider->need_mons))
- )
+ ) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_start_transaction;
+ }
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
}
}
} else {
@@ -9710,8 +9871,22 @@ int spider_db_udf_copy_tables(
{
tmp_spider = &spider[roop_count];
tmp_conn = tmp_spider->conns[0];
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
+ pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ tmp_conn->need_mon = &tmp_spider->need_mons[0];
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = TRUE;
+ tmp_conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_ping(tmp_spider, tmp_conn, 0))
{
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0),
tmp_spider->share->server_names[0]);
error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE;
@@ -9724,11 +9899,23 @@ int spider_db_udf_copy_tables(
(error_num = spider_db_lock_tables(tmp_spider, 0))
)
) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
tmp_conn->table_lock = 0;
if (error_num == HA_ERR_OUT_OF_MEM)
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
goto error_lock_tables;
}
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
tmp_conn->table_lock = 1;
}
}
@@ -9736,11 +9923,23 @@ int spider_db_udf_copy_tables(
tmp_conn = src_tbl_conn->conn;
spider_conn_set_timeout_from_share(tmp_conn, 0,
copy_tables->trx->thd, src_tbl_conn->share);
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
+ pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ tmp_conn->need_mon = &src_tbl_conn->need_mon;
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = TRUE;
+ tmp_conn->mta_conn_mutex_unlock_later = TRUE;
if (select_ct->exec_query(
tmp_conn,
-1,
&src_tbl_conn->need_mon)
) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(tmp_conn);
if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM)
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
@@ -9769,6 +9968,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
@@ -9784,6 +9987,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
@@ -9810,6 +10017,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
@@ -9827,6 +10038,10 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
error_num = ER_OUT_OF_RESOURCES;
@@ -9839,12 +10054,20 @@ int spider_db_udf_copy_tables(
my_error(ER_OUT_OF_RESOURCES, MYF(0), HA_ERR_OUT_OF_MEM);
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
goto error_db_query;
}
result->free_result();
delete result;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
for (dst_tbl_conn = copy_tables->table_conn[1]; dst_tbl_conn;
@@ -9865,6 +10088,12 @@ int spider_db_udf_copy_tables(
}
if (error_num)
{
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
if (error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM)
my_message(ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM,
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
@@ -9872,6 +10101,10 @@ int spider_db_udf_copy_tables(
}
error_num = HA_ERR_END_OF_FILE;
end_of_file = TRUE;
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
+ tmp_conn->mta_conn_mutex_lock_already = FALSE;
+ tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&tmp_conn->mta_conn_mutex);
}
@@ -9914,9 +10147,12 @@ int spider_db_udf_copy_tables(
{
tmp_conn = dst_tbl_conn->conn;
insert_ct = dst_tbl_conn->copy_table;
+ pthread_mutex_assert_not_owner(&tmp_conn->mta_conn_mutex);
pthread_mutex_lock(&tmp_conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
tmp_conn->need_mon = &dst_tbl_conn->need_mon;
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!tmp_conn->mta_conn_mutex_unlock_later);
tmp_conn->mta_conn_mutex_lock_already = TRUE;
tmp_conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(tmp_conn, 0,
@@ -9926,6 +10162,8 @@ int spider_db_udf_copy_tables(
-1,
&dst_tbl_conn->need_mon)
) {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
tmp_conn->mta_conn_mutex_lock_already = FALSE;
tmp_conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(tmp_conn);
@@ -9934,6 +10172,8 @@ int spider_db_udf_copy_tables(
ER_SPIDER_REMOTE_SERVER_GONE_AWAY_STR, MYF(0));
goto error_db_query;
} else {
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(tmp_conn->mta_conn_mutex_unlock_later);
tmp_conn->mta_conn_mutex_lock_already = FALSE;
tmp_conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&tmp_conn->mta_conn_mutex_file_pos);
@@ -10074,8 +10314,6 @@ int spider_db_open_handler(
int link_idx
) {
int error_num;
- bool tmp_mta_conn_mutex_lock_already;
- bool tmp_mta_conn_mutex_unlock_later;
SPIDER_SHARE *share = spider->share;
uint *handler_id_ptr =
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
@@ -10090,16 +10328,14 @@ int spider_db_open_handler(
;
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_db_open_handler");
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- }
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
- tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
conn->mta_conn_mutex_unlock_later = TRUE;
if (!spider->handler_opened(link_idx, conn->conn_kind))
*handler_id_ptr = conn->opened_handlers;
@@ -10148,11 +10384,6 @@ int spider_db_open_handler(
{
my_printf_error(ER_SPIDER_HS_NUM, ER_SPIDER_HS_STR, MYF(0),
conn->db_conn->get_errno(), conn->db_conn->get_error());
- if (!conn->mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
spider->need_mons[link_idx] = ER_SPIDER_HS_NUM;
error_num = ER_SPIDER_HS_NUM;
goto error;
@@ -10288,23 +10519,21 @@ int spider_db_open_handler(
}
DBUG_PRINT("info",("spider conn=%p", conn));
DBUG_PRINT("info",("spider opened_handlers=%u", conn->opened_handlers));
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
error:
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
@@ -10354,6 +10583,7 @@ int spider_db_bulk_open_handler(
}
bool tmp_mta_conn_mutex_unlock_later;
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
conn->mta_conn_mutex_unlock_later = TRUE;
SPIDER_DB_RESULT *result;
@@ -10392,24 +10622,19 @@ int spider_db_close_handler(
uint tgt_conn_kind
) {
int error_num;
- bool tmp_mta_conn_mutex_lock_already;
- bool tmp_mta_conn_mutex_unlock_later;
spider_db_handler *dbton_hdl = spider->dbton_handler[conn->dbton_id];
DBUG_ENTER("spider_db_close_handler");
DBUG_PRINT("info",("spider conn=%p", conn));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider->handler_opened(link_idx, tgt_conn_kind))
{
- if (!conn->mta_conn_mutex_lock_already)
- {
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- }
- DBUG_ASSERT(conn->mta_conn_mutex_file_pos.file_name);
- tmp_mta_conn_mutex_lock_already = conn->mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_lock_already = TRUE;
- tmp_mta_conn_mutex_unlock_later = conn->mta_conn_mutex_unlock_later;
- conn->mta_conn_mutex_unlock_later = TRUE;
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
if (conn->conn_kind == SPIDER_CONN_KIND_MYSQL)
{
@@ -10417,7 +10642,15 @@ int spider_db_close_handler(
dbton_hdl->reset_sql(SPIDER_SQL_TYPE_HANDLER);
if ((error_num = dbton_hdl->append_close_handler_part(
SPIDER_SQL_TYPE_HANDLER, link_idx)))
+ {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
+ }
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
spider->share);
@@ -10443,24 +10676,22 @@ int spider_db_close_handler(
goto error;
conn->opened_handlers--;
DBUG_PRINT("info",("spider opened_handlers=%u", conn->opened_handlers));
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
error:
- conn->mta_conn_mutex_lock_already = tmp_mta_conn_mutex_lock_already;
- conn->mta_conn_mutex_unlock_later = tmp_mta_conn_mutex_unlock_later;
- if (!tmp_mta_conn_mutex_unlock_later)
- {
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
@@ -10497,3 +10728,4 @@ bool spider_db_conn_is_network_error(
}
DBUG_RETURN(FALSE);
}
+
diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc
index cf1a07715fc..b3114adbc36 100644
--- a/storage/spider/spd_db_mysql.cc
+++ b/storage/spider/spd_db_mysql.cc
@@ -1844,10 +1844,6 @@ void spider_db_mysql::print_warnings(
if (!(db_conn->server_status & SERVER_MORE_RESULTS_EXISTS))
#endif
{
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
-*/
if (
spider_param_dry_access() ||
!mysql_real_query(db_conn, SPIDER_SQL_SHOW_WARNINGS_STR,
@@ -1865,18 +1861,10 @@ void spider_db_mysql::print_warnings(
{
if (res)
mysql_free_result(res);
-/*
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
-*/
DBUG_VOID_RETURN;
}
/* no record is ok */
}
-/*
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
-*/
num_fields = mysql_num_fields(res);
if (num_fields != 3)
{
@@ -1895,11 +1883,6 @@ void spider_db_mysql::print_warnings(
}
if (res)
mysql_free_result(res);
- } else {
-/*
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
-*/
}
}
}
@@ -2039,14 +2022,31 @@ int spider_db_mysql::consistent_snapshot(
) {
DBUG_ENTER("spider_db_mysql::consistent_snapshot");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_START_CONSISTENT_SNAPSHOT_STR,
SPIDER_SQL_START_CONSISTENT_SNAPSHOT_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2064,16 +2064,18 @@ int spider_db_mysql::start_transaction(
) {
DBUG_ENTER("spider_db_mysql::start_transaction");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if (spider_db_query(
conn,
SPIDER_SQL_START_TRANSACTION_STR,
SPIDER_SQL_START_TRANSACTION_LEN,
-1,
need_mon)
- )
+ ) {
DBUG_RETURN(spider_db_errorno(conn));
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(0);
}
@@ -2082,14 +2084,31 @@ int spider_db_mysql::commit(
) {
DBUG_ENTER("spider_db_mysql::commit");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_COMMIT_STR,
SPIDER_SQL_COMMIT_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2102,6 +2121,13 @@ int spider_db_mysql::rollback(
int error_num;
DBUG_ENTER("spider_db_mysql::rollback");
DBUG_PRINT("info",("spider this=%p", this));
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
@@ -2118,12 +2144,18 @@ int spider_db_mysql::rollback(
)
conn->thd->clear_error();
else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(error_num);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
@@ -2160,14 +2192,31 @@ int spider_db_mysql::xa_end(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_END_STR, SPIDER_SQL_XA_END_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2186,14 +2235,31 @@ int spider_db_mysql::xa_prepare(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_PREPARE_STR, SPIDER_SQL_XA_PREPARE_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2212,14 +2278,31 @@ int spider_db_mysql::xa_commit(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_COMMIT_STR, SPIDER_SQL_XA_COMMIT_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2238,14 +2321,31 @@ int spider_db_mysql::xa_rollback(
sql_str.length(0);
sql_str.q_append(SPIDER_SQL_XA_ROLLBACK_STR, SPIDER_SQL_XA_ROLLBACK_LEN);
spider_db_append_xid_str(&sql_str, xid);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -2267,50 +2367,118 @@ int spider_db_mysql::set_trx_isolation(
switch (trx_isolation)
{
case ISO_READ_UNCOMMITTED:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_READ_UNCOMMITTED_STR,
SPIDER_SQL_ISO_READ_UNCOMMITTED_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
case ISO_READ_COMMITTED:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_READ_COMMITTED_STR,
SPIDER_SQL_ISO_READ_COMMITTED_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
case ISO_REPEATABLE_READ:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_REPEATABLE_READ_STR,
SPIDER_SQL_ISO_REPEATABLE_READ_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
case ISO_SERIALIZABLE:
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_SERIALIZABLE_STR,
SPIDER_SQL_ISO_SERIALIZABLE_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
@@ -2335,25 +2503,59 @@ int spider_db_mysql::set_autocommit(
DBUG_PRINT("info",("spider this=%p", this));
if (autocommit)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_ON_STR,
SPIDER_SQL_AUTOCOMMIT_ON_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_OFF_STR,
SPIDER_SQL_AUTOCOMMIT_OFF_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -2375,25 +2577,59 @@ int spider_db_mysql::set_sql_log_off(
DBUG_PRINT("info",("spider this=%p", this));
if (sql_log_off)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_SQL_LOG_ON_STR,
SPIDER_SQL_SQL_LOG_ON_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_SQL_LOG_OFF_STR,
SPIDER_SQL_SQL_LOG_OFF_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -2424,14 +2660,31 @@ int spider_db_mysql::set_time_zone(
sql_str.q_append(SPIDER_SQL_TIME_ZONE_STR, SPIDER_SQL_TIME_ZONE_LEN);
sql_str.q_append(tz_str->ptr(), tz_str->length());
sql_str.q_append(SPIDER_SQL_VALUE_QUOTE_STR, SPIDER_SQL_VALUE_QUOTE_LEN);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
sql_str.ptr(),
sql_str.length(),
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -4959,6 +5212,14 @@ int spider_mysql_share::discover_table_structure(
) {
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (!conn->disable_reconnect)
{
ha_spider tmp_spider;
@@ -4971,14 +5232,15 @@ int spider_mysql_share::discover_table_structure(
if ((error_num = spider_db_ping(&tmp_spider, conn, 0)))
{
DBUG_PRINT("info",("spider spider_db_ping error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
continue;
}
}
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &need_mon;
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, roop_count, trx->thd,
spider_share);
if (
@@ -4995,6 +5257,8 @@ int spider_mysql_share::discover_table_structure(
)
) {
DBUG_PRINT("info",("spider spider_get_trx error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5014,6 +5278,8 @@ int spider_mysql_share::discover_table_structure(
if (error_num || (error_num = spider_db_errorno(conn)))
{
DBUG_PRINT("info",("spider column store error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5022,6 +5288,8 @@ int spider_mysql_share::discover_table_structure(
}
/* no record */
DBUG_PRINT("info",("spider column no record error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5034,6 +5302,8 @@ int spider_mysql_share::discover_table_structure(
DBUG_PRINT("info",("spider column fetch error"));
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5050,6 +5320,8 @@ int spider_mysql_share::discover_table_structure(
if (conn->db_conn->next_result())
{
DBUG_PRINT("info",("spider single result error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5062,6 +5334,8 @@ int spider_mysql_share::discover_table_structure(
if (error_num || (error_num = spider_db_errorno(conn)))
{
DBUG_PRINT("info",("spider index store error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5070,6 +5344,8 @@ int spider_mysql_share::discover_table_structure(
}
/* no record */
DBUG_PRINT("info",("spider index no record error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5082,6 +5358,8 @@ int spider_mysql_share::discover_table_structure(
DBUG_PRINT("info",("spider index fetch error"));
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5093,6 +5371,8 @@ int spider_mysql_share::discover_table_structure(
if (conn->db_conn->next_result())
{
DBUG_PRINT("info",("spider dual result error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5105,6 +5385,8 @@ int spider_mysql_share::discover_table_structure(
if (error_num || (error_num = spider_db_errorno(conn)))
{
DBUG_PRINT("info",("spider table store error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5113,6 +5395,8 @@ int spider_mysql_share::discover_table_structure(
}
/* no record */
DBUG_PRINT("info",("spider table no record error"));
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5125,6 +5409,8 @@ int spider_mysql_share::discover_table_structure(
DBUG_PRINT("info",("spider table fetch error"));
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5133,6 +5419,8 @@ int spider_mysql_share::discover_table_structure(
}
res->free_result();
delete res;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10273,9 +10561,12 @@ int spider_mysql_handler::show_table_status(
DBUG_PRINT("info",("spider sts_mode=%d", sts_mode));
if (sts_mode == 1)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10299,6 +10590,8 @@ int spider_mysql_handler::show_table_status(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10307,6 +10600,8 @@ int spider_mysql_handler::show_table_status(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10322,11 +10617,15 @@ int spider_mysql_handler::show_table_status(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10342,6 +10641,8 @@ int spider_mysql_handler::show_table_status(
request_key.next = NULL;
if (spider_param_dry_access())
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10350,9 +10651,17 @@ int spider_mysql_handler::show_table_status(
}
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
+ {
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
+ DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
DBUG_RETURN(error_num);
else {
my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM,
@@ -10363,6 +10672,8 @@ int spider_mysql_handler::show_table_status(
DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10405,9 +10716,12 @@ int spider_mysql_handler::show_table_status(
DBUG_RETURN(error_num);
}
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10431,6 +10745,8 @@ int spider_mysql_handler::show_table_status(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10439,6 +10755,8 @@ int spider_mysql_handler::show_table_status(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10454,11 +10772,15 @@ int spider_mysql_handler::show_table_status(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10474,6 +10796,8 @@ int spider_mysql_handler::show_table_status(
request_key.next = NULL;
if (spider_param_dry_access())
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10482,6 +10806,8 @@ int spider_mysql_handler::show_table_status(
}
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (error_num || (error_num = spider_db_errorno(conn)))
@@ -10489,6 +10815,8 @@ int spider_mysql_handler::show_table_status(
else
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10572,9 +10900,12 @@ int spider_mysql_handler::show_index(
DBUG_PRINT("info",("spider crd_mode=%d", crd_mode));
if (crd_mode == 1)
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10598,6 +10929,8 @@ int spider_mysql_handler::show_index(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10606,6 +10939,8 @@ int spider_mysql_handler::show_index(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10621,11 +10956,15 @@ int spider_mysql_handler::show_index(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10643,6 +10982,8 @@ int spider_mysql_handler::show_index(
{
if (error_num || (error_num = spider_db_errorno(conn)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10651,6 +10992,8 @@ int spider_mysql_handler::show_index(
}
/* no record is ok */
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10705,9 +11048,12 @@ int spider_mysql_handler::show_index(
DBUG_RETURN(error_num);
}
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10731,6 +11077,8 @@ int spider_mysql_handler::show_index(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10739,6 +11087,8 @@ int spider_mysql_handler::show_index(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10754,11 +11104,15 @@ int spider_mysql_handler::show_index(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10776,6 +11130,8 @@ int spider_mysql_handler::show_index(
{
if (error_num || (error_num = spider_db_errorno(conn)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10784,6 +11140,8 @@ int spider_mysql_handler::show_index(
}
/* no record is ok */
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10850,9 +11208,12 @@ int spider_mysql_handler::show_records(
SPIDER_SHARE *share = spider->share;
uint pos = spider->conn_link_idx[link_idx];
DBUG_ENTER("spider_mysql_handler::show_records");
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10876,6 +11237,8 @@ int spider_mysql_handler::show_records(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10885,6 +11248,8 @@ int spider_mysql_handler::show_records(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10901,12 +11266,16 @@ int spider_mysql_handler::show_records(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10923,18 +11292,29 @@ int spider_mysql_handler::show_records(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
{
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 6", error_num));
+ DBUG_RETURN(error_num);
} else {
- DBUG_PRINT("info", ("spider error_num=%d 6",
+ DBUG_PRINT("info", ("spider error_num=%d 7",
ER_QUERY_ON_FOREIGN_DATA_SOURCE));
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10984,9 +11364,12 @@ ha_rows spider_mysql_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -11012,6 +11395,8 @@ ha_rows spider_mysql_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11022,6 +11407,8 @@ ha_rows spider_mysql_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11040,6 +11427,8 @@ ha_rows spider_mysql_handler::explain_select(
error_num = spider_db_errorno(conn);
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11049,6 +11438,8 @@ ha_rows spider_mysql_handler::explain_select(
} else {
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11068,6 +11459,8 @@ ha_rows spider_mysql_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11075,6 +11468,8 @@ ha_rows spider_mysql_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
} else {
my_errno = ER_QUERY_ON_FOREIGN_DATA_SOURCE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11082,6 +11477,8 @@ ha_rows spider_mysql_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11114,13 +11511,18 @@ int spider_mysql_handler::lock_tables(
}
if (str->length())
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11136,10 +11538,14 @@ int spider_mysql_handler::lock_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11174,14 +11580,31 @@ int spider_mysql_handler::unlock_tables(
{
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
spider->share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
str->ptr(),
str->length(),
-1,
&spider->need_mons[link_idx])
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -11204,13 +11627,18 @@ int spider_mysql_handler::disable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11226,11 +11654,15 @@ int spider_mysql_handler::disable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11253,13 +11685,18 @@ int spider_mysql_handler::enable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11275,11 +11712,15 @@ int spider_mysql_handler::enable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11303,13 +11744,18 @@ int spider_mysql_handler::check_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11325,11 +11771,15 @@ int spider_mysql_handler::check_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11353,13 +11803,18 @@ int spider_mysql_handler::repair_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11375,11 +11830,15 @@ int spider_mysql_handler::repair_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11402,13 +11861,18 @@ int spider_mysql_handler::analyze_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11424,11 +11888,15 @@ int spider_mysql_handler::analyze_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11451,13 +11919,18 @@ int spider_mysql_handler::optimize_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11473,11 +11946,15 @@ int spider_mysql_handler::optimize_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11503,6 +11980,14 @@ int spider_mysql_handler::flush_tables(
}
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
str->ptr(),
@@ -11510,9 +11995,17 @@ int spider_mysql_handler::flush_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -11528,6 +12021,14 @@ int spider_mysql_handler::flush_logs(
DBUG_PRINT("info",("spider this=%p", this));
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_FLUSH_LOGS_STR,
@@ -11535,9 +12036,17 @@ int spider_mysql_handler::flush_logs(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
diff --git a/storage/spider/spd_db_oracle.cc b/storage/spider/spd_db_oracle.cc
index 4622f3254a1..dd81352bb5e 100644
--- a/storage/spider/spd_db_oracle.cc
+++ b/storage/spider/spd_db_oracle.cc
@@ -1780,16 +1780,18 @@ int spider_db_oracle::start_transaction(
}
DBUG_RETURN(set_trx_isolation(conn->trx_isolation, need_mon));
}
+ pthread_mutex_assert_owner(&conn->mta_conn_mutex);
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
if (spider_db_query(
conn,
SPIDER_SQL_START_TRANSACTION_STR,
SPIDER_SQL_START_TRANSACTION_LEN,
-1,
need_mon)
- )
+ ) {
DBUG_RETURN(spider_db_errorno(conn));
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
+ }
DBUG_RETURN(0);
}
@@ -1978,14 +1980,31 @@ int spider_db_oracle::set_trx_isolation(
DBUG_RETURN(exec_query(SPIDER_SQL_ISO_READ_COMMITTED_STR,
SPIDER_SQL_ISO_READ_COMMITTED_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_READ_COMMITTED_STR,
SPIDER_SQL_ISO_READ_COMMITTED_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
@@ -1996,14 +2015,31 @@ int spider_db_oracle::set_trx_isolation(
DBUG_RETURN(exec_query(SPIDER_SQL_ISO_SERIALIZABLE_STR,
SPIDER_SQL_ISO_SERIALIZABLE_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_ISO_SERIALIZABLE_STR,
SPIDER_SQL_ISO_SERIALIZABLE_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
break;
@@ -2033,14 +2069,31 @@ int spider_db_oracle::set_autocommit(
DBUG_RETURN(exec_query(SPIDER_SQL_AUTOCOMMIT_ON_STR,
SPIDER_SQL_AUTOCOMMIT_ON_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_ON_STR,
SPIDER_SQL_AUTOCOMMIT_ON_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
} else {
@@ -2049,14 +2102,31 @@ int spider_db_oracle::set_autocommit(
DBUG_RETURN(exec_query(SPIDER_SQL_AUTOCOMMIT_OFF_STR,
SPIDER_SQL_AUTOCOMMIT_OFF_LEN, -1));
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = need_mon;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_AUTOCOMMIT_OFF_STR,
SPIDER_SQL_AUTOCOMMIT_OFF_LEN,
-1,
need_mon)
- )
+ ) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
+ }
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
}
@@ -10390,112 +10460,6 @@ int spider_oracle_handler::show_table_status(
if (sts_mode == 1)
{
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (
- (error_num = spider_db_set_names(spider, conn, link_idx)) ||
- (
- spider_db_query(
- conn,
- oracle_share->show_table_status[0 + pos].ptr(),
- oracle_share->show_table_status[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx]) &&
- (error_num = spider_db_errorno(conn))
- )
- ) {
- if (
- error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
- !conn->disable_reconnect
- ) {
-*/
- /* retry */
-/*
- if ((error_num = spider_db_ping(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- if ((error_num = spider_db_set_names(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (spider_db_query(
- conn,
- oracle_share->show_table_status[0 + pos].ptr(),
- oracle_share->show_table_status[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx])
- ) {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- DBUG_RETURN(spider_db_errorno(conn));
- }
- } else {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- }
- st_spider_db_request_key request_key;
- request_key.spider_thread_id = spider->trx->spider_thread_id;
- request_key.query_id = spider->trx->thd->query_id;
- request_key.handler = spider;
- request_key.request_id = 1;
- request_key.next = NULL;
- if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
- DBUG_RETURN(error_num);
- else {
- my_printf_error(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM,
- ER_SPIDER_REMOTE_TABLE_NOT_FOUND_STR, MYF(0),
- oracle_share->db_names_str[spider->conn_link_idx[link_idx]].ptr(),
- oracle_share->table_names_str[spider->conn_link_idx[
- link_idx]].ptr());
- DBUG_RETURN(ER_SPIDER_REMOTE_TABLE_NOT_FOUND_NUM);
- }
- }
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- error_num = res->fetch_table_status(
- sts_mode,
- share->records,
- share->mean_rec_length,
- share->data_file_length,
- share->max_data_file_length,
- share->index_file_length,
- auto_increment_value,
- share->create_time,
- share->update_time,
- share->check_time
- );
- res->free_result();
- delete res;
- if (error_num)
- DBUG_RETURN(error_num);
-*/
if (!share->records)
share->records = 10000;
share->mean_rec_length = 65535;
@@ -10506,9 +10470,12 @@ int spider_oracle_handler::show_table_status(
share->update_time = (time_t) 0;
share->check_time = (time_t) 0;
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10532,6 +10499,8 @@ int spider_oracle_handler::show_table_status(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10540,6 +10509,8 @@ int spider_oracle_handler::show_table_status(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10555,11 +10526,15 @@ int spider_oracle_handler::show_table_status(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10575,6 +10550,8 @@ int spider_oracle_handler::show_table_status(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
if (error_num || (error_num = spider_db_errorno(conn)))
@@ -10582,6 +10559,8 @@ int spider_oracle_handler::show_table_status(
else
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10636,105 +10615,6 @@ int spider_oracle_handler::show_index(
DBUG_PRINT("info",("spider crd_mode=%d", crd_mode));
if (crd_mode == 1)
{
-/*
- pthread_mutex_lock(&conn->mta_conn_mutex);
- SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
- conn->need_mon = &spider->need_mons[link_idx];
- conn->mta_conn_mutex_lock_already = TRUE;
- conn->mta_conn_mutex_unlock_later = TRUE;
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (
- (error_num = spider_db_set_names(spider, conn, link_idx)) ||
- (
- spider_db_query(
- conn,
- oracle_share->show_index[0 + pos].ptr(),
- oracle_share->show_index[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx]) &&
- (error_num = spider_db_errorno(conn))
- )
- ) {
- if (
- error_num == ER_SPIDER_REMOTE_SERVER_GONE_AWAY_NUM &&
- !conn->disable_reconnect
- ) {
-*/
- /* retry */
-/*
- if ((error_num = spider_db_ping(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- if ((error_num = spider_db_set_names(spider, conn, link_idx)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
- share);
- if (spider_db_query(
- conn,
- oracle_share->show_index[0 + pos].ptr(),
- oracle_share->show_index[0 + pos].length(),
- -1,
- &spider->need_mons[link_idx])
- ) {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- DBUG_RETURN(spider_db_errorno(conn));
- }
- } else {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
- }
- st_spider_db_request_key request_key;
- request_key.spider_thread_id = spider->trx->spider_thread_id;
- request_key.query_id = spider->trx->thd->query_id;
- request_key.handler = spider;
- request_key.request_id = 1;
- request_key.next = NULL;
- if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
- {
- if (error_num || (error_num = spider_db_errorno(conn)))
- {
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- DBUG_RETURN(error_num);
- }
-*/
- /* no record is ok */
-/*
- }
- conn->mta_conn_mutex_lock_already = FALSE;
- conn->mta_conn_mutex_unlock_later = FALSE;
- SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
- pthread_mutex_unlock(&conn->mta_conn_mutex);
- if (res)
- {
- error_num = res->fetch_table_cardinality(
- crd_mode,
- table,
- share->cardinality,
- share->cardinality_upd,
- share->bitmap_size
- );
- }
-*/
for (roop_count = 0, tmp_cardinality = share->cardinality;
roop_count < (int) table->s->fields;
roop_count++, tmp_cardinality++)
@@ -10746,19 +10626,13 @@ int spider_oracle_handler::show_index(
*tmp_cardinality = 1;
}
}
-/*
- if (res)
- {
- res->free_result();
- delete res;
- }
- if (error_num)
- DBUG_RETURN(error_num);
-*/
} else {
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10782,6 +10656,8 @@ int spider_oracle_handler::show_index(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10790,6 +10666,8 @@ int spider_oracle_handler::show_index(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10805,11 +10683,15 @@ int spider_oracle_handler::show_index(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10827,6 +10709,8 @@ int spider_oracle_handler::show_index(
{
if (error_num || (error_num = spider_db_errorno(conn)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10835,6 +10719,8 @@ int spider_oracle_handler::show_index(
}
/* no record is ok */
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10880,9 +10766,12 @@ int spider_oracle_handler::show_records(
SPIDER_SHARE *share = spider->share;
uint pos = spider->conn_link_idx[link_idx];
DBUG_ENTER("spider_oracle_handler::show_records");
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -10906,6 +10795,8 @@ int spider_oracle_handler::show_records(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10915,6 +10806,8 @@ int spider_oracle_handler::show_records(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10931,12 +10824,16 @@ int spider_oracle_handler::show_records(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10953,18 +10850,29 @@ int spider_oracle_handler::show_records(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
{
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
DBUG_RETURN(error_num);
+ }
+ else if (error_num || (error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 6", error_num));
+ DBUG_RETURN(error_num);
} else {
- DBUG_PRINT("info", ("spider error_num=%d 6",
+ DBUG_PRINT("info", ("spider error_num=%d 7",
ER_QUERY_ON_FOREIGN_DATA_SOURCE));
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -10997,9 +10905,12 @@ int spider_oracle_handler::show_autoinc(
if (!oracle_share->show_autoinc)
DBUG_RETURN(0);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -11023,6 +10934,8 @@ int spider_oracle_handler::show_autoinc(
/* retry */
if ((error_num = spider_db_ping(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11032,6 +10945,8 @@ int spider_oracle_handler::show_autoinc(
}
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11048,12 +10963,16 @@ int spider_oracle_handler::show_autoinc(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_PRINT("info", ("spider error_num=%d 3", error_num));
DBUG_RETURN(spider_db_errorno(conn));
}
} else {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11070,18 +10989,29 @@ int spider_oracle_handler::show_autoinc(
request_key.next = NULL;
if (!(res = conn->db_conn->store_result(NULL, &request_key, &error_num)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
- if (error_num || (error_num = spider_db_errorno(conn)))
+ if (error_num)
{
+ SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_PRINT("info", ("spider error_num=%d 5", error_num));
DBUG_RETURN(error_num);
+ }
+ else if ((error_num = spider_db_errorno(conn)))
+ {
+ DBUG_PRINT("info", ("spider error_num=%d 6", error_num));
+ DBUG_RETURN(error_num);
} else {
- DBUG_PRINT("info", ("spider error_num=%d 6",
+ DBUG_PRINT("info", ("spider error_num=%d 7",
ER_QUERY_ON_FOREIGN_DATA_SOURCE));
DBUG_RETURN(ER_QUERY_ON_FOREIGN_DATA_SOURCE);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11191,9 +11121,12 @@ ha_rows spider_oracle_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
@@ -11219,6 +11152,8 @@ ha_rows spider_oracle_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11229,6 +11164,8 @@ ha_rows spider_oracle_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11247,6 +11184,8 @@ ha_rows spider_oracle_handler::explain_select(
error_num = spider_db_errorno(conn);
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11256,6 +11195,8 @@ ha_rows spider_oracle_handler::explain_select(
} else {
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11275,6 +11216,8 @@ ha_rows spider_oracle_handler::explain_select(
{
if (spider->check_error_mode(error_num))
my_errno = error_num;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11282,6 +11225,8 @@ ha_rows spider_oracle_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
} else {
my_errno = ER_QUERY_ON_FOREIGN_DATA_SOURCE;
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11289,6 +11234,8 @@ ha_rows spider_oracle_handler::explain_select(
DBUG_RETURN(HA_POS_ERROR);
}
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11322,13 +11269,18 @@ int spider_oracle_handler::lock_tables(
}
if (str->length())
{
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11344,10 +11296,14 @@ int spider_oracle_handler::lock_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
DBUG_RETURN(spider_db_errorno(conn));
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11393,13 +11349,18 @@ int spider_oracle_handler::disable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11415,11 +11376,15 @@ int spider_oracle_handler::disable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11442,13 +11407,18 @@ int spider_oracle_handler::enable_keys(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11464,11 +11434,15 @@ int spider_oracle_handler::enable_keys(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11492,13 +11466,18 @@ int spider_oracle_handler::check_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11514,11 +11493,15 @@ int spider_oracle_handler::check_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11542,13 +11525,18 @@ int spider_oracle_handler::repair_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11564,11 +11552,15 @@ int spider_oracle_handler::repair_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11591,13 +11583,18 @@ int spider_oracle_handler::analyze_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11613,11 +11610,15 @@ int spider_oracle_handler::analyze_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11640,13 +11641,18 @@ int spider_oracle_handler::optimize_table(
{
DBUG_RETURN(error_num);
}
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_set_names(spider, conn, link_idx)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11662,11 +11668,15 @@ int spider_oracle_handler::optimize_table(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -11692,6 +11702,14 @@ int spider_oracle_handler::flush_tables(
}
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
str->ptr(),
@@ -11699,9 +11717,17 @@ int spider_oracle_handler::flush_tables(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
@@ -11717,6 +11743,14 @@ int spider_oracle_handler::flush_logs(
DBUG_PRINT("info",("spider this=%p", this));
spider_conn_set_timeout_from_share(conn, link_idx, spider->trx->thd,
share);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
+ pthread_mutex_lock(&conn->mta_conn_mutex);
+ SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
+ conn->need_mon = &spider->need_mons[link_idx];
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = TRUE;
+ conn->mta_conn_mutex_unlock_later = TRUE;
if (spider_db_query(
conn,
SPIDER_SQL_FLUSH_LOGS_STR,
@@ -11724,9 +11758,17 @@ int spider_oracle_handler::flush_logs(
-1,
&spider->need_mons[link_idx])
) {
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
error_num = spider_db_errorno(conn);
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
+ conn->mta_conn_mutex_lock_already = FALSE;
+ conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
pthread_mutex_unlock(&conn->mta_conn_mutex);
DBUG_RETURN(0);
diff --git a/storage/spider/spd_include.h b/storage/spider/spd_include.h
index 472bcea298e..accb875bfd9 100644
--- a/storage/spider/spd_include.h
+++ b/storage/spider/spd_include.h
@@ -17,6 +17,8 @@
#define SPIDER_HEX_VERSION 0x0302
#if MYSQL_VERSION_ID < 50500
+#define pthread_mutex_assert_owner(A)
+#define pthread_mutex_assert_not_owner(A)
#else
#define my_free(A,B) my_free(A)
#ifdef pthread_mutex_t
@@ -39,6 +41,8 @@
#undef pthread_mutex_destroy
#endif
#define pthread_mutex_destroy mysql_mutex_destroy
+#define pthread_mutex_assert_owner(A) mysql_mutex_assert_owner(A)
+#define pthread_mutex_assert_not_owner(A) mysql_mutex_assert_not_owner(A)
#ifdef pthread_cond_t
#undef pthread_cond_t
#endif
diff --git a/storage/spider/spd_table.cc b/storage/spider/spd_table.cc
index 9726afdd66e..48f7dc135e8 100644
--- a/storage/spider/spd_table.cc
+++ b/storage/spider/spd_table.cc
@@ -5809,13 +5809,18 @@ int spider_open_all_tables(
}
conn->error_mode &= spider_param_error_read_mode(thd, 0);
conn->error_mode &= spider_param_error_write_mode(thd, 0);
+ pthread_mutex_assert_not_owner(&conn->mta_conn_mutex);
pthread_mutex_lock(&conn->mta_conn_mutex);
SPIDER_SET_FILE_POS(&conn->mta_conn_mutex_file_pos);
conn->need_mon = &mon_val;
+ DBUG_ASSERT(!conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(!conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = TRUE;
conn->mta_conn_mutex_unlock_later = TRUE;
if ((error_num = spider_db_before_query(conn, &mon_val)))
{
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
@@ -5828,6 +5833,8 @@ int spider_open_all_tables(
free_root(&mem_root, MYF(0));
DBUG_RETURN(error_num);
}
+ DBUG_ASSERT(conn->mta_conn_mutex_lock_already);
+ DBUG_ASSERT(conn->mta_conn_mutex_unlock_later);
conn->mta_conn_mutex_lock_already = FALSE;
conn->mta_conn_mutex_unlock_later = FALSE;
SPIDER_CLEAR_FILE_POS(&conn->mta_conn_mutex_file_pos);
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index 618d257be29..d52b1a31998 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -1,4 +1,4 @@
-SET(TOKUDB_VERSION 5.6.41-84.1)
+SET(TOKUDB_VERSION 5.6.49-89.0)
# PerconaFT only supports x86-64 and cmake-2.8.9+
IF(CMAKE_VERSION VERSION_LESS "2.8.9")
MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
@@ -94,6 +94,7 @@ IF(DEFINED TOKUDB_NOPATCH_CONFIG)
ADD_DEFINITIONS("-DTOKUDB_NOPATCH_CONFIG=${TOKUDB_NOPATCH_CONFIG}")
ENDIF()
+MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-missing-format-attribute)
MY_CHECK_AND_SET_COMPILER_FLAG(-Wno-missing-field-initializers)
IF (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/PerconaFT/")
diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake
index 2f04a33558a..88210868eda 100644
--- a/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake
+++ b/storage/tokudb/PerconaFT/cmake_modules/TokuFeatureDetection.cmake
@@ -134,4 +134,4 @@ static __thread int tlsvar = 0;
int main(void) { return tlsvar; }" HAVE_GNU_TLS)
## set TOKUDB_REVISION
-set(CMAKE_TOKUDB_REVISION 0 CACHE INTEGER "Revision of tokudb.")
+set(CMAKE_TOKUDB_REVISION 0 CACHE STRING "Revision of tokudb.")
diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
index 8f65895cc9c..924e24c8f2e 100644
--- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
+++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake
@@ -47,20 +47,18 @@ include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
## adds a compiler flag if the compiler supports it
-macro(set_cflags_if_supported)
+macro(prepend_cflags_if_supported)
foreach(flag ${ARGN})
MY_CHECK_AND_SET_COMPILER_FLAG(${flag})
endforeach(flag)
-endmacro(set_cflags_if_supported)
+endmacro(prepend_cflags_if_supported)
if (NOT DEFINED MYSQL_PROJECT_NAME_DOCSTRING)
set (OPTIONAL_CFLAGS "${OPTIONAL_CFLAGS} -Wmissing-format-attribute")
endif()
## disable some warnings
-## missing-format-attribute causes warnings in some MySQL include files
-## if the library is built as a part of TokuDB MySQL storage engine
-set_cflags_if_supported(
+prepend_cflags_if_supported(
-Wno-missing-field-initializers
-Wstrict-null-sentinel
-Winit-self
@@ -77,7 +75,6 @@ set_cflags_if_supported(
-fno-exceptions
-Wno-error=nonnull-compare
)
-## set_cflags_if_supported_named("-Weffc++" -Weffcpp)
if (CMAKE_CXX_FLAGS MATCHES -fno-implicit-templates)
# must append this because mysql sets -fno-implicit-templates and we need to override it
@@ -89,24 +86,18 @@ endif()
## Clang has stricter POD checks. So, only enable this warning on our other builds (Linux + GCC)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES Clang)
- set_cflags_if_supported(
+ prepend_cflags_if_supported(
-Wpacked
)
endif ()
option (PROFILING "Allow profiling and debug" ON)
if (PROFILING)
- set_cflags_if_supported(
+ prepend_cflags_if_supported(
-fno-omit-frame-pointer
)
endif ()
-## this hits with optimized builds somewhere in ftleaf_split, we don't
-## know why but we don't think it's a big deal
-set_cflags_if_supported(
- -Wno-error=strict-overflow
- )
-
# new flag sets in MySQL 8.0 seem to explicitly disable this
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
@@ -144,7 +135,7 @@ else ()
endif ()
## set warnings
-set_cflags_if_supported(
+prepend_cflags_if_supported(
-Wextra
-Wbad-function-cast
-Wno-missing-noreturn
@@ -167,12 +158,12 @@ set_cflags_if_supported(
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang)
# Disabling -Wcast-align with clang. TODO: fix casting and re-enable it, someday.
- set_cflags_if_supported(-Wcast-align)
+ prepend_cflags_if_supported(-Wcast-align)
endif ()
-## always want these in debug builds
-set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror ${CMAKE_C_FLAGS_DEBUG}")
-set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror ${CMAKE_CXX_FLAGS_DEBUG}")
+## never want these
+set(CMAKE_C_FLAGS "-Wno-error ${CMAKE_C_FLAGS}")
+set(CMAKE_CXX_FLAGS "-Wno-error ${CMAKE_CXX_FLAGS}")
# pick language dialect
set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")
diff --git a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
index d97d8762252..8e9856b4060 100644
--- a/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
+++ b/storage/tokudb/PerconaFT/ft/cachetable/cachetable.cc
@@ -224,6 +224,9 @@ uint32_t toku_get_checkpoint_period_unlocked (CACHETABLE ct) {
}
void toku_set_cleaner_period (CACHETABLE ct, uint32_t new_period) {
+ if(force_recovery) {
+ return;
+ }
ct->cl.set_period(new_period);
}
@@ -3025,9 +3028,12 @@ int toku_cleaner_thread (void *cleaner_v) {
//
ENSURE_POD(cleaner);
+extern uint force_recovery;
+
int cleaner::init(uint32_t _cleaner_iterations, pair_list* _pl, CACHETABLE _ct) {
// default is no cleaner, for now
m_cleaner_cron_init = false;
+ if (force_recovery) return 0;
int r = toku_minicron_setup(&m_cleaner_cron, 0, toku_cleaner_thread, this);
if (r == 0) {
m_cleaner_cron_init = true;
diff --git a/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc b/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc
index 35ba864b9ea..ab9802e88b0 100644
--- a/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-cachetable-wrappers.cc
@@ -72,7 +72,7 @@ cachetable_put_empty_node_with_dep_nodes(
enum cachetable_dirty dependent_dirty_bits[num_dependent_nodes];
for (uint32_t i = 0; i < num_dependent_nodes; i++) {
dependent_pairs[i] = dependent_nodes[i]->ct_pair;
- dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty;
+ dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty();
}
toku_cachetable_put_with_dep_pairs(
@@ -252,7 +252,7 @@ toku_pin_ftnode_for_query(
// written out, it would have to be dirtied. That
// requires a write lock, and a write lock requires you to
// resolve checkpointing.
- if (!node->dirty) {
+ if (!node->dirty()) {
toku_ft_bn_update_max_msn(node, max_msn_in_path, bfe->child_to_read);
}
}
@@ -279,7 +279,7 @@ toku_pin_ftnode_with_dep_nodes(
enum cachetable_dirty dependent_dirty_bits[num_dependent_nodes];
for (uint32_t i = 0; i < num_dependent_nodes; i++) {
dependent_pairs[i] = dependent_nodes[i]->ct_pair;
- dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty;
+ dependent_dirty_bits[i] = (enum cachetable_dirty) dependent_nodes[i]->dirty();
}
int r = toku_cachetable_get_and_pin_with_dep_pairs(
@@ -332,7 +332,7 @@ cleanup:
void toku_unpin_ftnode(FT ft, FTNODE node) {
int r = toku_cachetable_unpin(ft->cf,
node->ct_pair,
- static_cast<enum cachetable_dirty>(node->dirty),
+ static_cast<enum cachetable_dirty>(node->dirty()),
make_ftnode_pair_attr(node));
invariant_zero(r);
}
@@ -343,7 +343,7 @@ toku_unpin_ftnode_read_only(FT ft, FTNODE node)
int r = toku_cachetable_unpin(
ft->cf,
node->ct_pair,
- (enum cachetable_dirty) node->dirty,
+ (enum cachetable_dirty) node->dirty(),
make_invalid_pair_attr()
);
assert(r==0);
diff --git a/storage/tokudb/PerconaFT/ft/ft-flusher.cc b/storage/tokudb/PerconaFT/ft/ft-flusher.cc
index e6452f60cfc..8e687d4ae58 100644
--- a/storage/tokudb/PerconaFT/ft/ft-flusher.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-flusher.cc
@@ -138,7 +138,7 @@ maybe_destroy_child_blbs(FTNODE node, FTNODE child, FT ft)
// up to date.
if (child->n_children > 1 &&
child->height == 0 &&
- !child->dirty) {
+ !child->dirty()) {
for (int i = 0; i < child->n_children; ++i) {
if (BP_STATE(child, i) == PT_AVAIL &&
node->max_msn_applied_to_node_on_disk.msn < BLB_MAX_MSN_APPLIED(child, i).msn)
@@ -479,7 +479,7 @@ handle_split_of_child(
}
)
- node->dirty = 1;
+ node->set_dirty();
XREALLOC_N(node->n_children+1, node->bp);
// Slide the children over.
@@ -661,8 +661,8 @@ static void ftnode_finalize_split(FTNODE node, FTNODE B, MSN max_msn_applied_to_
// The new node in the split inherits the oldest known reference xid
B->oldest_referenced_xid_known = node->oldest_referenced_xid_known;
- node->dirty = 1;
- B->dirty = 1;
+ node->set_dirty();
+ B->set_dirty();
}
void
@@ -1002,8 +1002,8 @@ flush_this_child(
paranoid_invariant(child->blocknum.b!=0);
// VERIFY_NODE does not work off client thread as of now
//VERIFY_NODE(t, child);
- node->dirty = 1;
- child->dirty = 1;
+ node->set_dirty();
+ child->set_dirty();
BP_WORKDONE(node, childnum) = 0; // this buffer is drained, no work has been done by its contents
NONLEAF_CHILDINFO bnc = BNC(node, childnum);
@@ -1033,8 +1033,8 @@ merge_leaf_nodes(FTNODE a, FTNODE b)
// TODO(leif): this is no longer the way in_memory_stats is
// maintained. verify that it's ok to move this just before the unpin
// and then do that.
- a->dirty = 1;
- b->dirty = 1;
+ a->set_dirty();
+ b->set_dirty();
bn_data* a_last_bd = BLB_DATA(a, a->n_children-1);
// this bool states if the last basement node in a has any items or not
@@ -1166,8 +1166,8 @@ maybe_merge_pinned_nonleaf_nodes(
a->n_children = new_n_children;
b->n_children = 0;
- a->dirty = 1;
- b->dirty = 1;
+ a->set_dirty();
+ b->set_dirty();
*did_merge = true;
*did_rebalance = false;
@@ -1210,7 +1210,7 @@ maybe_merge_pinned_nodes(
toku_ftnode_assert_fully_in_memory(parent);
toku_ftnode_assert_fully_in_memory(a);
toku_ftnode_assert_fully_in_memory(b);
- parent->dirty = 1; // just to make sure
+ parent->set_dirty(); // just to make sure
{
MSN msna = a->max_msn_applied_to_node_on_disk;
MSN msnb = b->max_msn_applied_to_node_on_disk;
@@ -1334,8 +1334,8 @@ ft_merge_child(
}
paranoid_invariant(BP_BLOCKNUM(node, childnuma).b == childa->blocknum.b);
- childa->dirty = 1; // just to make sure
- childb->dirty = 1; // just to make sure
+ childa->set_dirty(); // just to make sure
+ childb->set_dirty(); // just to make sure
} else {
// flow will be inaccurate for a while, oh well. the children
// are leaves in this case so it's not a huge deal (we're
@@ -1344,7 +1344,7 @@ ft_merge_child(
// If we didn't merge the nodes, then we need the correct pivot.
invariant_notnull(splitk.data);
node->pivotkeys.replace_at(&splitk, childnuma);
- node->dirty = 1;
+ node->set_dirty();
}
toku_destroy_dbt(&splitk);
}
@@ -1368,7 +1368,7 @@ ft_merge_child(
call_flusher_thread_callback(ft_flush_aflter_merge);
// unlock the parent
- paranoid_invariant(node->dirty);
+ paranoid_invariant(node->dirty());
toku_unpin_ftnode(ft, node);
}
else {
@@ -1376,7 +1376,7 @@ ft_merge_child(
call_flusher_thread_callback(ft_flush_aflter_rebalance);
// unlock the parent
- paranoid_invariant(node->dirty);
+ paranoid_invariant(node->dirty());
toku_unpin_ftnode(ft, node);
toku_unpin_ftnode(ft, childb);
}
@@ -1438,9 +1438,9 @@ void toku_ft_flush_some_child(FT ft, FTNODE parent, struct flusher_advice *fa)
// only do the following work if there is a flush to perform
if (toku_bnc_n_entries(BNC(parent, childnum)) > 0 || parent->height == 1) {
- if (!parent->dirty) {
+ if (!parent->dirty()) {
dirtied++;
- parent->dirty = 1;
+ parent->set_dirty();
}
// detach buffer
BP_WORKDONE(parent, childnum) = 0; // this buffer is drained, no work has been done by its contents
@@ -1485,9 +1485,9 @@ void toku_ft_flush_some_child(FT ft, FTNODE parent, struct flusher_advice *fa)
// in the buffer to flush, and as a result, flushing is not necessary
// and bnc is NULL
if (bnc != NULL) {
- if (!child->dirty) {
+ if (!child->dirty()) {
dirtied++;
- child->dirty = 1;
+ child->set_dirty();
}
// do the actual flush
toku_bnc_flush_to_child(
@@ -1786,7 +1786,7 @@ static void flush_node_fun(void *fe_v)
// read them back in, or just do the regular partial fetch. If we
// don't, that means fe->node is a parent, so we need to do this anyway.
bring_node_fully_into_memory(fe->node,fe->ft);
- fe->node->dirty = 1;
+ fe->node->set_dirty();
struct flusher_advice fa;
struct flush_status_update_extra fste;
@@ -1892,7 +1892,7 @@ void toku_ft_flush_node_on_background_thread(FT ft, FTNODE parent)
//
// can detach buffer and unpin root here
//
- parent->dirty = 1;
+ parent->set_dirty();
BP_WORKDONE(parent, childnum) = 0; // this buffer is drained, no work has been done by its contents
NONLEAF_CHILDINFO bnc = BNC(parent, childnum);
NONLEAF_CHILDINFO new_bnc = toku_create_empty_nl();
diff --git a/storage/tokudb/PerconaFT/ft/ft-internal.h b/storage/tokudb/PerconaFT/ft/ft-internal.h
index eec591d1744..130d3c302aa 100644
--- a/storage/tokudb/PerconaFT/ft/ft-internal.h
+++ b/storage/tokudb/PerconaFT/ft/ft-internal.h
@@ -76,11 +76,30 @@ enum ft_type {
FT_CHECKPOINT_INPROGRESS
};
+extern "C" {
+extern uint force_recovery;
+}
+
+extern int writing_rollback;
+
// The ft_header is not managed by the cachetable. Instead, it hangs off the cachefile as userdata.
struct ft_header {
enum ft_type type;
- int dirty;
+ int dirty_;
+
+ void set_dirty() {
+ if(force_recovery) assert(writing_rollback);
+ dirty_ = 1;
+ }
+
+ void clear_dirty() {
+ dirty_ = 0;
+ }
+
+ bool dirty() {
+ return dirty_;
+ }
// Free-running counter incremented once per checkpoint (toggling LSB).
// LSB indicates which header location is used on disk so this
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.cc b/storage/tokudb/PerconaFT/ft/ft-ops.cc
index 6d39b08fe02..d2e92768dde 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.cc
@@ -655,7 +655,7 @@ void toku_ftnode_clone_callback(void *value_data,
node->layout_version_read_from_disk;
cloned_node->build_id = node->build_id;
cloned_node->height = node->height;
- cloned_node->dirty = node->dirty;
+ cloned_node->dirty_ = node->dirty_;
cloned_node->fullhash = node->fullhash;
cloned_node->n_children = node->n_children;
@@ -671,8 +671,8 @@ void toku_ftnode_clone_callback(void *value_data,
toku_ftnode_clone_partitions(node, cloned_node);
// clear dirty bit
- node->dirty = 0;
- cloned_node->dirty = 0;
+ node->clear_dirty();
+ cloned_node->clear_dirty();
node->layout_version_read_from_disk = FT_LAYOUT_VERSION;
// set new pair attr if necessary
if (node->height == 0) {
@@ -741,7 +741,7 @@ void toku_ftnode_flush_callback(CACHEFILE UU(cachefile),
// persisted, we need undo the logical row count adjustments as
// they may occur again in the future if/when the node is
// re-read from disk for another query or change.
- if (!ftnode->dirty && !write_me) {
+ if (!ftnode->dirty() && !write_me) {
int64_t lrc_delta = 0;
for (int i = 0; i < ftnode->n_children; i++) {
if (BP_STATE(ftnode, i) == PT_AVAIL) {
@@ -846,8 +846,8 @@ int toku_ftnode_fetch_callback(CACHEFILE UU(cachefile),
if (r == 0) {
*sizep = make_ftnode_pair_attr(*node);
(*node)->ct_pair = p;
- *dirtyp = (*node)->dirty; // deserialize could mark the node as dirty
- // (presumably for upgrade)
+ *dirtyp = (*node)->dirty(); // deserialize could mark the node as dirty
+ // (presumably for upgrade)
}
return r;
}
@@ -869,7 +869,7 @@ void toku_ftnode_pe_est_callback(
paranoid_invariant(ftnode_pv != NULL);
long bytes_to_free = 0;
FTNODE node = static_cast<FTNODE>(ftnode_pv);
- if (node->dirty || node->height == 0 ||
+ if (node->dirty() || node->height == 0 ||
node->layout_version_read_from_disk < FT_FIRST_LAYOUT_VERSION_WITH_BASEMENT_NODES) {
*bytes_freed_estimate = 0;
*cost = PE_CHEAP;
@@ -946,7 +946,7 @@ int toku_ftnode_pe_callback(void *ftnode_pv,
void *pointers_to_free[node->n_children * 2];
// Don't partially evict dirty nodes
- if (node->dirty) {
+ if (node->dirty()) {
goto exit;
}
// Don't partially evict nodes whose partitions can't be read back
@@ -1399,7 +1399,7 @@ ft_init_new_root(FT ft, FTNODE oldroot, FTNODE *newrootp)
MSN msna = oldroot->max_msn_applied_to_node_on_disk;
newroot->max_msn_applied_to_node_on_disk = msna;
BP_STATE(newroot,0) = PT_AVAIL;
- newroot->dirty = 1;
+ newroot->set_dirty();
// Set the first child to have the new blocknum,
// and then swap newroot with oldroot. The new root
@@ -1487,7 +1487,7 @@ static void inject_message_in_locked_node(
// mark the node as dirty.
// enforcing invariant here.
//
- paranoid_invariant(node->dirty != 0);
+ paranoid_invariant(node->dirty() != 0);
// update some status variables
if (node->height != 0) {
@@ -1847,7 +1847,7 @@ static void push_something_in_subtree(
}
}
- if (next_loc != NEITHER_EXTREME || child->dirty || toku_bnc_should_promote(ft, bnc)) {
+ if (next_loc != NEITHER_EXTREME || child->dirty() || toku_bnc_should_promote(ft, bnc)) {
push_something_in_subtree(ft, child, -1, msg, flow_deltas, gc_info, depth + 1, next_loc, false);
toku_sync_fetch_and_add(&bnc->flow[0], flow_deltas[0]);
// The recursive call unpinned the child, but
@@ -2802,9 +2802,9 @@ static int ft_create_file(FT_HANDLE UU(ft_handle), const char *fname, int *fdp)
}
// open a file for use by the ft. if the file does not exist, error
-static int ft_open_file(const char *fname, int *fdp) {
+static int ft_open_file(const char *fname, int *fdp, bool rw) {
int fd;
- fd = ft_open_maybe_direct(fname, O_RDWR | O_BINARY, file_mode);
+ fd = ft_open_maybe_direct(fname, (rw ? O_RDWR : O_RDONLY) | O_BINARY, file_mode);
if (fd==-1) {
return get_error_errno();
}
@@ -2955,7 +2955,7 @@ toku_ft_handle_inherit_options(FT_HANDLE t, FT ft) {
// The checkpointed version (checkpoint_lsn) of the dictionary must be no later than max_acceptable_lsn .
// Requires: The multi-operation client lock must be held to prevent a checkpoint from occuring.
static int
-ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn, FILENUM use_filenum, DICTIONARY_ID use_dictionary_id, LSN max_acceptable_lsn) {
+ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn, FILENUM use_filenum, DICTIONARY_ID use_dictionary_id, LSN max_acceptable_lsn, bool open_rw = true) {
int r;
bool txn_created = false;
char *fname_in_cwd = NULL;
@@ -2977,7 +2977,7 @@ ft_handle_open(FT_HANDLE ft_h, const char *fname_in_env, int is_create, int only
fname_in_cwd = toku_cachetable_get_fname_in_cwd(cachetable, fname_in_env);
{
int fd = -1;
- r = ft_open_file(fname_in_cwd, &fd);
+ r = ft_open_file(fname_in_cwd, &fd, open_rw);
if (reserved_filenum.fileid == FILENUM_NONE.fileid) {
reserved_filenum = toku_cachetable_reserve_filenum(cachetable);
}
@@ -3123,15 +3123,15 @@ toku_ft_handle_open_recovery(FT_HANDLE t, const char *fname_in_env, int is_creat
// Open an ft in normal use. The FILENUM and dict_id are assigned by the ft_handle_open() function.
// Requires: The multi-operation client lock must be held to prevent a checkpoint from occuring.
int
-toku_ft_handle_open(FT_HANDLE t, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn) {
+toku_ft_handle_open(FT_HANDLE t, const char *fname_in_env, int is_create, int only_create, CACHETABLE cachetable, TOKUTXN txn, bool open_rw) {
int r;
- r = ft_handle_open(t, fname_in_env, is_create, only_create, cachetable, txn, FILENUM_NONE, DICTIONARY_ID_NONE, MAX_LSN);
+ r = ft_handle_open(t, fname_in_env, is_create, only_create, cachetable, txn, FILENUM_NONE, DICTIONARY_ID_NONE, MAX_LSN, open_rw);
return r;
}
// clone an ft handle. the cloned handle has a new dict_id but refers to the same fractal tree
int
-toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn) {
+toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn, bool open_rw) {
FT_HANDLE result_ft_handle;
toku_ft_handle_create(&result_ft_handle);
@@ -3146,7 +3146,7 @@ toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN t
CACHEFILE cf = ft_handle->ft->cf;
CACHETABLE ct = toku_cachefile_get_cachetable(cf);
const char *fname_in_env = toku_cachefile_fname_in_env(cf);
- int r = toku_ft_handle_open(result_ft_handle, fname_in_env, false, false, ct, txn);
+ int r = toku_ft_handle_open(result_ft_handle, fname_in_env, false, false, ct, txn, open_rw);
if (r != 0) {
toku_ft_handle_close(result_ft_handle);
result_ft_handle = NULL;
@@ -3547,7 +3547,7 @@ unlock_ftnode_fun (void *v) {
int r = toku_cachetable_unpin_ct_prelocked_no_flush(
ft_handle->ft->cf,
node->ct_pair,
- (enum cachetable_dirty) node->dirty,
+ (enum cachetable_dirty) node->dirty(),
x->msgs_applied ? make_ftnode_pair_attr(node) : make_invalid_pair_attr()
);
assert_zero(r);
@@ -4969,6 +4969,14 @@ static void toku_pfs_keys_destroy(void) {
}
int toku_ft_layer_init(void) {
+ static bool ft_layer_init_started = false;
+
+ if(ft_layer_init_started) {
+ return 0;
+ }
+
+ ft_layer_init_started = true;
+
int r = 0;
// Portability must be initialized first
@@ -4999,6 +5007,14 @@ exit:
}
void toku_ft_layer_destroy(void) {
+ static bool ft_layer_destroy_started = false;
+
+ if(ft_layer_destroy_started) {
+ return;
+ }
+
+ ft_layer_destroy_started = true;
+
toku_mutex_destroy(&ft_open_close_lock);
toku_ft_serialize_layer_destroy();
toku_checkpoint_destroy();
diff --git a/storage/tokudb/PerconaFT/ft/ft-ops.h b/storage/tokudb/PerconaFT/ft/ft-ops.h
index df8ffe287df..7b6d0634c37 100644
--- a/storage/tokudb/PerconaFT/ft/ft-ops.h
+++ b/storage/tokudb/PerconaFT/ft/ft-ops.h
@@ -125,12 +125,12 @@ typedef int (*ft_update_func)(DB *db, const DBT *key, const DBT *old_val, const
void toku_ft_set_update(FT_HANDLE ft_h, ft_update_func update_fun);
int toku_ft_handle_open(FT_HANDLE, const char *fname_in_env,
- int is_create, int only_create, CACHETABLE ct, TOKUTXN txn) __attribute__ ((warn_unused_result));
+ int is_create, int only_create, CACHETABLE ct, TOKUTXN txn, bool open_rw=true) __attribute__ ((warn_unused_result));
int toku_ft_handle_open_recovery(FT_HANDLE, const char *fname_in_env, int is_create, int only_create, CACHETABLE ct, TOKUTXN txn,
FILENUM use_filenum, LSN max_acceptable_lsn) __attribute__ ((warn_unused_result));
// clone an ft handle. the cloned handle has a new dict_id but refers to the same fractal tree
-int toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn);
+int toku_ft_handle_clone(FT_HANDLE *cloned_ft_handle, FT_HANDLE ft_handle, TOKUTXN txn, bool open_rw=true);
// close an ft handle during normal operation. the underlying ft may or may not close,
// depending if there are still references. an lsn for this close will come from the logger.
diff --git a/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc b/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc
index e31d80772d5..3b5501b66d3 100644
--- a/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-recount-rows.cc
@@ -98,7 +98,7 @@ int toku_ft_recount_rows(FT_HANDLE ft,
if (rre._cancelled == false) {
// update ft count
toku_unsafe_set(&ft->ft->in_memory_logical_rows, rre._keys);
- ft->ft->h->dirty = 1;
+ ft->ft->h->set_dirty();
ret = 0;
}
diff --git a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
index 930fb3013d2..8338a0777eb 100644
--- a/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-test-helpers.cc
@@ -258,7 +258,7 @@ int toku_testsetup_insert_to_nonleaf (FT_HANDLE ft_handle, BLOCKNUM blocknum, en
// is directly queueing something in a FIFO instead of
// using ft APIs.
node->max_msn_applied_to_node_on_disk = msn;
- node->dirty = 1;
+ node->set_dirty();
// Also hack max_msn_in_ft
ft_handle->ft->h->max_msn_in_ft = msn;
diff --git a/storage/tokudb/PerconaFT/ft/ft-verify.cc b/storage/tokudb/PerconaFT/ft/ft-verify.cc
index a2835f730eb..3819799c32f 100644
--- a/storage/tokudb/PerconaFT/ft/ft-verify.cc
+++ b/storage/tokudb/PerconaFT/ft/ft-verify.cc
@@ -511,7 +511,7 @@ toku_verify_ft_with_progress (FT_HANDLE ft_handle, int (*progress_callback)(void
if (r == 0) {
toku_ft_lock(ft_handle->ft);
ft_handle->ft->h->time_of_last_verification = time(NULL);
- ft_handle->ft->h->dirty = 1;
+ ft_handle->ft->h->set_dirty();
toku_ft_unlock(ft_handle->ft);
}
return r;
diff --git a/storage/tokudb/PerconaFT/ft/ft.cc b/storage/tokudb/PerconaFT/ft/ft.cc
index 454bf11794f..5c9f27bf5ad 100644
--- a/storage/tokudb/PerconaFT/ft/ft.cc
+++ b/storage/tokudb/PerconaFT/ft/ft.cc
@@ -60,7 +60,7 @@ void toku_reset_root_xid_that_created(FT ft, TXNID new_root_xid_that_created) {
// (see cooperative use of dirty bit in ft_begin_checkpoint())
toku_ft_lock(ft);
ft->h->root_xid_that_created = new_root_xid_that_created;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -146,7 +146,7 @@ static void ft_begin_checkpoint (LSN checkpoint_lsn, void *header_v) {
assert(ft->h->type == FT_CURRENT);
assert(ft->checkpoint_header == NULL);
ft_copy_for_checkpoint_unlocked(ft, checkpoint_lsn);
- ft->h->dirty = 0; // this is only place this bit is cleared (in currentheader)
+ ft->h->clear_dirty(); // this is only place this bit is cleared (in currentheader)
ft->blocktable.note_start_checkpoint_unlocked();
toku_ft_unlock (ft);
}
@@ -185,7 +185,7 @@ static void ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
FT_HEADER ch = ft->checkpoint_header;
assert(ch);
assert(ch->type == FT_CHECKPOINT_INPROGRESS);
- if (ch->dirty) { // this is only place this bit is tested (in checkpoint_header)
+ if (ch->dirty()) { // this is only place this bit is tested (in checkpoint_header)
TOKULOGGER logger = toku_cachefile_logger(cf);
if (logger) {
toku_logger_fsync_if_lsn_not_fsynced(logger, ch->checkpoint_lsn);
@@ -200,7 +200,7 @@ static void ft_checkpoint (CACHEFILE cf, int fd, void *header_v) {
// write translation and header to disk (or at least to OS internal buffer)
toku_serialize_ft_to(fd, ch, &ft->blocktable, ft->cf);
- ch->dirty = 0; // this is only place this bit is cleared (in checkpoint_header)
+ ch->clear_dirty(); // this is only place this bit is cleared (in checkpoint_header)
// fsync the cachefile
toku_cachefile_fsync(cf);
@@ -254,7 +254,7 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
toku_log_fclose(
logger,
&lsn,
- ft->h->dirty,
+ ft->h->dirty(),
bs,
toku_cachefile_filenum(cachefile)); // flush the log on
// close (if new header
@@ -265,7 +265,7 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
}
}
}
- if (ft->h->dirty) { // this is the only place this bit is tested (in currentheader)
+ if (ft->h->dirty()) { // this is the only place this bit is tested (in currentheader)
bool do_checkpoint = true;
if (logger && logger->rollback_cachefile == cachefile) {
do_checkpoint = false;
@@ -274,7 +274,7 @@ static void ft_close(CACHEFILE cachefile, int fd, void *header_v, bool oplsn_val
ft_begin_checkpoint(lsn, header_v);
ft_checkpoint(cachefile, fd, ft);
ft_end_checkpoint(cachefile, fd, header_v);
- assert(!ft->h->dirty); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
+ assert(!ft->h->dirty()); // dirty bit should be cleared by begin_checkpoint and never set again (because we're closing the dictionary)
}
}
}
@@ -370,7 +370,7 @@ ft_header_create(FT_OPTIONS options, BLOCKNUM root_blocknum, TXNID root_xid_that
uint64_t now = (uint64_t) time(NULL);
struct ft_header h = {
.type = FT_CURRENT,
- .dirty = 0,
+ .dirty_ = 0,
.checkpoint_count = 0,
.checkpoint_lsn = ZERO_LSN,
.layout_version = FT_LAYOUT_VERSION,
@@ -521,7 +521,7 @@ toku_ft_note_hot_begin(FT_HANDLE ft_handle) {
toku_ft_lock(ft);
ft->h->time_of_last_optimize_begin = now;
ft->h->count_of_optimize_in_progress++;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -545,7 +545,7 @@ toku_ft_note_hot_complete(FT_HANDLE ft_handle, bool success, MSN msn_at_start_of
if (ft->h->count_of_optimize_in_progress == ft->h->count_of_optimize_in_progress_read_from_disk)
ft->h->count_of_optimize_in_progress = 0;
}
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -958,7 +958,7 @@ void toku_ft_remove_reference(
void toku_ft_set_nodesize(FT ft, unsigned int nodesize) {
toku_ft_lock(ft);
ft->h->nodesize = nodesize;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -971,7 +971,7 @@ void toku_ft_get_nodesize(FT ft, unsigned int *nodesize) {
void toku_ft_set_basementnodesize(FT ft, unsigned int basementnodesize) {
toku_ft_lock(ft);
ft->h->basementnodesize = basementnodesize;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -984,7 +984,7 @@ void toku_ft_get_basementnodesize(FT ft, unsigned int *basementnodesize) {
void toku_ft_set_compression_method(FT ft, enum toku_compression_method method) {
toku_ft_lock(ft);
ft->h->compression_method = method;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
@@ -997,7 +997,7 @@ void toku_ft_get_compression_method(FT ft, enum toku_compression_method *methodp
void toku_ft_set_fanout(FT ft, unsigned int fanout) {
toku_ft_lock(ft);
ft->h->fanout = fanout;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
toku_ft_unlock(ft);
}
diff --git a/storage/tokudb/PerconaFT/ft/ft.h b/storage/tokudb/PerconaFT/ft/ft.h
index ff0b63b2b12..5c6caead978 100644
--- a/storage/tokudb/PerconaFT/ft/ft.h
+++ b/storage/tokudb/PerconaFT/ft/ft.h
@@ -184,11 +184,11 @@ void tokuft_update_product_name_strings(void);
extern char toku_product_name[TOKU_MAX_PRODUCT_NAME_LENGTH];
struct toku_product_name_strings_struct {
- char db_version[sizeof(toku_product_name) + sizeof("1.2.3 build ") + 256];
- char environmentdictionary[sizeof(toku_product_name) + sizeof(".environment")];
- char fileopsdirectory[sizeof(toku_product_name) + sizeof(".directory")];
- char single_process_lock[sizeof(toku_product_name) + sizeof("___lock_dont_delete_me")];
- char rollback_cachefile[sizeof(toku_product_name) + sizeof(".rollback")];
+ char db_version[sizeof(toku_product_name) + sizeof("1.2.3 build ") + 256 + 1];
+ char environmentdictionary[sizeof(toku_product_name) + sizeof(".environment") + 1];
+ char fileopsdirectory[sizeof(toku_product_name) + sizeof(".directory") + 1];
+ char single_process_lock[sizeof(toku_product_name) + sizeof("___lock_dont_delete_me") + 1];
+ char rollback_cachefile[sizeof(toku_product_name) + sizeof(".rollback") + 1];
};
extern struct toku_product_name_strings_struct toku_product_name_strings;
diff --git a/storage/tokudb/PerconaFT/ft/logger/logger.cc b/storage/tokudb/PerconaFT/ft/logger/logger.cc
index ddbbdcb25ab..1267900bc0a 100644
--- a/storage/tokudb/PerconaFT/ft/logger/logger.cc
+++ b/storage/tokudb/PerconaFT/ft/logger/logger.cc
@@ -49,6 +49,11 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "util/status.h"
+int writing_rollback = 0;
+extern "C" {
+ uint force_recovery = 0;
+}
+
static const int log_format_version = TOKU_LOG_VERSION;
toku_instr_key *result_output_condition_lock_mutex_key;
@@ -231,6 +236,7 @@ void toku_logger_initialize_rollback_cache(TOKULOGGER logger, FT ft) {
}
int toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool create) {
+ writing_rollback++;
assert(logger->is_open);
assert(!logger->rollback_cachefile);
@@ -250,6 +256,7 @@ int toku_logger_open_rollback(TOKULOGGER logger, CACHETABLE cachetable, bool cre
} else {
toku_ft_handle_close(ft_handle);
}
+ writing_rollback--;
return r;
}
@@ -267,20 +274,20 @@ void toku_logger_close_rollback_check_empty(TOKULOGGER logger, bool clean_shutdo
FT CAST_FROM_VOIDP(ft, toku_cachefile_get_userdata(cf));
if (clean_shutdown) {
//Verify it is safe to close it.
- assert(!ft->h->dirty); //Must not be dirty.
+ assert(!ft->h->dirty()); //Must not be dirty.
ft->blocktable.free_unused_blocknums(ft->h->root_blocknum);
// Must have no data blocks (rollback logs or otherwise).
ft->blocktable.verify_no_data_blocks_except_root(ft->h->root_blocknum);
- assert(!ft->h->dirty);
+ assert(!ft->h->dirty());
} else {
- ft->h->dirty = 0;
+ ft->h->clear_dirty();
}
ft_to_close = toku_ft_get_only_existing_ft_handle(ft);
if (clean_shutdown) {
bool is_empty;
is_empty = toku_ft_is_empty_fast(ft_to_close);
assert(is_empty);
- assert(!ft->h->dirty); // it should not have been dirtied by the toku_ft_is_empty test.
+ assert(!ft->h->dirty()); // it should not have been dirtied by the toku_ft_is_empty test.
}
}
diff --git a/storage/tokudb/PerconaFT/ft/node.cc b/storage/tokudb/PerconaFT/ft/node.cc
index 27943496fbf..39a76c8615e 100644
--- a/storage/tokudb/PerconaFT/ft/node.cc
+++ b/storage/tokudb/PerconaFT/ft/node.cc
@@ -77,7 +77,7 @@ void toku_initialize_empty_ftnode(FTNODE n, BLOCKNUM blocknum, int height, int n
}
}
}
- n->dirty = 1; // special case exception, it's okay to mark as dirty because the basements are empty
+ n->set_dirty(); // special case exception, it's okay to mark as dirty because the basements are empty
toku_ft_status_note_ftnode(height, true);
}
@@ -153,7 +153,7 @@ void toku_ftnode_clone_partitions(FTNODE node, FTNODE cloned_node) {
void toku_evict_bn_from_memory(FTNODE node, int childnum, FT ft) {
// free the basement node
- assert(!node->dirty);
+ assert(!node->dirty());
BASEMENTNODE bn = BLB(node, childnum);
toku_ft_decrease_stats(&ft->in_memory_stats, bn->stat64_delta);
toku_ft_adjust_logical_row_count(ft, -BLB_LRD(node, childnum));
@@ -595,7 +595,7 @@ toku_apply_ancestors_messages_to_node (
oldest_referenced_xid_for_simple_gc,
node->oldest_referenced_xid_known,
true);
- if (!node->dirty && child_to_read >= 0) {
+ if (!node->dirty() && child_to_read >= 0) {
paranoid_invariant(BP_STATE(node, child_to_read) == PT_AVAIL);
apply_ancestors_messages_to_bn(
t,
@@ -712,7 +712,7 @@ bool toku_ft_leaf_needs_ancestors_messages(
paranoid_invariant(node->height == 0);
bool needs_ancestors_messages = false;
// child_to_read may be -1 in test cases
- if (!node->dirty && child_to_read >= 0) {
+ if (!node->dirty() && child_to_read >= 0) {
paranoid_invariant(BP_STATE(node, child_to_read) == PT_AVAIL);
needs_ancestors_messages = bn_needs_ancestors_messages(
ft,
@@ -745,7 +745,7 @@ cleanup:
void toku_ft_bn_update_max_msn(FTNODE node, MSN max_msn_applied, int child_to_read) {
invariant(node->height == 0);
- if (!node->dirty && child_to_read >= 0) {
+ if (!node->dirty() && child_to_read >= 0) {
paranoid_invariant(BP_STATE(node, child_to_read) == PT_AVAIL);
BASEMENTNODE bn = BLB(node, child_to_read);
if (max_msn_applied.msn > bn->max_msn_applied.msn) {
@@ -832,7 +832,7 @@ struct rebalance_array_info {
void toku_ftnode_leaf_rebalance(FTNODE node, unsigned int basementnodesize) {
assert(node->height == 0);
- assert(node->dirty);
+ assert(node->dirty());
uint32_t num_orig_basements = node->n_children;
// Count number of leaf entries in this leaf (num_le).
@@ -1141,7 +1141,7 @@ void toku_ft_nonleaf_append_child(FTNODE node, FTNODE child, const DBT *pivotkey
invariant(childnum > 0);
node->pivotkeys.insert_at(pivotkey, childnum - 1);
}
- node->dirty = 1;
+ node->set_dirty();
}
void
@@ -1744,7 +1744,7 @@ static void ft_append_msg_to_child_buffer(const toku::comparator &cmp, FTNODE no
int childnum, const ft_msg &msg, bool is_fresh) {
paranoid_invariant(BP_STATE(node,childnum) == PT_AVAIL);
bnc_insert_msg(BNC(node, childnum), msg, is_fresh, cmp);
- node->dirty = 1;
+ node->set_dirty();
}
// This is only exported for tests.
@@ -2089,7 +2089,7 @@ void toku_ft_leaf_apply_msg(
// be reapplied later), we mark the node as dirty and
// take the opportunity to update node->max_msn_applied_to_node_on_disk.
//
- node->dirty = 1;
+ node->set_dirty();
//
// we cannot blindly update node->max_msn_applied_to_node_on_disk,
diff --git a/storage/tokudb/PerconaFT/ft/node.h b/storage/tokudb/PerconaFT/ft/node.h
index 05c8a44ebed..61093f3ed8d 100644
--- a/storage/tokudb/PerconaFT/ft/node.h
+++ b/storage/tokudb/PerconaFT/ft/node.h
@@ -155,6 +155,12 @@ private:
size_t _total_size;
};
+extern int writing_rollback;
+
+extern "C" {
+extern uint force_recovery;
+}
+
// TODO: class me up
struct ftnode {
// max_msn_applied that will be written to disk
@@ -173,9 +179,22 @@ struct ftnode {
uint32_t build_id;
// height is always >= 0. 0 for leaf, >0 for nonleaf.
int height;
- int dirty;
+ int dirty_;
uint32_t fullhash;
+ void set_dirty() {
+ if(force_recovery) assert(writing_rollback);
+ dirty_ = 1;
+ }
+
+ void clear_dirty() {
+ dirty_ = 0;
+ }
+
+ bool dirty() {
+ return dirty_;
+ }
+
// for internal nodes, if n_children==fanout+1 then the tree needs to be
// rebalanced. for leaf nodes, represents number of basement nodes
int n_children;
diff --git a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
index 56d51f56915..c4c99844edf 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/block_table.cc
@@ -195,9 +195,9 @@ static void ft_set_dirty(FT ft, bool for_checkpoint) {
invariant(ft->h->type == FT_CURRENT);
if (for_checkpoint) {
invariant(ft->checkpoint_header->type == FT_CHECKPOINT_INPROGRESS);
- ft->checkpoint_header->dirty = 1;
+ ft->checkpoint_header->set_dirty();
} else {
- ft->h->dirty = 1;
+ ft->h->set_dirty();
}
}
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc
index 02a9dfd085c..de58fb42a8b 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft-node-deserialize.cc
@@ -60,7 +60,7 @@ initialize_ftnode(FTNODE node, BLOCKNUM blocknum)
{
node->fullhash = 0xDEADBEEF; // <CER> Is this 'spoof' ok?
node->blocknum = blocknum;
- node->dirty = 0;
+ node->clear_dirty();
node->bp = NULL;
// <CER> Can we use this initialization as a correctness assert in
// a later function?
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
index 0d6573972d7..0813855bf55 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft-serialize.cc
@@ -340,7 +340,7 @@ int deserialize_ft_versioned(int fd, struct rbuf *rb, FT *ftp, uint32_t version)
{
struct ft_header h = {
.type = FT_CURRENT,
- .dirty = 0,
+ .dirty_ = 0,
.checkpoint_count = checkpoint_count,
.checkpoint_lsn = checkpoint_lsn,
.layout_version = FT_LAYOUT_VERSION,
diff --git a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc
index 46bb8f81412..46f2e9600c5 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc
+++ b/storage/tokudb/PerconaFT/ft/serialize/ft_node-serialize.cc
@@ -827,7 +827,7 @@ int toku_serialize_ftnode_to(int fd,
node, n_uncompressed_bytes, n_to_write, io_time, for_checkpoint);
toku_free(compressed_buf);
- node->dirty = 0; // See #1957. Must set the node to be clean after
+ node->clear_dirty(); // See #1957. Must set the node to be clean after
// serializing it so that it doesn't get written again on
// the next checkpoint or eviction.
if (node->height == 0) {
@@ -1544,7 +1544,7 @@ static FTNODE alloc_ftnode_for_deserialize(uint32_t fullhash, BLOCKNUM blocknum)
FTNODE XMALLOC(node);
node->fullhash = fullhash;
node->blocknum = blocknum;
- node->dirty = 0;
+ node->clear_dirty();
node->oldest_referenced_xid_known = TXNID_NONE;
node->bp = nullptr;
node->ct_pair = nullptr;
@@ -1951,7 +1951,7 @@ static int deserialize_and_upgrade_internal_node(FTNODE node,
// Assign the highest msn from our upgrade message buffers
node->max_msn_applied_to_node_on_disk = highest_msn;
// Since we assigned MSNs to this node's messages, we need to dirty it.
- node->dirty = 1;
+ node->set_dirty();
// Must compute the checksum now (rather than at the end, while we
// still have the pointer to the buffer).
@@ -2908,9 +2908,9 @@ int toku_serialize_rollback_log_to(int fd,
toku_free(compressed_buf);
if (!is_serialized) {
toku_static_serialized_rollback_log_destroy(&serialized_local);
- log->dirty = 0; // See #1957. Must set the node to be clean after
- // serializing it so that it doesn't get written again
- // on the next checkpoint or eviction.
+ log->dirty = false; // See #1957. Must set the node to be clean after
+ // serializing it so that it doesn't get written again
+ // on the next checkpoint or eviction.
}
return 0;
}
diff --git a/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h b/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h
index eb8c953b08c..31ffd7e1617 100644
--- a/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h
+++ b/storage/tokudb/PerconaFT/ft/serialize/rbtree_mhs.h
@@ -193,6 +193,7 @@ namespace MhsRbTree {
BlockPair(OUUInt64 o, OUUInt64 s) : _offset(o), _size(s) {}
BlockPair(const BlockPair &o)
: _offset(o._offset), _size(o._size) {}
+ BlockPair& operator=(const BlockPair&) = default;
int operator<(const BlockPair &rhs) const {
return _offset < rhs._offset;
diff --git a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc
index c1c4cb4f16e..a13e6d26d15 100644
--- a/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/cachetable-simple-close.cc
@@ -195,13 +195,13 @@ static void test_multiple_cachefiles(bool use_same_hash) {
char fname1[strlen(TOKU_TEST_FILENAME) + sizeof("_1")];
strcpy(fname1, TOKU_TEST_FILENAME);
- strncat(fname1, "_1", sizeof("_1"));
+ strcat(fname1, "_1");
char fname2[strlen(TOKU_TEST_FILENAME) + sizeof("_2")];
strcpy(fname2, TOKU_TEST_FILENAME);
- strncat(fname2, "_2", sizeof("_2"));
+ strcat(fname2, "_2");
char fname3[strlen(TOKU_TEST_FILENAME) + sizeof("_3")];
strcpy(fname3, TOKU_TEST_FILENAME);
- strncat(fname3, "_3", sizeof("_3"));
+ strcat(fname3, "_3");
unlink(fname1);
unlink(fname2);
@@ -280,10 +280,10 @@ static void test_evictor(void) {
char fname1[strlen(TOKU_TEST_FILENAME) + sizeof("_1")];
strcpy(fname1, TOKU_TEST_FILENAME);
- strncat(fname1, "_1", sizeof("_1"));
+ strcat(fname1, "_1");
char fname2[strlen(TOKU_TEST_FILENAME) + sizeof("_2")];
strcpy(fname2, TOKU_TEST_FILENAME);
- strncat(fname2, "_2", sizeof("_2"));
+ strcat(fname2, "_2");
unlink(fname1);
unlink(fname2);
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc b/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc
index 7abd2267a7e..1d6bc2fba7a 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-bfe-query.cc
@@ -337,7 +337,7 @@ static void test_prefetching(void) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 3;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
uint64_t key1 = 100;
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc b/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
index 00ff8cf204b..1a708b8e3cc 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-clock-test.cc
@@ -133,7 +133,7 @@ static void test1(int fd, FT ft_h, FTNODE *dn) {
for (int i = 0; i < (*dn)->n_children; i++) {
invariant(BP_STATE(*dn, i) == PT_AVAIL);
}
- (*dn)->dirty = 1;
+ (*dn)->set_dirty();
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
toku_ftnode_pe_callback(*dn, attr, ft_h, def_pe_finalize_impl, nullptr);
@@ -246,7 +246,7 @@ static void test_serialize_nonleaf(void) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(2, sn.bp);
DBT pivotkey;
@@ -384,7 +384,7 @@ static void test_serialize_leaf(void) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkey;
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc
index d50488ae197..bd5df7862cd 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-benchmark.cc
@@ -95,7 +95,7 @@ static void test_serialize_leaf(int valsize,
sn->layout_version_original = FT_LAYOUT_VERSION;
sn->height = 0;
sn->n_children = 8;
- sn->dirty = 1;
+ sn->set_dirty();
sn->oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn->n_children, sn->bp);
sn->pivotkeys.create_empty();
@@ -173,7 +173,7 @@ static void test_serialize_leaf(int valsize,
for (int i = 0; i < ser_runs; i++) {
gettimeofday(&t[0], NULL);
ndd = NULL;
- sn->dirty = 1;
+ sn->set_dirty();
r = toku_serialize_ftnode_to(
fd, make_blocknum(20), sn, &ndd, true, ft->ft, false);
invariant(r == 0);
@@ -265,7 +265,7 @@ static void test_serialize_nonleaf(int valsize,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 8;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
sn.pivotkeys.create_empty();
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc
index 0cddaf19651..4fca8efad35 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-serialize-test.cc
@@ -238,7 +238,7 @@ static void test_serialize_leaf_check_msn(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkey;
@@ -381,7 +381,7 @@ static void test_serialize_leaf_with_large_pivots(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = nrows;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
@@ -538,7 +538,7 @@ static void test_serialize_leaf_with_many_rows(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 1;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
XMALLOC_N(sn.n_children, sn.bp);
@@ -693,7 +693,7 @@ static void test_serialize_leaf_with_large_rows(enum ftnode_verify_type bft,
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 1;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
@@ -845,7 +845,7 @@ static void test_serialize_leaf_with_empty_basement_nodes(
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 7;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkeys[6];
@@ -989,7 +989,7 @@ static void test_serialize_leaf_with_multiple_empty_basement_nodes(
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 4;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkeys[3];
@@ -1100,7 +1100,7 @@ static void test_serialize_nonleaf(enum ftnode_verify_type bft, bool do_clone) {
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 1;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(2, sn.bp);
DBT pivotkey;
diff --git a/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc b/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc
index a23a3a60879..c668b9410c9 100644
--- a/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/ft-test-header.cc
@@ -57,7 +57,7 @@ static void test_header (void) {
assert(r==0);
// now insert some info into the header
FT ft = t->ft;
- ft->h->dirty = 1;
+ ft->h->set_dirty();
// cast away const because we actually want to fiddle with the header
// in this test
*((int *) &ft->h->layout_version_original) = 13;
diff --git a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc
index 761d672539b..fe950b60972 100644
--- a/storage/tokudb/PerconaFT/ft/tests/make-tree.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/make-tree.cc
@@ -88,7 +88,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
leafnode->max_msn_applied_to_node_on_disk = msn;
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc b/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc
index e3a3bfa28dc..bf9a1aa1484 100644
--- a/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/mempool-115.cc
@@ -102,7 +102,7 @@ public:
sn.layout_version_original = FT_LAYOUT_VERSION;
sn.height = 0;
sn.n_children = 2;
- sn.dirty = 1;
+ sn.set_dirty();
sn.oldest_referenced_xid_known = TXNID_NONE;
MALLOC_N(sn.n_children, sn.bp);
DBT pivotkey;
diff --git a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc
index c37dcd089f8..6d13eabfd93 100644
--- a/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/msnfilter.cc
@@ -161,7 +161,7 @@ append_leaf(FT_HANDLE ft, FTNODE leafnode, void *key, uint32_t keylen, void *val
}
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc b/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc
index 8ac1cd62c50..02dc63fca7e 100644
--- a/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/recovery-test5123.cc
@@ -49,9 +49,9 @@ static void test_5123(void) {
test_setup(TOKU_TEST_FILENAME, &logger, &ct);
int r;
- TXNID_PAIR one = {.parent_id64 = (TXNID)1, TXNID_NONE};
- TXNID_PAIR two = {.parent_id64 = (TXNID)2, TXNID_NONE};
- TXNID_PAIR three = {.parent_id64 = (TXNID)3, TXNID_NONE};
+ TXNID_PAIR one = { (TXNID)1, TXNID_NONE};
+ TXNID_PAIR two = { (TXNID)2, TXNID_NONE};
+ TXNID_PAIR three = { (TXNID)3, TXNID_NONE};
toku_log_xbegin(logger, NULL, false, one, TXNID_PAIR_NONE);
toku_log_xbegin(logger, NULL, false, three, TXNID_PAIR_NONE);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
index 06a26614885..5c73d281b98 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-flush.cc
@@ -245,7 +245,7 @@ doit (bool after_child_pin) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
if (after_child_pin) {
assert(toku_bnc_nbytesinbuf(BNC(node, 0)) == 0);
@@ -265,7 +265,7 @@ doit (bool after_child_pin) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
if (after_child_pin) {
assert(BLB_NBYTESINDATA(node,0) > 0);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
index 1029dfef320..cab370274cb 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-merge.cc
@@ -270,7 +270,7 @@ doit (int state) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
BLOCKNUM left_child, right_child;
// cases where we expect the checkpoint to contain the merge
if (state == ft_flush_aflter_merge || state == flt_flush_before_unpin_remove) {
@@ -301,7 +301,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -318,7 +318,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -336,7 +336,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
index 208ebe3ca31..87f66512642 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-rebalance.cc
@@ -284,7 +284,7 @@ doit (int state) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
BLOCKNUM left_child, right_child;
assert(node->n_children == 2);
@@ -304,7 +304,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
@@ -319,7 +319,7 @@ doit (int state) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
index 2b29de409b1..d5f7fe50f46 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-checkpoint-during-split.cc
@@ -260,7 +260,7 @@ doit (bool after_split) {
true
);
assert(node->height == 1);
- assert(!node->dirty);
+ assert(!node->dirty());
BLOCKNUM left_child, right_child;
if (after_split) {
assert(node->n_children == 2);
@@ -287,7 +287,7 @@ doit (bool after_split) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -302,7 +302,7 @@ doit (bool after_split) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 1);
toku_unpin_ftnode(c_ft->ft, node);
@@ -318,7 +318,7 @@ doit (bool after_split) {
true
);
assert(node->height == 0);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 1);
assert(BLB_DATA(node, 0)->num_klpairs() == 2);
toku_unpin_ftnode(c_ft->ft, node);
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc b/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc
index 460134ec353..e1937538471 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-dirty-flushes-on-cleaner.cc
@@ -199,7 +199,7 @@ doit (void) {
&node,
true
);
- assert(node->dirty);
+ assert(node->dirty());
assert(node->n_children == 2);
assert(BP_STATE(node,0) == PT_AVAIL);
assert(BP_STATE(node,1) == PT_AVAIL);
@@ -229,7 +229,7 @@ doit (void) {
&node,
true
);
- assert(node->dirty);
+ assert(node->dirty());
assert(node->n_children == 2);
assert(BP_STATE(node,0) == PT_AVAIL);
assert(BP_STATE(node,1) == PT_AVAIL);
@@ -250,7 +250,7 @@ doit (void) {
&node,
true
);
- assert(node->dirty);
+ assert(node->dirty());
// we expect that this flushes its buffer, that
// a merge is not done, and that the lookup
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc b/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc
index 89d7130e5f7..f9d4d1646b8 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-flushes-on-cleaner.cc
@@ -203,7 +203,7 @@ doit (bool keep_other_bn_in_memory) {
&node,
true
);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 2);
// a hack to get the basement nodes evicted
for (int i = 0; i < 20; i++) {
@@ -249,7 +249,7 @@ doit (bool keep_other_bn_in_memory) {
&node,
true
);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(node->n_children == 2);
assert(BP_STATE(node,0) == PT_AVAIL);
if (keep_other_bn_in_memory) {
@@ -273,7 +273,7 @@ doit (bool keep_other_bn_in_memory) {
&node,
true
);
- assert(!node->dirty);
+ assert(!node->dirty());
// we expect that this flushes its buffer, that
// a merge is not done, and that the lookup
diff --git a/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc b/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc
index 83dfd0244f4..29d07483f99 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test-pick-child-to-flush.cc
@@ -194,7 +194,7 @@ doit (void) {
toku_pin_node_with_min_bfe(&node, node_internal, t);
toku_ftnode_assert_fully_in_memory(node);
assert(node->n_children == 2);
- assert(!node->dirty);
+ assert(!node->dirty());
assert(toku_bnc_n_entries(node->bp[0].ptr.u.nonleaf) > 0);
assert(toku_bnc_n_entries(node->bp[1].ptr.u.nonleaf) > 0);
@@ -216,7 +216,7 @@ doit (void) {
toku_pin_node_with_min_bfe(&node, node_internal, t);
toku_ftnode_assert_fully_in_memory(node);
- assert(node->dirty);
+ assert(node->dirty());
assert(node->n_children == 2);
// child 0 should have empty buffer because it flushed
// child 1 should still have message in buffer
@@ -226,14 +226,14 @@ doit (void) {
r = toku_checkpoint(cp, NULL, NULL, NULL, NULL, NULL, CLIENT_CHECKPOINT);
assert_zero(r);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(!node->dirty);
+ assert(!node->dirty());
curr_child_to_flush = 1;
num_flushes_called = 0;
toku_ft_flush_some_child(t->ft, node, &fa);
assert(num_flushes_called == 1);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(node->dirty);
+ assert(node->dirty());
toku_ftnode_assert_fully_in_memory(node);
assert(node->n_children == 2);
// both buffers should be empty now
@@ -244,14 +244,14 @@ doit (void) {
r = toku_checkpoint(cp, NULL, NULL, NULL, NULL, NULL, CLIENT_CHECKPOINT);
assert_zero(r);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(!node->dirty);
+ assert(!node->dirty());
curr_child_to_flush = 0;
num_flushes_called = 0;
toku_ft_flush_some_child(t->ft, node, &fa);
assert(num_flushes_called == 1);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(node->dirty); // nothing was flushed, but since we were trying to flush to a leaf, both become dirty
+ assert(node->dirty()); // nothing was flushed, but since we were trying to flush to a leaf, both become dirty
toku_ftnode_assert_fully_in_memory(node);
assert(node->n_children == 2);
// both buffers should be empty now
@@ -280,17 +280,17 @@ doit (void) {
assert(num_flushes_called == 2);
toku_pin_node_with_min_bfe(&node, node_internal, t);
- assert(node->dirty);
+ assert(node->dirty());
toku_unpin_ftnode(t->ft, node);
toku_pin_node_with_min_bfe(&node, node_leaf[0], t);
- assert(node->dirty);
+ assert(node->dirty());
toku_unpin_ftnode(t->ft, node);
toku_pin_node_with_min_bfe(&node, node_leaf[1], t);
if (i == 0) {
- assert(!node->dirty);
+ assert(!node->dirty());
}
else {
- assert(node->dirty);
+ assert(node->dirty());
}
toku_unpin_ftnode(t->ft, node);
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/test3884.cc b/storage/tokudb/PerconaFT/ft/tests/test3884.cc
index cfb76424668..5de55b0daff 100644
--- a/storage/tokudb/PerconaFT/ft/tests/test3884.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/test3884.cc
@@ -105,7 +105,7 @@ setup_ftnode_header(struct ftnode *node)
node->layout_version = FT_LAYOUT_VERSION;
node->layout_version_original = FT_LAYOUT_VERSION;
node->height = 0;
- node->dirty = 1;
+ node->set_dirty();
node->oldest_referenced_xid_known = TXNID_NONE;
}
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc
index b10885c2e62..1ba5f1c2503 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-msn.cc
@@ -93,7 +93,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
// leafnode->max_msn_applied_to_node = msn;
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc
index c1d08ce41a6..42415a07765 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-bad-pivots.cc
@@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
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 22a29c0ff69..e31b13c4f4d 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-in-leaf.cc
@@ -78,7 +78,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc
index 80189dd9804..009eda63999 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-dup-pivots.cc
@@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc
index a84aac1f063..5c639d8d28a 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-misrouted-msgs.cc
@@ -78,7 +78,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc
index ca413f52567..d55ec7a736f 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-leaf.cc
@@ -80,7 +80,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc
index 6efa06913c2..ff231001c77 100644
--- a/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc
+++ b/storage/tokudb/PerconaFT/ft/tests/verify-unsorted-pivots.cc
@@ -77,7 +77,7 @@ append_leaf(FTNODE leafnode, void *key, size_t keylen, void *val, size_t vallen)
NULL);
// don't forget to dirty the node
- leafnode->dirty = 1;
+ leafnode->set_dirty();
}
static void
diff --git a/storage/tokudb/PerconaFT/ft/txn/rollback.cc b/storage/tokudb/PerconaFT/ft/txn/rollback.cc
index 0c793842f3c..105f980dc0d 100644
--- a/storage/tokudb/PerconaFT/ft/txn/rollback.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/rollback.cc
@@ -43,6 +43,8 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#include "ft/logger/log-internal.h"
#include "ft/txn/rollback-ct-callbacks.h"
+extern int writing_rollback;
+
static void rollback_unpin_remove_callback(CACHEKEY* cachekey, bool for_checkpoint, void* extra) {
FT CAST_FROM_VOIDP(ft, extra);
ft->blocktable.free_blocknum(cachekey, ft, for_checkpoint);
@@ -155,6 +157,7 @@ static void rollback_log_create (
ROLLBACK_LOG_NODE *result
)
{
+ writing_rollback++;
ROLLBACK_LOG_NODE XMALLOC(log);
rollback_empty_log_init(log);
@@ -169,6 +172,7 @@ static void rollback_log_create (
get_write_callbacks_for_rollback_log(ft),
toku_rollback_node_save_ct_pair);
txn->roll_info.current_rollback = log->blocknum;
+ writing_rollback --;
}
void toku_rollback_log_unpin(TOKUTXN txn, ROLLBACK_LOG_NODE log) {
diff --git a/storage/tokudb/PerconaFT/ft/txn/txn.cc b/storage/tokudb/PerconaFT/ft/txn/txn.cc
index 7327cbd9d24..7152833d88d 100644
--- a/storage/tokudb/PerconaFT/ft/txn/txn.cc
+++ b/storage/tokudb/PerconaFT/ft/txn/txn.cc
@@ -723,7 +723,11 @@ time_t toku_txn_get_start_time(struct tokutxn *txn) {
return txn->start_time;
}
+extern uint force_recovery;
int toku_txn_reads_txnid(TXNID txnid, TOKUTXN txn, bool is_provisional UU()) {
+ if(force_recovery) {
+ return TOKUDB_ACCEPT;
+ }
int r = 0;
TXNID oldest_live_in_snapshot = toku_get_oldest_in_live_root_txn_list(txn);
if (oldest_live_in_snapshot == TXNID_NONE && txnid < txn->snapshot_txnid64) {
diff --git a/storage/tokudb/PerconaFT/ftcxx/cursor.hpp b/storage/tokudb/PerconaFT/ftcxx/cursor.hpp
index 9ecc4d173c6..bde5dbf2c19 100644
--- a/storage/tokudb/PerconaFT/ftcxx/cursor.hpp
+++ b/storage/tokudb/PerconaFT/ftcxx/cursor.hpp
@@ -398,8 +398,8 @@ namespace ftcxx {
{}
bool operator()(const DBT *key, const DBT *val) {
- _key = std::move(Slice(*key).owned());
- _val = std::move(Slice(*val).owned());
+ _key = Slice(*key).owned();
+ _val = Slice(*val).owned();
// Don't bulk fetch.
return false;
diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.cc b/storage/tokudb/PerconaFT/locktree/lock_request.cc
index 0a95dc417d6..cc6fcafcd5d 100644
--- a/storage/tokudb/PerconaFT/locktree/lock_request.cc
+++ b/storage/tokudb/PerconaFT/locktree/lock_request.cc
@@ -93,6 +93,10 @@ void lock_request::destroy(void) {
toku_cond_destroy(&m_wait_cond);
}
+void lock_request::clearmem(char c) {
+ memset(this, c, sizeof(* this));
+}
+
// set the lock request parameters. this API allows a lock request to be reused.
void lock_request::set(locktree *lt, TXNID txnid, const DBT *left_key, const DBT *right_key, lock_request::type lock_type, bool big_txn, void *extra) {
invariant(m_state != state::PENDING);
diff --git a/storage/tokudb/PerconaFT/locktree/lock_request.h b/storage/tokudb/PerconaFT/locktree/lock_request.h
index 8b22241e276..e16e77ed6f4 100644
--- a/storage/tokudb/PerconaFT/locktree/lock_request.h
+++ b/storage/tokudb/PerconaFT/locktree/lock_request.h
@@ -89,6 +89,7 @@ public:
// effect: Destroys a lock request.
void destroy(void);
+ void clearmem(char c);
// effect: Resets the lock request parameters, allowing it to be reused.
// requires: Lock request was already created at some point
diff --git a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc
index 5c28701c49e..83436a651e1 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race.cc
@@ -83,7 +83,7 @@ namespace toku {
}
request.destroy();
- memset(&request, 0xab, sizeof request);
+ request.clearmem(0xab);
toku_pthread_yield();
if ((i % 10) == 0)
diff --git a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc
index 8458bae6b8c..6748ae30ee1 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_race_3.cc
@@ -96,7 +96,7 @@ namespace toku {
}
request.destroy();
- memset(&request, 0xab, sizeof request);
+ request.clearmem(0xab);
toku_pthread_yield();
if ((i % 10) == 0)
diff --git a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc
index 4b6dadd440f..cd3dc7b37ef 100644
--- a/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc
+++ b/storage/tokudb/PerconaFT/locktree/tests/lock_request_start_retry_wait_race_2.cc
@@ -98,7 +98,7 @@ namespace toku {
}
request.destroy();
- memset(&request, 0xab, sizeof request);
+ request.clearmem(0xab);
toku_pthread_yield();
if ((i % 10) == 0)
diff --git a/storage/tokudb/PerconaFT/portability/portability.cc b/storage/tokudb/PerconaFT/portability/portability.cc
index 81115a516aa..556a34fb861 100644
--- a/storage/tokudb/PerconaFT/portability/portability.cc
+++ b/storage/tokudb/PerconaFT/portability/portability.cc
@@ -60,7 +60,7 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
#if defined(HAVE_SYS_SYSCALL_H)
# include <sys/syscall.h>
#endif
-#if defined(HAVE_SYS_SYSCTL_H)
+#if defined(HAVE_SYS_SYSCTL_H) && !defined(_SC_PHYS_PAGES)
# include <sys/sysctl.h>
#endif
#if defined(HAVE_PTHREAD_H)
diff --git a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
index 786a6ef0546..0f287429542 100644
--- a/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
+++ b/storage/tokudb/PerconaFT/portability/toku_instr_mysql.cc
@@ -359,7 +359,16 @@ void toku_instr_rwlock_wrlock_wait_end(
void toku_instr_rwlock_unlock(toku_pthread_rwlock_t &rwlock) {
if (rwlock.psi_rwlock)
+
+// Due to change introduced in e4148f2a22922687f7652c4e3d21a22da07c9e78
+// PSI rwlock version and interface changed
+// PSI_CURRENT_RWLOCK_VERSION is not defined in MySQL 5.6 and is defined
+// as 1 in 5.7 and < 8.0.17
+#if defined(PSI_CURRENT_RWLOCK_VERSION) && (PSI_CURRENT_RWLOCK_VERSION == 2)
+ PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock, PSI_RWLOCK_UNLOCK);
+#else
PSI_RWLOCK_CALL(unlock_rwlock)(rwlock.psi_rwlock);
+#endif
}
#endif // TOKU_MYSQL_WITH_PFS
diff --git a/storage/tokudb/PerconaFT/src/tests/test.h b/storage/tokudb/PerconaFT/src/tests/test.h
index ff464f55890..c5214961afd 100644
--- a/storage/tokudb/PerconaFT/src/tests/test.h
+++ b/storage/tokudb/PerconaFT/src/tests/test.h
@@ -428,14 +428,14 @@ static int env_del_multiple_test_no_array(
/* Some macros for evaluating blocks or functions within the scope of a
* transaction. */
#define IN_TXN_COMMIT(env, parent, txn, flags, expr) ({ \
- DB_TXN *(txn); \
+ DB_TXN *txn; \
{ int chk_r = (env)->txn_begin((env), (parent), &(txn), (flags)); CKERR(chk_r); } \
(expr); \
{ int chk_r = (txn)->commit((txn), 0); CKERR(chk_r); } \
})
#define IN_TXN_ABORT(env, parent, txn, flags, expr) ({ \
- DB_TXN *(txn); \
+ DB_TXN *txn; \
{ int chk_r = (env)->txn_begin((env), (parent), &(txn), (flags)); CKERR(chk_r); } \
(expr); \
{ int chk_r = (txn)->abort(txn); CKERR(chk_r); } \
diff --git a/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc b/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc
index ecd88f3c5fe..55b2943e67f 100644
--- a/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc
+++ b/storage/tokudb/PerconaFT/src/tests/test_mostly_seq.cc
@@ -68,7 +68,7 @@ seqinsert (int n, float p) {
int v = i;
DBT key, val;
r = db->put(db, 0, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0);
- if (random() <= RAND_MAX * p) {
+ if (random() <= static_cast<float>(RAND_MAX) * p) {
k = htonl(i-1);
v = i-1;
r = db->put(db, 0, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0);
diff --git a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
index e232f327d10..1d8833adcba 100644
--- a/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
+++ b/storage/tokudb/PerconaFT/src/tests/threaded_stress_test_helpers.h
@@ -432,17 +432,17 @@ tsv_print_perf_totals(const struct cli_args *cli_args, uint64_t *counters[], con
}
const struct perf_formatter perf_formatters[] = {
- [HUMAN] = {
+ { /* HUMAN */
.header = human_print_perf_header,
.iteration = human_print_perf_iteration,
.totals = human_print_perf_totals
},
- [CSV] = {
+ { /* CSV */
.header = csv_print_perf_header,
.iteration = csv_print_perf_iteration,
.totals = csv_print_perf_totals
},
- [TSV] = {
+ { /* TSV */
.header = tsv_print_perf_header,
.iteration = tsv_print_perf_iteration,
.totals = tsv_print_perf_totals
diff --git a/storage/tokudb/PerconaFT/src/ydb.cc b/storage/tokudb/PerconaFT/src/ydb.cc
index 8dcbba361b9..6d82791a3e3 100644
--- a/storage/tokudb/PerconaFT/src/ydb.cc
+++ b/storage/tokudb/PerconaFT/src/ydb.cc
@@ -39,6 +39,9 @@ Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
extern const char *toku_patent_string;
const char *toku_copyright_string = "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.";
+
+extern int writing_rollback;
+
#include <db.h>
#include <errno.h>
#include <string.h>
@@ -87,6 +90,8 @@ const char *toku_copyright_string = "Copyright (c) 2006, 2015, Percona and/or it
int toku_close_trace_file (void) { return 0; }
#endif
+extern uint force_recovery;
+
// Set when env is panicked, never cleared.
static int env_is_panicked = 0;
@@ -223,6 +228,9 @@ env_fs_redzone(DB_ENV *env, uint64_t total) {
// Check the available space in the file systems used by tokuft and erect barriers when available space gets low.
static int
env_fs_poller(void *arg) {
+ if(force_recovery == 6) {
+ return 0;
+ }
DB_ENV *env = (DB_ENV *) arg;
int r;
@@ -307,6 +315,9 @@ env_fs_init(DB_ENV *env) {
// Initialize the minicron that polls file system space
static int
env_fs_init_minicron(DB_ENV *env) {
+ if(force_recovery == 6) {
+ return 0;
+ }
int r = toku_minicron_setup(&env->i->fs_poller, env->i->fs_poll_time*1000, env_fs_poller, env);
if (r == 0)
env->i->fs_poller_is_init = true;
@@ -709,7 +720,7 @@ static int validate_env(DB_ENV *env,
}
// Test for fileops directory
- if (r == 0) {
+ if (r == 0 && force_recovery != 6) {
path = toku_construct_full_name(
2, env->i->dir, toku_product_name_strings.fileopsdirectory);
assert(path);
@@ -752,7 +763,7 @@ static int validate_env(DB_ENV *env,
}
// Test for recovery log
- if ((r == 0) && (env->i->open_flags & DB_INIT_LOG)) {
+ if ((r == 0) && (env->i->open_flags & DB_INIT_LOG) && force_recovery != 6) {
// if using transactions, test for existence of log
r = ydb_recover_log_exists(env); // return 0 or ENOENT
if (expect_newenv && (r != ENOENT))
@@ -813,6 +824,27 @@ unlock_single_process(DB_ENV *env) {
// (The set of necessary files is defined in the function validate_env() above.)
static int
env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
+
+ if(force_recovery == 6) {
+ {
+ const int len = strlen(toku_product_name_strings.rollback_cachefile);
+ toku_product_name_strings.rollback_cachefile[len] = '2';
+ toku_product_name_strings.rollback_cachefile[len+1] = 0;
+ }
+
+ {
+ const int len = strlen(toku_product_name_strings.single_process_lock);
+ toku_product_name_strings.single_process_lock[len] = '2';
+ toku_product_name_strings.single_process_lock[len+1] = 0;
+ }
+
+ {
+ const int len = strlen(toku_product_name_strings.environmentdictionary);
+ toku_product_name_strings.environmentdictionary[len] = '2';
+ toku_product_name_strings.environmentdictionary[len+1] = 0;
+ }
+ }
+
HANDLE_PANICKED_ENV(env);
int r;
bool newenv; // true iff creating a new environment
@@ -903,7 +935,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
bool need_rollback_cachefile;
need_rollback_cachefile = false;
- if (flags & (DB_INIT_TXN | DB_INIT_LOG)) {
+ if (flags & (DB_INIT_TXN | DB_INIT_LOG) && force_recovery != 6) {
need_rollback_cachefile = true;
}
@@ -916,7 +948,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
r = ydb_maybe_upgrade_env(env, &last_lsn_of_clean_shutdown_read_from_log, &upgrade_in_progress);
if (r!=0) goto cleanup;
- if (upgrade_in_progress) {
+ if (upgrade_in_progress || force_recovery == 6) {
// Delete old rollback file. There was a clean shutdown, so it has nothing useful,
// and there is no value in upgrading it. It is simpler to just create a new one.
char* rollback_filename = toku_construct_full_name(2, env->i->dir, toku_product_name_strings.rollback_cachefile);
@@ -934,9 +966,13 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
unused_flags &= ~DB_INIT_TXN & ~DB_INIT_LOG;
+ if(force_recovery == 6) {
+ flags |= DB_INIT_LOG | DB_INIT_TXN;
+ }
+
// do recovery only if there exists a log and recovery is requested
// otherwise, a log is created when the logger is opened later
- if (!newenv) {
+ if (!newenv && force_recovery == 0) {
if (flags & DB_INIT_LOG) {
// the log does exist
if (flags & DB_RECOVER) {
@@ -1005,7 +1041,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
assert (using_txns);
toku_logger_set_cachetable(env->i->logger, env->i->cachetable);
if (!toku_logger_rollback_is_open(env->i->logger)) {
- bool create_new_rollback_file = newenv | upgrade_in_progress;
+ bool create_new_rollback_file = newenv | upgrade_in_progress | (force_recovery == 6);
r = toku_logger_open_rollback(env->i->logger, env->i->cachetable, create_new_rollback_file);
if (r != 0) {
r = toku_ydb_do_error(env, r, "Cant open rollback\n");
@@ -1024,6 +1060,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
assert_zero(r);
r = toku_db_use_builtin_key_cmp(env->i->persistent_environment);
assert_zero(r);
+ writing_rollback++;
r = toku_db_open_iname(env->i->persistent_environment, txn, toku_product_name_strings.environmentdictionary, DB_CREATE, mode);
if (r != 0) {
r = toku_ydb_do_error(env, r, "Cant open persistent env\n");
@@ -1056,6 +1093,7 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
assert_zero(r);
}
capture_persistent_env_contents(env, txn);
+ writing_rollback--;
}
{
r = toku_db_create(&env->i->directory, env, 0);
@@ -1074,8 +1112,10 @@ env_open(DB_ENV * env, const char *home, uint32_t flags, int mode) {
txn = NULL;
}
cp = toku_cachetable_get_checkpointer(env->i->cachetable);
- r = toku_checkpoint(cp, env->i->logger, NULL, NULL, NULL, NULL, STARTUP_CHECKPOINT);
- assert_zero(r);
+ if (!force_recovery) {
+ r = toku_checkpoint(cp, env->i->logger, NULL, NULL, NULL, NULL, STARTUP_CHECKPOINT);
+ }
+ writing_rollback--;
env_fs_poller(env); // get the file system state at startup
r = env_fs_init_minicron(env);
if (r != 0) {
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.cc b/storage/tokudb/PerconaFT/src/ydb_db.cc
index 40c4a7f6577..f10535062e9 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.cc
+++ b/storage/tokudb/PerconaFT/src/ydb_db.cc
@@ -323,6 +323,7 @@ toku_db_open(DB * db, DB_TXN * txn, const char *fname, const char *dbname, DBTYP
// DB_THREAD is implicitly supported and DB_BLACKHOLE is supported at the ft-layer
unused_flags &= ~DB_THREAD;
unused_flags &= ~DB_BLACKHOLE;
+ unused_flags &= ~DB_RDONLY;
// check for unknown or conflicting flags
if (unused_flags) return EINVAL; // unknown flags
@@ -404,7 +405,7 @@ int toku_db_lt_on_create_callback(toku::locktree *lt, void *extra) {
FT_HANDLE ft_handle = info->ft_handle;
FT_HANDLE cloned_ft_handle;
- r = toku_ft_handle_clone(&cloned_ft_handle, ft_handle, ttxn);
+ r = toku_ft_handle_clone(&cloned_ft_handle, ft_handle, ttxn, info->open_rw);
if (r == 0) {
assert(lt->get_userdata() == NULL);
lt->set_userdata(cloned_ft_handle);
@@ -465,6 +466,7 @@ int toku_db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, uint32_t
flags&=~DB_READ_COMMITTED;
flags&=~DB_SERIALIZABLE;
flags&=~DB_IS_HOT_INDEX;
+ flags&=~DB_RDONLY;
// unknown or conflicting flags are bad
int unknown_flags = flags & ~DB_THREAD;
unknown_flags &= ~DB_BLACKHOLE;
@@ -479,11 +481,12 @@ int toku_db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, uint32_t
db->i->open_flags = flags;
db->i->open_mode = mode;
+ bool open_rw = mode & (S_IWUSR | S_IWOTH | S_IWGRP);
FT_HANDLE ft_handle = db->i->ft_handle;
int r = toku_ft_handle_open(ft_handle, iname_in_env,
is_db_create, is_db_excl,
db->dbenv->i->cachetable,
- txn ? db_txn_struct_i(txn)->tokutxn : nullptr);
+ txn ? db_txn_struct_i(txn)->tokutxn : nullptr, open_rw);
if (r != 0) {
goto out;
}
@@ -505,6 +508,7 @@ int toku_db_open_iname(DB * db, DB_TXN * txn, const char *iname_in_env, uint32_t
struct lt_on_create_callback_extra on_create_extra = {
.txn = txn,
.ft_handle = db->i->ft_handle,
+ .open_rw = false
};
db->i->lt = db->dbenv->i->ltm.get_lt(db->i->dict_id,
toku_ft_get_comparator(db->i->ft_handle),
diff --git a/storage/tokudb/PerconaFT/src/ydb_db.h b/storage/tokudb/PerconaFT/src/ydb_db.h
index ab8fcd2a401..c260e9d0fbe 100644
--- a/storage/tokudb/PerconaFT/src/ydb_db.h
+++ b/storage/tokudb/PerconaFT/src/ydb_db.h
@@ -67,6 +67,7 @@ void ydb_db_layer_get_status(YDB_DB_LAYER_STATUS statp);
struct lt_on_create_callback_extra {
DB_TXN *txn;
FT_HANDLE ft_handle;
+ bool open_rw;
};
int toku_db_lt_on_create_callback(toku::locktree *lt, void *extra);
void toku_db_lt_on_destroy_callback(toku::locktree *lt);
diff --git a/storage/tokudb/PerconaFT/tools/tokuftdump.cc b/storage/tokudb/PerconaFT/tools/tokuftdump.cc
index 2838ae5182e..44edb15162a 100644
--- a/storage/tokudb/PerconaFT/tools/tokuftdump.cc
+++ b/storage/tokudb/PerconaFT/tools/tokuftdump.cc
@@ -181,7 +181,7 @@ static void dump_header(FT ft) {
printf(" time_of_creation= %" PRIu64 " %s\n", ft->h->time_of_creation, timestr);
format_time(ft->h->time_of_last_modification, timestr);
printf(" time_of_last_modification=%" PRIu64 " %s\n", ft->h->time_of_last_modification, timestr);
- printf(" dirty=%d\n", ft->h->dirty);
+ printf(" dirty=%d\n", ft->h->dirty());
printf(" checkpoint_count=%" PRId64 "\n", ft->h->checkpoint_count);
printf(" checkpoint_lsn=%" PRId64 "\n", ft->h->checkpoint_lsn.lsn);
printf(" nodesize=%u\n", ft->h->nodesize);
diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc
index a4dc9f6e326..39931e747ce 100644
--- a/storage/tokudb/ha_tokudb.cc
+++ b/storage/tokudb/ha_tokudb.cc
@@ -1333,7 +1333,7 @@ int ha_tokudb::open_main_dictionary(
NULL,
DB_BTREE,
open_flags,
- 0);
+ S_IWUSR);
if (error) {
goto exit;
}
@@ -1396,7 +1396,7 @@ int ha_tokudb::open_secondary_dictionary(
}
- error = (*ptr)->open(*ptr, txn, newname, NULL, DB_BTREE, open_flags, 0);
+ error = (*ptr)->open(*ptr, txn, newname, NULL, DB_BTREE, open_flags, S_IWUSR);
if (error) {
my_errno = error;
goto cleanup;
diff --git a/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt b/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt
index b351df53683..127c28fabfd 100644
--- a/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt
+++ b/storage/tokudb/mysql-test/rpl/t/rpl_parallel_tokudb-slave.opt
@@ -1,5 +1 @@
--log-warnings=0 --slave-transaction-retries=0
-
-
-
-
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
index 7d5b555488e..dd47b8a1a5c 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_newdecimal.result
@@ -1531,11 +1531,8 @@ select (1.20396873 * 0.89550000 * 0.68000000 * 1.08721696 * 0.99500000 *
1.01500000 * 1.01500000 * 0.99500000)
0.812988073953673124592306939480
create table t1 as select 5.05 / 0.014;
-Warnings:
-Note 1265 Data truncated for column '5.05 / 0.014' at row 1
show warnings;
Level Code Message
-Note 1265 Data truncated for column '5.05 / 0.014' at row 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@@ -1650,8 +1647,6 @@ my_col
0.123456789123456789123456789123
DROP TABLE t1;
CREATE TABLE t1 SELECT 1 / .123456789123456789123456789123456789123456789123456789123456789123456789123456789 AS my_col;
-Warnings:
-Note 1265 Data truncated for column 'my_col' at row 1
DESCRIBE t1;
Field Type Null Key Default Extra
my_col decimal(65,4) YES NULL
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_ranges.result b/storage/tokudb/mysql-test/tokudb/r/type_ranges.result
index bd8491336b3..395f21a8a8f 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_ranges.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_ranges.result
@@ -95,8 +95,6 @@ DROP INDEX test ON t1;
insert into t1 values (10, 1,1,1,1,1,1,1,1,1,1,1,1,1,NULL,0,0,0,1,1,1,1,'one','one');
insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,NULL,2,2,'two','two,one');
insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3);
-Warnings:
-Warning 1265 Data truncated for column 'string' at row 1
insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1);
Warnings:
Warning 1264 Out of range value for column 'utiny' at row 1
@@ -137,7 +135,7 @@ select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,ut
auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col
10 1 1 1 1 1 1 1.0 1.0000 1 00001 1 1 1 0 0000-00-00 00:00:00 0000-00-00 00:00:00 1 1 1 1
11 2 2 2 2 2 2 2.0 2.0000 2 00002 2 2 2 0 NULL NULL NULL NULL NULL 2 2
-12 0.33333333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
+12 0.3333 3 3 3 3 3 3.0 3.0000 3 00003 3 3 3 0 1997-03-03 10:10:10 1997-03-03 10:10:10 3
13 -1 -1 -1 -1 -1 -1 -1.0 -1.0000 0 00000 0 0 0 0 1997-08-07 08:07:06 1997-04-03 09:08:07 -1 -1 -1 -1
14 -429496729 -128 -32768 -8388608 -2147483648 -4294967295 -4294967296.0 -4294967295.0000 0 00000 0 0 0 0 0000-00-00 00:00:00 0000-00-00 00:00:00 -4294967295 -4294967295 -4294967295 -4294967295
15 4294967295 127 32767 8388607 2147483647 4294967295 4294967296.0 4294967295.0000 255 65535 16777215 4294967295 4294967295 0 0000-00-00 00:00:00 0000-00-00 00:00:00 4294967295 4294967295 4294967295 4294967295
@@ -189,7 +187,7 @@ Warning 1265 Data truncated for column 'new_field' at row 7
select * from t2;
auto string mediumblob_col new_field
1 2 2 ne
-2 0.33333333 ne
+2 0.3333 ne
3 -1 -1 ne
4 -429496729 -4294967295 ne
5 4294967295 4294967295 ne
diff --git a/storage/tokudb/tokudb_status.h b/storage/tokudb/tokudb_status.h
index 5cca54e52c9..07772bdc92a 100644
--- a/storage/tokudb/tokudb_status.h
+++ b/storage/tokudb/tokudb_status.h
@@ -201,7 +201,7 @@ int create(
name,
NULL,
DB_BTREE, DB_CREATE | DB_EXCL,
- 0);
+ S_IWUSR);
}
if (error == 0) {
*status_db_ptr = status_db;
@@ -230,7 +230,7 @@ int open(
NULL,
DB_BTREE,
DB_THREAD,
- 0);
+ S_IWUSR);
}
if (error == 0) {
uint32_t pagesize = 0;
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 5235fe434a9..7d97881f552 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -3,7 +3,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2015, 2017, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1542,17 +1542,23 @@ fail_err:
}
ulint max_size = page_get_max_insert_size_after_reorganize(page, 1);
+ if (max_size < rec_size) {
+ goto fail;
+ }
+
+ const ulint n_recs = page_get_n_recs(page);
+ if (UNIV_UNLIKELY(n_recs >= 8189)) {
+ ut_ad(srv_page_size == 65536);
+ goto fail;
+ }
if (page_has_garbage(page)) {
- if ((max_size < rec_size
- || max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT)
- && page_get_n_recs(page) > 1
+ if (max_size < BTR_CUR_PAGE_REORGANIZE_LIMIT
+ && n_recs > 1
&& page_get_max_insert_size(page, 1) < rec_size) {
goto fail;
}
- } else if (max_size < rec_size) {
- goto fail;
}
/* If there have been many consecutive inserts to the
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 398e1e84994..5e92c101110 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -4936,9 +4936,8 @@ buf_page_io_complete(buf_page_t* bpage)
err = buf_page_check_corrupt(bpage, space);
}
-database_corrupted:
-
if (err != DB_SUCCESS) {
+database_corrupted:
/* Not a real corruption if it was triggered by
error injection */
DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
@@ -4953,6 +4952,11 @@ database_corrupted:
goto page_not_corrupt;
);
+ if (uncompressed && bpage->zip.data) {
+ memset(reinterpret_cast<buf_block_t*>(bpage)
+ ->frame, 0, srv_page_size);
+ }
+
if (err == DB_PAGE_CORRUPTED) {
ib_logf(IB_LOG_LEVEL_ERROR,
"Database page corruption on disk"
diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc
index c3a169d45ef..776e5ab06a2 100644
--- a/storage/xtradb/buf/buf0dblwr.cc
+++ b/storage/xtradb/buf/buf0dblwr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -554,12 +554,18 @@ buf_dblwr_process()
continue;
}
- if (!fil_check_adress_in_tablespace(space_id, page_no)) {
+ if (!space()->size) {
+ fil_space_get_size(space_id);
+ }
+
+ if (UNIV_UNLIKELY(space()->size <= page_no)) {
ib_logf(IB_LOG_LEVEL_WARN,
- "A copy of page " ULINTPF ":" ULINTPF
+ "A copy of page " ULINTPF
" in the doublewrite buffer slot " ULINTPF
- " is not within space bounds",
- space_id, page_no, page_no_dblwr);
+ " is beyond the end of the tablespace "
+ " %s (" ULINTPF " pages)",
+ page_no, page_no_dblwr,
+ space()->name, space()->size);
continue;
}
@@ -963,6 +969,7 @@ try_again:
ib_int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
}
@@ -1112,6 +1119,7 @@ try_again:
checkpoint. */
ib_int64_t sig_count = os_event_reset(buf_dblwr->b_event);
mutex_exit(&buf_dblwr->mutex);
+ os_aio_simulated_wake_handler_threads();
os_event_wait_low(buf_dblwr->b_event, sig_count);
goto try_again;
diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc
index 349e7d45ab8..20dec30d106 100644
--- a/storage/xtradb/buf/buf0dump.cc
+++ b/storage/xtradb/buf/buf0dump.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -176,7 +176,7 @@ get_buf_dump_dir()
/* The dump file should be created in the default data directory if
innodb_data_home_dir is set as an empty string. */
- if (strcmp(srv_data_home, "") == 0) {
+ if (!*srv_data_home) {
dump_dir = fil_path_to_mysql_datadir;
} else {
dump_dir = srv_data_home;
@@ -208,9 +208,11 @@ buf_dump(
ulint i;
int ret;
+ mysql_mutex_lock(&LOCK_global_system_variables);
ut_snprintf(full_filename, sizeof(full_filename),
"%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR,
srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
ut_snprintf(tmp_filename, sizeof(tmp_filename),
format_name, full_filename);
@@ -514,9 +516,11 @@ buf_load()
/* Ignore any leftovers from before */
buf_load_abort_flag = FALSE;
+ mysql_mutex_lock(&LOCK_global_system_variables);
ut_snprintf(full_filename, sizeof(full_filename),
"%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR,
srv_buf_dump_filename);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
buf_load_status(STATUS_NOTICE,
"Loading buffer pool(s) from %s", full_filename);
diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc
index eccc7c281c1..4993654952b 100644
--- a/storage/xtradb/buf/buf0flu.cc
+++ b/storage/xtradb/buf/buf0flu.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@@ -1297,8 +1297,11 @@ buf_flush_try_neighbors(
/* fprintf(stderr, "Flush area: low %lu high %lu\n", low, high); */
- if (high > fil_space_get_size(space)) {
- high = fil_space_get_size(space);
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ high = s->max_page_number_for_io(high);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
ulint count = 0;
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index 13bf5e79f2d..9a577bc3010 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -1049,7 +1049,7 @@ buf_LRU_check_size_of_non_data_objects(
+ UT_LIST_GET_LEN(buf_pool->LRU))
< buf_pool->curr_size / 3) {
- if (!buf_lru_switched_on_innodb_mon) {
+ if (!buf_lru_switched_on_innodb_mon && srv_monitor_event) {
/* Over 67 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory
diff --git a/storage/xtradb/buf/buf0rea.cc b/storage/xtradb/buf/buf0rea.cc
index 1ef9162cab9..a962b94c0c2 100644
--- a/storage/xtradb/buf/buf0rea.cc
+++ b/storage/xtradb/buf/buf0rea.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -344,19 +344,22 @@ buf_read_ahead_random(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ /* Remember the tablespace version along with the
+ tablespace size: if DISCARD + IMPORT changes the
+ actual .ibd file meanwhile, we do not try to read
+ outside the bounds of the tablespace! */
+ tablespace_version = s->tablespace_version;
- tablespace_version = fil_space_get_version(space);
-
- low = (offset / buf_read_ahead_random_area)
- * buf_read_ahead_random_area;
- high = (offset / buf_read_ahead_random_area + 1)
- * buf_read_ahead_random_area;
- if (high > fil_space_get_size(space)) {
+ low = (offset / buf_read_ahead_random_area)
+ * buf_read_ahead_random_area;
+ high = (offset / buf_read_ahead_random_area + 1)
+ * buf_read_ahead_random_area;
+ high = s->max_page_number_for_io(high);
- high = fil_space_get_size(space);
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
}
if (buf_pool->n_pend_reads
@@ -495,22 +498,16 @@ buf_read_page(
ulint offset,
trx_t* trx)
{
- ib_int64_t tablespace_version;
- ulint count;
dberr_t err = DB_SUCCESS;
- tablespace_version = fil_space_get_version(space_id);
-
FilSpace space(space_id, true);
if (space()) {
-
- /* We do the i/o in the synchronous aio mode to save thread
- switches: hence TRUE */
- count = buf_read_page_low(&err, true, BUF_READ_ANY_PAGE, space_id,
- zip_size, FALSE,
- tablespace_version, offset, trx);
-
+ ulint count = buf_read_page_low(&err, /*sync=*/true,
+ BUF_READ_ANY_PAGE,
+ space_id, zip_size, FALSE,
+ space()->tablespace_version,
+ offset, trx);
srv_stats.buf_pool_reads.add(count);
}
@@ -683,13 +680,23 @@ buf_read_ahead_linear(
return(0);
}
- /* Remember the tablespace version before we ask te tablespace size
- below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
- do not try to read outside the bounds of the tablespace! */
+ uint32_t space_high_limit = 0;
- tablespace_version = fil_space_get_version(space);
+ if (fil_space_t *s = fil_space_acquire_for_io(space)) {
+ /* Remember the tablespace version along with the
+ tablespace size: if DISCARD + IMPORT changes the
+ actual .ibd file meanwhile, we do not try to read
+ outside the bounds of the tablespace! */
+ tablespace_version = s->tablespace_version;
+
+ space_high_limit = s->max_page_number_for_io(ULINT_UNDEFINED);
+
+ fil_space_release_for_io(s);
+ } else {
+ return 0;
+ }
- if (high > fil_space_get_size(space)) {
+ if (high > space_high_limit) {
/* The area is not whole, return */
return(0);
@@ -825,7 +832,7 @@ buf_read_ahead_linear(
return(0);
}
- if (high > fil_space_get_size(space)) {
+ if (high > space_high_limit) {
/* The area is not whole, return */
return(0);
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 2bea154749f..6d0500589b1 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -604,7 +604,10 @@ dict_table_close(
mutex_exit(&dict_sys->mutex);
- if (drop_aborted) {
+ /* dict_table_try_drop_aborted() can generate undo logs.
+ So it should be avoided after shutdown of background
+ threads */
+ if (drop_aborted && srv_undo_sources) {
dict_table_try_drop_aborted(NULL, table_id, 0);
}
}
diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc
index f4bbc5c8f06..82480b13827 100644
--- a/storage/xtradb/dict/dict0mem.cc
+++ b/storage/xtradb/dict/dict0mem.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -416,15 +416,14 @@ dict_mem_table_col_rename_low(
}
}
- dict_index_t* new_index = dict_foreign_find_index(
+ /* New index can be null if XtraDB already dropped
+ the foreign index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->foreign_index = dict_foreign_find_index(
foreign->foreign_table, NULL,
foreign->foreign_col_names,
foreign->n_fields, NULL, true, false,
NULL, NULL, NULL);
- /* There must be an equivalent index in this case. */
- ut_ad(new_index != NULL);
-
- foreign->foreign_index = new_index;
} else {
@@ -447,7 +446,41 @@ dict_mem_table_col_rename_low(
foreign = *it;
- ut_ad(foreign->referenced_index != NULL);
+ if (!foreign->referenced_index) {
+ /* Referenced index could have been dropped
+ when foreign_key_checks is disabled. In that case,
+ rename the corresponding referenced_col_names and
+ find the equivalent referenced index also */
+ for (unsigned f = 0; f < foreign->n_fields; f++) {
+
+ const char*& rc =
+ foreign->referenced_col_names[f];
+
+ if (strcmp(rc, from)) {
+ continue;
+ }
+
+ if (to_len <= strlen(rc)) {
+ memcpy(const_cast<char*>(rc), to,
+ to_len + 1);
+ } else {
+ rc = static_cast<char*>(
+ mem_heap_dup(
+ foreign->heap,
+ to, to_len + 1));
+ }
+ }
+
+ /* New index can be null if InnoDB already dropped
+ the referenced index when FOREIGN_KEY_CHECKS is
+ disabled */
+ foreign->referenced_index = dict_foreign_find_index(
+ foreign->referenced_table, NULL,
+ foreign->referenced_col_names,
+ foreign->n_fields, NULL, true, false,
+ NULL, NULL, NULL);
+ return;
+ }
for (unsigned f = 0; f < foreign->n_fields; f++) {
/* foreign->referenced_col_names[] need to be
@@ -820,3 +853,22 @@ operator<< (std::ostream& out, const dict_foreign_set& fk_set)
return(out);
}
+/** Check whether fulltext index gets affected by foreign
+key constraint. */
+bool dict_foreign_t::affects_fulltext() const
+{
+ if (foreign_table == referenced_table || !foreign_table->fts)
+ return false;
+
+ for (ulint i = 0; i < n_fields; i++)
+ {
+ if (dict_table_is_fts_column(
+ foreign_table->fts->indexes,
+ dict_index_get_nth_col_no(foreign_index, i))
+ != ULINT_UNDEFINED)
+ return true;
+ }
+
+ return false;
+}
+
diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc
index 43a3bd8ff29..fc7ef41786e 100644
--- a/storage/xtradb/fil/fil0crypt.cc
+++ b/storage/xtradb/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -44,15 +44,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
#include "ha_prototypes.h" // IB_LOG_
#include <my_crypt.h>
-/** Mutex for keys */
-static ib_mutex_t fil_crypt_key_mutex;
-
static bool fil_crypt_threads_inited = false;
-#ifdef UNIV_PFS_MUTEX
-static mysql_pfs_key_t fil_crypt_key_mutex_key;
-#endif
-
/** Is encryption enabled/disabled */
UNIV_INTERN ulong srv_encrypt_tables = 0;
@@ -133,9 +126,6 @@ UNIV_INTERN
void
fil_space_crypt_init()
{
- mutex_create(fil_crypt_key_mutex_key,
- &fil_crypt_key_mutex, SYNC_NO_ORDER_CHECK);
-
fil_crypt_throttle_sleep_event = os_event_create();
mutex_create(fil_crypt_stat_mutex_key,
@@ -152,7 +142,6 @@ fil_space_crypt_cleanup()
{
os_event_free(fil_crypt_throttle_sleep_event);
fil_crypt_throttle_sleep_event = NULL;
- mutex_free(&fil_crypt_key_mutex);
mutex_free(&crypt_stat_mutex);
}
@@ -706,47 +695,8 @@ fil_space_encrypt(
fil_space_crypt_t* crypt_data = space->crypt_data;
ut_ad(space->n_pending_ios > 0);
ulint zip_size = fsp_flags_get_zip_size(space->flags);
- byte* tmp = fil_encrypt_buf(crypt_data, space->id, offset, lsn, src_frame, zip_size, dst_frame);
-
-#ifdef UNIV_DEBUG
- if (tmp) {
- /* Verify that encrypted buffer is not corrupted */
- dberr_t err = DB_SUCCESS;
- byte* src = src_frame;
- bool page_compressed_encrypted = (mach_read_from_2(tmp+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED);
- byte uncomp_mem[UNIV_PAGE_SIZE_MAX];
- byte tmp_mem[UNIV_PAGE_SIZE_MAX];
- ulint size = (zip_size) ? zip_size : UNIV_PAGE_SIZE;
-
- if (page_compressed_encrypted) {
- memcpy(uncomp_mem, src, srv_page_size);
- ulint unzipped1 = fil_page_decompress(
- tmp_mem, uncomp_mem);
- ut_ad(unzipped1);
- if (unzipped1 != srv_page_size) {
- src = uncomp_mem;
- }
- }
-
- ut_ad(!buf_page_is_corrupted(true, src, zip_size, space));
- ut_ad(fil_space_decrypt(crypt_data, tmp_mem, size, tmp, &err));
- ut_ad(err == DB_SUCCESS);
-
- /* Need to decompress the page if it was also compressed */
- if (page_compressed_encrypted) {
- byte buf[UNIV_PAGE_SIZE_MAX];
- memcpy(buf, tmp_mem, srv_page_size);
- ulint unzipped2 = fil_page_decompress(tmp_mem, buf);
- ut_ad(unzipped2);
- }
-
- memcpy(tmp_mem + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,
- src + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 8);
- ut_ad(!memcmp(src, tmp_mem, size));
- }
-#endif /* UNIV_DEBUG */
-
- return tmp;
+ return fil_encrypt_buf(crypt_data, space->id, offset, lsn,
+ src_frame, zip_size, dst_frame);
}
/******************************************************************
@@ -1490,6 +1440,109 @@ fil_crypt_return_iops(
fil_crypt_update_total_stat(state);
}
+/** Remove space from key rotation list if there are no pending operations. */
+static void fil_space_remove_from_keyrotation(fil_space_t *space)
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ if (space->n_pending_ops == 0 && space->is_in_rotation_list)
+ {
+ space->is_in_rotation_list= false;
+ ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
+ UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
+ }
+}
+
+/** Return the next tablespace from key rotation list.
+@param space previous tablespace (NULL to start from the beginning)
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_keyrotate_next(fil_space_t *space)
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0)
+ {
+ if (space)
+ {
+ space->n_pending_ops--;
+ fil_space_remove_from_keyrotation(space);
+ }
+
+ return NULL;
+ }
+
+ if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->rotation_list);
+ /* We can trust that space is not NULL because we
+ checked list length above */
+ }
+ else
+ {
+ space->n_pending_ops--;
+ fil_space_t *old = space;
+ space= UT_LIST_GET_NEXT(rotation_list, space);
+ fil_space_remove_from_keyrotation(old);
+ }
+
+ /* Skip spaces that are being created by fil_ibd_create(),
+ or dropped. Note that rotation_list contains only
+ space->purpose == FIL_TABLESPACE. */
+ while (space && (!UT_LIST_GET_LEN(space->chain) || space->is_stopping()))
+ {
+ fil_space_t *old = space;
+ space= UT_LIST_GET_NEXT(rotation_list, space);
+ fil_space_remove_from_keyrotation(old);
+ }
+
+ if (space)
+ space->n_pending_ops++;
+
+ return space;
+}
+
+/** Return the next tablespace.
+@param space previous tablespace (NULL to start from the beginning)
+@return pointer to the next tablespace (with n_pending_ops incremented)
+@retval NULL if this was the last */
+static fil_space_t *fil_space_next(fil_space_t *space)
+{
+ mutex_enter(&fil_system->mutex);
+ ut_ad(!space || space->n_pending_ops);
+
+ if (!srv_fil_crypt_rotate_key_age)
+ space= fil_space_keyrotate_next(space);
+ else if (!space)
+ {
+ space= UT_LIST_GET_FIRST(fil_system->space_list);
+ /* We can trust that space is not NULL because at least the
+ system tablespace is always present and loaded first. */
+ space->n_pending_ops++;
+ }
+ else
+ {
+ ut_ad(space->n_pending_ops > 0);
+ /* Move on to the next fil_space_t */
+ space->n_pending_ops--;
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ /* Skip abnormal tablespaces or those that are being created by
+ fil_ibd_create(), or being dropped. */
+ while (space &&
+ (UT_LIST_GET_LEN(space->chain) == 0 ||
+ space->is_stopping() || space->purpose != FIL_TABLESPACE))
+ space= UT_LIST_GET_NEXT(space_list, space);
+
+ if (space)
+ space->n_pending_ops++;
+ }
+
+ mutex_exit(&fil_system->mutex);
+
+ return space;
+}
+
/***********************************************************************
Search for a space needing rotation
@param[in,out] key_state Key state
@@ -1524,14 +1577,7 @@ fil_crypt_find_space_to_rotate(
state->space = NULL;
}
- /* If key rotation is enabled (default) we iterate all tablespaces.
- If key rotation is not enabled we iterate only the tablespaces
- added to keyrotation list. */
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_space_keyrotate_next(state->space);
- }
+ state->space = fil_space_next(state->space);
while (!state->should_shutdown() && state->space) {
fil_crypt_read_crypt_data(state->space);
@@ -1544,14 +1590,15 @@ fil_crypt_find_space_to_rotate(
return true;
}
- if (srv_fil_crypt_rotate_key_age) {
- state->space = fil_space_next(state->space);
- } else {
- state->space = fil_space_keyrotate_next(state->space);
- }
+ state->space = fil_space_next(state->space);
+ }
+
+ if (state->space) {
+ fil_space_release(state->space);
+ state->space = NULL;
}
- /* if we didn't find any space return iops */
+ /* no work to do; release our allocation of I/O capacity */
fil_crypt_return_iops(state);
return false;
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 766e9d91cfb..41bc4cca8a6 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -684,7 +684,7 @@ fil_node_open_file(
#ifdef UNIV_HOTBACKUP
add_size:
#endif /* UNIV_HOTBACKUP */
- space->size += node->size;
+ space->committed_size = space->size += node->size;
}
ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(space->flags);
@@ -1158,6 +1158,9 @@ retry:
ut_a(success);
/* InnoDB data files cannot shrink. */
ut_a(space->size >= size);
+ if (size > space->committed_size) {
+ space->committed_size = size;
+ }
/* There could be multiple concurrent I/O requests for
this tablespace (multiple threads trying to extend
@@ -1815,25 +1818,6 @@ fil_space_get_zip_size(
return(flags);
}
-/*******************************************************************//**
-Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache.
-@return TRUE if the address is meaningful */
-UNIV_INTERN
-ibool
-fil_check_adress_in_tablespace(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint page_no)/*!< in: page number */
-{
- if (fil_space_get_size(id) > page_no) {
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
@@ -6879,137 +6863,3 @@ fil_space_release(fil_space_t* space)
space->n_pending_ops--;
mutex_exit(&fil_system->mutex);
}
-
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_next(fil_space_t* prev_space)
-{
- fil_space_t* space=prev_space;
-
- mutex_enter(&fil_system->mutex);
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->space_list);
-
- /* We can trust that space is not NULL because at least the
- system tablespace is always present and loaded first. */
- space->n_pending_ops++;
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
- space = UT_LIST_GET_NEXT(space_list, space);
-
- /* Skip spaces that are being created by
- fil_ibd_create(), or dropped, or !tablespace. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping()
- || space->purpose != FIL_TABLESPACE)) {
- space = UT_LIST_GET_NEXT(space_list, space);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
-
-/**
-Remove space from key rotation list if there are no more
-pending operations.
-@param[in] space Tablespace */
-static
-void
-fil_space_remove_from_keyrotation(
- fil_space_t* space)
-{
- ut_ad(mutex_own(&fil_system->mutex));
- ut_ad(space);
-
- if (space->n_pending_ops == 0 && space->is_in_rotation_list) {
- space->is_in_rotation_list = false;
- ut_a(UT_LIST_GET_LEN(fil_system->rotation_list) > 0);
- UT_LIST_REMOVE(rotation_list, fil_system->rotation_list, space);
- }
-}
-
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_keyrotate_next(
- fil_space_t* prev_space)
-{
- fil_space_t* space = prev_space;
- fil_space_t* old = NULL;
-
- mutex_enter(&fil_system->mutex);
-
- if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) {
- if (space) {
- ut_ad(space->n_pending_ops > 0);
- space->n_pending_ops--;
- fil_space_remove_from_keyrotation(space);
- }
- mutex_exit(&fil_system->mutex);
- return(NULL);
- }
-
- if (prev_space == NULL) {
- space = UT_LIST_GET_FIRST(fil_system->rotation_list);
-
- /* We can trust that space is not NULL because we
- checked list length above */
- } else {
- ut_ad(space->n_pending_ops > 0);
-
- /* Move on to the next fil_space_t */
- space->n_pending_ops--;
-
- old = space;
- space = UT_LIST_GET_NEXT(rotation_list, space);
-
- fil_space_remove_from_keyrotation(old);
- }
-
- /* Skip spaces that are being created by fil_ibd_create(),
- or dropped. Note that rotation_list contains only
- space->purpose == FIL_TABLESPACE. */
- while (space != NULL
- && (UT_LIST_GET_LEN(space->chain) == 0
- || space->is_stopping())) {
-
- old = space;
- space = UT_LIST_GET_NEXT(rotation_list, space);
- fil_space_remove_from_keyrotation(old);
- }
-
- if (space != NULL) {
- space->n_pending_ops++;
- }
-
- mutex_exit(&fil_system->mutex);
-
- return(space);
-}
diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc
index edc1fa913e7..656d1d46a6a 100644
--- a/storage/xtradb/fil/fil0pagecompress.cc
+++ b/storage/xtradb/fil/fil0pagecompress.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (C) 2013, 2018, MariaDB Corporation.
+Copyright (C) 2013, 2020, MariaDB Corporation.
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,24 +243,12 @@ success:
/* Set up the actual payload lenght */
mach_write_to_2(out_buf+FIL_PAGE_DATA, write_size);
-#ifdef UNIV_DEBUG
- /* Verify */
ut_ad(fil_page_is_compressed(out_buf) || fil_page_is_compressed_encrypted(out_buf));
ut_ad(mach_read_from_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM) == BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf+FIL_PAGE_DATA) == write_size);
ut_ad(mach_read_from_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) == (ulint)comp_method ||
mach_read_from_2(out_buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE) == (ulint)comp_method);
- /* Verify that page can be decompressed */
- {
- page_t tmp_buf[UNIV_PAGE_SIZE_MAX];
- page_t page[UNIV_PAGE_SIZE_MAX];
- memcpy(page, out_buf, srv_page_size);
- ut_ad(fil_page_decompress(tmp_buf, page));
- ut_ad(!buf_page_is_corrupted(false, page, 0, NULL));
- }
-#endif /* UNIV_DEBUG */
-
write_size+=header_len;
if (block_size <= 0) {
diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc
index fc2e192a3b1..e2e9709d5f2 100644
--- a/storage/xtradb/fsp/fsp0fsp.cc
+++ b/storage/xtradb/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -450,7 +450,7 @@ xdes_get_descriptor_with_space_hdr(
page_t* descr_page;
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET);
/* Read free limit and space size */
@@ -534,7 +534,7 @@ xdes_lst_get_descriptor(
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
descr = fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr)
- XDES_FLST_NODE;
@@ -690,7 +690,7 @@ fsp_header_init(ulint space_id, ulint size, mtr_t* mtr)
ut_ad(mtr);
- mtr_x_lock(fil_space_get_latch(space_id, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space_id, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
block = buf_page_create(space_id, 0, zip_size, mtr);
@@ -817,7 +817,7 @@ fsp_header_inc_size(
ut_ad(mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
header = fsp_get_space_header(space,
fsp_flags_get_zip_size(flags),
@@ -846,7 +846,7 @@ fsp_header_get_tablespace_size(void)
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(0, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(0, NULL), &mtr);
header = fsp_get_space_header(0, 0, &mtr);
@@ -1073,7 +1073,6 @@ fsp_fill_free_list(
ulint frag_n_used;
ulint actual_increase;
ulint i;
- mtr_t ibuf_mtr;
ut_ad(page_offset(header) == FSP_HEADER_OFFSET);
@@ -1141,26 +1140,17 @@ fsp_fill_free_list(
MLOG_2BYTES, mtr);
}
- /* Initialize the ibuf bitmap page in a separate
- mini-transaction because it is low in the latching
- order, and we must be able to release its latch
- before returning from the fsp routine */
-
- mtr_start(&ibuf_mtr);
-
block = buf_page_create(space,
- i + FSP_IBUF_BITMAP_OFFSET,
- zip_size, &ibuf_mtr);
+ i + FSP_IBUF_BITMAP_OFFSET,
+ zip_size, mtr);
buf_page_get(space, zip_size,
i + FSP_IBUF_BITMAP_OFFSET,
- RW_X_LATCH, &ibuf_mtr);
+ RW_X_LATCH, mtr);
buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
- fsp_init_file_page(block, &ibuf_mtr);
+ fsp_init_file_page(block, mtr);
- ibuf_bitmap_page_init(block, &ibuf_mtr);
-
- mtr_commit(&ibuf_mtr);
+ ibuf_bitmap_page_init(block, mtr);
}
descr = xdes_get_descriptor_with_space_hdr(header, space, i,
@@ -2047,7 +2037,7 @@ fseg_create_general(
header = byte_offset + buf_block_get_frame(block);
}
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
if (!has_done_reservation) {
success = fsp_reserve_free_extents(&n_reserved, space, 2,
@@ -2194,7 +2184,7 @@ fseg_n_reserved_pages(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -2617,7 +2607,7 @@ fseg_alloc_free_page_general(
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(seg_header, space, zip_size, mtr);
@@ -2734,7 +2724,7 @@ fsp_reserve_free_extents(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
space_header = fsp_get_space_header(space, zip_size, mtr);
try_again:
@@ -2873,7 +2863,7 @@ fsp_get_available_space_in_free_extents(
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
mutex_exit(&dict_sys->mutex);
@@ -3169,7 +3159,7 @@ fseg_free_page(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
@@ -3203,7 +3193,7 @@ fseg_page_is_free(
zip_size = dict_tf_get_zip_size(flags);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode = fseg_inode_get(seg_header, space, zip_size, &mtr);
@@ -3328,7 +3318,7 @@ fseg_free_step(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
@@ -3415,7 +3405,7 @@ fseg_free_step_not_header(
latch = fil_space_get_latch(space, &flags);
zip_size = fsp_flags_get_zip_size(flags);
- mtr_x_lock(latch, mtr);
+ mtr_x_space_lock(latch, mtr);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3541,7 +3531,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3564,7 +3554,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3590,7 +3580,7 @@ fseg_validate_low(
ulint zip_size;
mtr_start(&mtr);
- mtr_x_lock(fil_space_get_latch(space, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3628,7 +3618,7 @@ fseg_validate(
space = page_get_space_id(page_align(header));
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3704,7 +3694,7 @@ fseg_print(
space = page_get_space_id(page_align(header));
- mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, &flags), mtr);
zip_size = fsp_flags_get_zip_size(flags);
inode = fseg_inode_get(header, space, zip_size, mtr);
@@ -3753,10 +3743,10 @@ fsp_validate(
/* Start first a mini-transaction mtr2 to lock out all other threads
from the fsp system */
mtr_start(&mtr2);
- mtr_x_lock(latch, &mtr2);
+ mtr_x_space_lock(latch, &mtr2);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3783,7 +3773,7 @@ fsp_validate(
/* Validate FSP_FREE list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FREE, &mtr);
@@ -3792,7 +3782,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3807,7 +3797,7 @@ fsp_validate(
/* Validate FSP_FREE_FRAG list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr);
@@ -3816,7 +3806,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3834,7 +3824,7 @@ fsp_validate(
/* Validate FSP_FULL_FRAG list */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr);
@@ -3843,7 +3833,7 @@ fsp_validate(
while (!fil_addr_is_null(node_addr)) {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
descr_count++;
descr = xdes_lst_get_descriptor(space, zip_size,
@@ -3858,7 +3848,7 @@ fsp_validate(
/* Validate segments */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3873,7 +3863,7 @@ fsp_validate(
n = 0;
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -3902,7 +3892,7 @@ fsp_validate(
}
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -3918,7 +3908,7 @@ fsp_validate(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4002,11 +3992,11 @@ fsp_print(
mtr_start(&mtr2);
- mtr_x_lock(latch, &mtr2);
+ mtr_x_space_lock(latch, &mtr2);
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4038,7 +4028,7 @@ fsp_print(
/* Print segments */
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4053,7 +4043,7 @@ fsp_print(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4075,7 +4065,7 @@ fsp_print(
}
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
header = fsp_get_space_header(space, zip_size, &mtr);
@@ -4090,7 +4080,7 @@ fsp_print(
do {
mtr_start(&mtr);
- mtr_x_lock(latch, &mtr);
+ mtr_x_space_lock(latch, &mtr);
seg_inode_page = fut_get_ptr(
space, zip_size, node_addr, RW_X_LATCH, &mtr)
@@ -4147,7 +4137,8 @@ fsp_page_is_free_func(
ut_ad(mtr);
- mtr_x_lock_func(fil_space_get_latch(space, &flags), file, line, mtr);
+ mtr_x_space_lock_func(fil_space_get_latch(space, &flags), file, line,
+ mtr);
ulint zip_size = fsp_flags_get_zip_size(flags);
xdes_t* descr = xdes_get_descriptor(space, zip_size, page_no, mtr);
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 6dbe5e0e2a0..2a1341c4cf0 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -443,9 +443,9 @@ fts_read_stopword(
/******************************************************************//**
Load user defined stopword from designated user table
-@return TRUE if load operation is successful */
+@return whether the operation is successful */
static
-ibool
+bool
fts_load_user_stopword(
/*===================*/
fts_t* fts, /*!< in: FTS struct */
@@ -453,27 +453,26 @@ fts_load_user_stopword(
name */
fts_stopword_t* stopword_info) /*!< in: Stopword info */
{
- pars_info_t* info;
- que_t* graph;
- dberr_t error = DB_SUCCESS;
- ibool ret = TRUE;
- trx_t* trx;
- ibool has_lock = fts->dict_locked;
-
- trx = trx_allocate_for_background();
- trx->op_info = "Load user stopword table into FTS cache";
-
- if (!has_lock) {
+ if (!fts->dict_locked) {
mutex_enter(&dict_sys->mutex);
}
- /* Validate the user table existence and in the right
- format */
+ /* Validate the user table existence in the right format */
+ bool ret= false;
stopword_info->charset = fts_valid_stopword_table(stopword_table_name);
if (!stopword_info->charset) {
- ret = FALSE;
- goto cleanup;
- } else if (!stopword_info->cached_stopword) {
+cleanup:
+ if (!fts->dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
+
+ return ret;
+ }
+
+ trx_t* trx = trx_allocate_for_background();
+ trx->op_info = "Load user stopword table into FTS cache";
+
+ if (!stopword_info->cached_stopword) {
/* Create the stopword RB tree with the stopword column
charset. All comparison will use this charset */
stopword_info->cached_stopword = rbt_create_arg_cmp(
@@ -482,14 +481,14 @@ fts_load_user_stopword(
}
- info = pars_info_create();
+ pars_info_t* info = pars_info_create();
pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name);
pars_info_bind_function(info, "my_func", fts_read_stopword,
stopword_info);
- graph = fts_parse_sql_no_dict_lock(
+ que_t* graph = fts_parse_sql_no_dict_lock(
NULL,
info,
"DECLARE FUNCTION my_func;\n"
@@ -508,14 +507,13 @@ fts_load_user_stopword(
"CLOSE c;");
for (;;) {
- error = fts_eval_sql(trx, graph);
+ dberr_t error = fts_eval_sql(trx, graph);
if (error == DB_SUCCESS) {
fts_sql_commit(trx);
stopword_info->status = STOPWORD_USER_TABLE;
break;
} else {
-
fts_sql_rollback(trx);
ut_print_timestamp(stderr);
@@ -537,14 +535,9 @@ fts_load_user_stopword(
}
que_graph_free(graph);
-
-cleanup:
- if (!has_lock) {
- mutex_exit(&dict_sys->mutex);
- }
-
trx_free_for_background(trx);
- return(ret);
+ ret = true;
+ goto cleanup;
}
/******************************************************************//**
@@ -1134,14 +1127,14 @@ fts_cache_clear(
index_cache->doc_stats = NULL;
}
- mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
- cache->sync_heap->arg = NULL;
-
cache->total_size = 0;
mutex_enter((ib_mutex_t*) &cache->deleted_lock);
cache->deleted_doc_ids = NULL;
mutex_exit((ib_mutex_t*) &cache->deleted_lock);
+
+ mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
+ cache->sync_heap->arg = NULL;
}
/*********************************************************************//**
@@ -3495,8 +3488,8 @@ fts_add_doc_by_id(
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL,
- NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL,
+ NULL, true, true);
}
fts_cache_add_doc(
@@ -7244,21 +7237,19 @@ This function loads the stopword into the FTS cache. It also
records/fetches stopword configuration to/from FTS configure
table, depending on whether we are creating or reloading the
FTS.
-@return TRUE if load operation is successful */
+@return true if load operation is successful */
UNIV_INTERN
-ibool
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transactions */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload) /*!< in: Whether it is
+ bool reload) /*!< in: Whether it is
for reloading FTS table */
{
fts_table_t fts_table;
@@ -7274,9 +7265,8 @@ fts_load_stopword(
cache = table->fts->cache;
- if (!reload && !(cache->stopword_info.status
- & STOPWORD_NOT_INIT)) {
- return(TRUE);
+ if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) {
+ return true;
}
if (!trx) {
@@ -7321,12 +7311,11 @@ fts_load_stopword(
goto cleanup;
}
- if (strlen((char*) str.f_str) > 0) {
+ if (*str.f_str) {
stopword_to_use = (const char*) str.f_str;
}
} else {
- stopword_to_use = (session_stopword_table)
- ? session_stopword_table : global_stopword_table;
+ stopword_to_use = session_stopword_table;
}
if (stopword_to_use
@@ -7363,7 +7352,7 @@ cleanup:
sizeof(fts_tokenizer_word_t), fts_utf8_string_cmp);
}
- return(error == DB_SUCCESS);
+ return error == DB_SUCCESS;
}
/**********************************************************************//**
@@ -7569,7 +7558,7 @@ fts_init_index(
} else {
if (table->fts->cache->stopword_info.status
& STOPWORD_NOT_INIT) {
- fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE);
+ fts_load_stopword(table, NULL, NULL, true, true);
}
for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) {
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index 8fce8efac2b..0c51e702907 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2007, 2020, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -146,6 +146,8 @@ struct fts_query_t {
fts_word_freq_t */
bool multi_exist; /*!< multiple FTS_EXIST oper */
+ byte visiting_sub_exp; /*!< count of nested
+ fts_ast_visit_sub_exp() */
};
/** For phrase matching, first we collect the documents and the positions
@@ -2856,6 +2858,8 @@ fts_query_get_token(
return(new_ptr);
}
+static dberr_t fts_ast_visit_sub_exp(fts_ast_node_t*, fts_ast_callback, void*);
+
/*****************************************************************//**
Visit every node of the AST. */
static
@@ -2945,7 +2949,7 @@ Process (nested) sub-expression, create a new result set to store the
sub-expression result by processing nodes under current sub-expression
list. Merge the sub-expression result with that of parent expression list.
@return DB_SUCCESS if all well */
-UNIV_INTERN
+static
dberr_t
fts_ast_visit_sub_exp(
/*==================*/
@@ -2965,6 +2969,14 @@ fts_ast_visit_sub_exp(
ut_a(node->type == FTS_AST_SUBEXP_LIST);
+ /* To avoid stack overflow, we limit the mutual recursion
+ depth between fts_ast_visit(), fts_query_visitor() and
+ fts_ast_visit_sub_exp(). */
+ if (query->visiting_sub_exp++ > 31) {
+ query->error = DB_OUT_OF_MEMORY;
+ DBUG_RETURN(query->error);
+ }
+
cur_oper = query->oper;
/* Save current result set */
@@ -2987,6 +2999,7 @@ fts_ast_visit_sub_exp(
/* Reinstate parent node state */
query->multi_exist = multi_exist;
query->oper = cur_oper;
+ query->visiting_sub_exp--;
/* Merge the sub-expression result with the parent result set. */
subexpr_doc_ids = query->doc_ids;
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 2aafb1a44ee..44c0c8d5bc5 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1,11 +1,10 @@
/*****************************************************************************
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1934,8 +1933,7 @@ innobase_srv_conc_enter_innodb(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1973,8 +1971,7 @@ innobase_srv_conc_exit_innodb(
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
#endif /* UNIV_SYNC_DEBUG */
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
@@ -2950,6 +2947,9 @@ innobase_trx_init(
trx->check_unique_secondary = !thd_test_options(
thd, OPTION_RELAXED_UNIQUE_CHECKS);
+#ifdef WITH_WSREP
+ trx->wsrep = wsrep_on(thd);
+#endif
/* Transaction on start caches the fake_changes state and uses it for
complete transaction lifetime.
@@ -4676,20 +4676,9 @@ innobase_commit_low(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0;
- if (thd && wsrep_on(thd)) {
-#ifdef WSREP_PROC_INFO
- char info[64];
- info[sizeof(info) - 1] = '\0';
- snprintf(info, sizeof(info) - 1,
- "innobase_commit_low():trx_commit_for_mysql(%lld)",
- (long long) wsrep_thd_trx_seqno(thd));
- tmp = thd_proc_info(thd, info);
-
-#else
- tmp = thd_proc_info(thd, "innobase_commit_low()");
-#endif /* WSREP_PROC_INFO */
+ if (trx->is_wsrep()) {
+ tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
}
#endif /* WITH_WSREP */
if (trx_is_started(trx)) {
@@ -4697,7 +4686,7 @@ innobase_commit_low(
trx_commit_for_mysql(trx);
}
#ifdef WITH_WSREP
- if (thd && wsrep_on(thd)) { thd_proc_info(thd, tmp); }
+ if (trx->is_wsrep()) { thd_proc_info(trx->mysql_thd, tmp); }
#endif /* WITH_WSREP */
}
@@ -8713,19 +8702,19 @@ ha_innobase::write_row(
sql_command = thd_sql_command(user_thd);
- if ((sql_command == SQLCOM_ALTER_TABLE
- || sql_command == SQLCOM_OPTIMIZE
- || sql_command == SQLCOM_CREATE_INDEX
+ if (num_write_row >= 10000
+ && (sql_command == SQLCOM_ALTER_TABLE
+ || sql_command == SQLCOM_OPTIMIZE
+ || sql_command == SQLCOM_CREATE_INDEX
#ifdef WITH_WSREP
- || (wsrep_on(user_thd) && wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
- !thd_test_options(
- user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
+ || (sql_command == SQLCOM_LOAD &&
+ trx->is_wsrep() && wsrep_load_data_splitting &&
+ !thd_test_options(
+ user_thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
#endif /* WITH_WSREP */
- || sql_command == SQLCOM_DROP_INDEX)
- && num_write_row >= 10000) {
+ || sql_command == SQLCOM_DROP_INDEX)) {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) && sql_command == SQLCOM_LOAD) {
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep()) {
WSREP_DEBUG("forced trx split for LOAD: %s",
wsrep_thd_query(user_thd));
}
@@ -8764,9 +8753,8 @@ no_commit:
;
} else if (src_table == prebuilt->table) {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep() &&
+ wsrep_load_data_splitting &&
!thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
@@ -8796,9 +8784,8 @@ no_commit:
prebuilt->sql_stat_start = TRUE;
} else {
#ifdef WITH_WSREP
- if (wsrep_on(user_thd) &&
- wsrep_load_data_splitting &&
- sql_command == SQLCOM_LOAD &&
+ if (sql_command == SQLCOM_LOAD && trx->is_wsrep() &&
+ wsrep_load_data_splitting &&
!thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
@@ -8943,21 +8930,19 @@ no_commit:
prebuilt->autoinc_offset,
prebuilt->autoinc_increment);
- if (wsrep_on(current_thd) &&
+ if (trx->is_wsrep() &&
auto_inc_inserted &&
wsrep_drupal_282555_workaround &&
- wsrep_thd_retry_counter(current_thd) == 0 &&
- !thd_test_options(current_thd,
+ wsrep_thd_retry_counter(user_thd) == 0 &&
+ !thd_test_options(user_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
WSREP_DEBUG(
"retrying insert: %s",
- (*wsrep_thd_query(current_thd)) ?
- wsrep_thd_query(current_thd) :
- (char *)"void");
+ wsrep_thd_query(user_thd));
error= DB_SUCCESS;
wsrep_thd_set_conflict_state(
- current_thd, MUST_ABORT);
+ user_thd, MUST_ABORT);
innobase_srv_conc_exit_innodb(prebuilt->trx);
/* jump straight to func exit over
* later wsrep hooks */
@@ -8995,7 +8980,7 @@ set_max_autoinc:
prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
- if (wsrep_on(user_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == REPL_RECV)
{
wsrep_thd_auto_increment_variables(
@@ -9044,18 +9029,16 @@ report_error:
user_thd);
#ifdef WITH_WSREP
- if (!error_result
- && wsrep_on(user_thd)
- && wsrep_thd_exec_mode(user_thd) == LOCAL_STATE
+ if (!error_result && trx->is_wsrep()
+ && wsrep_thd_exec_mode(user_thd) == LOCAL_STATE
&& !wsrep_consistency_check(user_thd)
&& !wsrep_thd_ignore_table(user_thd)) {
if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record, NULL)) {
DBUG_PRINT("wsrep", ("row key failed"));
error_result = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ goto func_exit;
}
}
-wsrep_error:
#endif /* WITH_WSREP */
if (error_result == HA_FTS_INVALID_DOCID) {
@@ -9536,7 +9519,7 @@ ha_innobase::update_row(
prebuilt autoinc values don't get
properly assigned. Fetch values from
server side. */
- if (wsrep_on(user_thd) &&
+ if (trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == REPL_RECV)
{
wsrep_thd_auto_increment_variables(
@@ -9581,9 +9564,8 @@ func_exit:
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == LOCAL_STATE &&
- wsrep_on(user_thd) &&
!wsrep_thd_ignore_table(user_thd))
{
DBUG_PRINT("wsrep", ("update row key"));
@@ -9592,11 +9574,9 @@ func_exit:
new_row)) {
WSREP_DEBUG("WSREP: UPDATE_ROW_KEY FAILED");
DBUG_PRINT("wsrep", ("row key failed"));
- err = HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
DBUG_RETURN(err);
@@ -9643,25 +9623,20 @@ ha_innobase::delete_row(
/* Tell the InnoDB server that there might be work for
utility threads: */
-
innobase_active_small();
#ifdef WITH_WSREP
- if (error == DB_SUCCESS &&
+ if (error == DB_SUCCESS && trx->is_wsrep() &&
wsrep_thd_exec_mode(user_thd) == LOCAL_STATE &&
- wsrep_on(user_thd) &&
!wsrep_thd_ignore_table(user_thd))
{
if (wsrep_append_keys(user_thd, WSREP_KEY_EXCLUSIVE, record,
- NULL)) {
+ NULL)) {
DBUG_PRINT("wsrep", ("delete fail"));
- error = (dberr_t) HA_ERR_INTERNAL_ERROR;
- goto wsrep_error;
+ DBUG_RETURN(HA_ERR_INTERNAL_ERROR);
}
}
-wsrep_error:
#endif /* WITH_WSREP */
-
DBUG_RETURN(convert_error_code_to_mysql(
error, prebuilt->table->flags, user_thd));
}
@@ -10917,8 +10892,7 @@ wsrep_append_foreign_key(
int cache_key_len;
bool const copy = true;
- if (!wsrep_on(trx->mysql_thd) ||
- wsrep_thd_exec_mode(thd) != LOCAL_STATE)
+ if (!trx->is_wsrep() || wsrep_thd_exec_mode(thd) != LOCAL_STATE)
return DB_SUCCESS;
if (!thd || !foreign ||
@@ -12073,10 +12047,17 @@ innobase_fts_load_stopword(
trx_t* trx, /*!< in: transaction */
THD* thd) /*!< in: current thread */
{
- return(fts_load_stopword(table, trx,
- innobase_server_stopword_table,
- THDVAR(thd, ft_user_stopword_table),
- THDVAR(thd, ft_enable_stopword), FALSE));
+ const char *stopword_table= THDVAR(thd, ft_user_stopword_table);
+ if (!stopword_table)
+ {
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ if (innobase_server_stopword_table)
+ stopword_table= thd_strdup(thd, innobase_server_stopword_table);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ }
+
+ return fts_load_stopword(table, trx, stopword_table,
+ THDVAR(thd, ft_enable_stopword), false);
}
/*****************************************************************//**
@@ -15541,12 +15522,11 @@ ha_innobase::external_lock(
THD* thd, /*!< in: handle to the user thread */
int lock_type) /*!< in: lock type */
{
- trx_t* trx;
-
DBUG_ENTER("ha_innobase::external_lock");
DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd);
+ trx_t* trx = prebuilt->trx;
/* Statement based binlogging does not work in isolation level
READ UNCOMMITTED and READ COMMITTED since the necessary
@@ -15560,22 +15540,19 @@ ha_innobase::external_lock(
&& thd_binlog_format(thd) == BINLOG_FORMAT_STMT
&& thd_binlog_filter_ok(thd)
&& thd_sqlcom_can_generate_row_events(thd)) {
- bool skip = 0;
+ bool skip = false;
+#ifdef WITH_WSREP
+ skip = trx->is_wsrep()
+ && wsrep_thd_exec_mode(thd) != LOCAL_STATE;
+#endif /* WITH_WSREP */
/* used by test case */
DBUG_EXECUTE_IF("no_innodb_binlog_errors", skip = true;);
if (!skip) {
-#ifdef WITH_WSREP
- if (!wsrep_on(thd) || wsrep_thd_exec_mode(thd) == LOCAL_STATE)
- {
-#endif /* WITH_WSREP */
- my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
- " InnoDB is limited to row-logging when "
- "transaction isolation level is "
- "READ COMMITTED or READ UNCOMMITTED.");
- DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
-#ifdef WITH_WSREP
- }
-#endif /* WITH_WSREP */
+ my_error(ER_BINLOG_STMT_MODE_AND_ROW_ENGINE, MYF(0),
+ " InnoDB is limited to row-logging when "
+ "transaction isolation level is "
+ "READ COMMITTED or READ UNCOMMITTED.");
+ DBUG_RETURN(HA_ERR_LOGGING_IMPOSSIBLE);
}
}
@@ -15606,8 +15583,6 @@ ha_innobase::external_lock(
}
- trx = prebuilt->trx;
-
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
@@ -17789,7 +17764,6 @@ innodb_stopword_table_validate(
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
trx_t* trx;
- int ret = 1;
ut_a(save != NULL);
ut_a(value != NULL);
@@ -17802,14 +17776,22 @@ innodb_stopword_table_validate(
/* Validate the stopword table's (if supplied) existence and
of the right format */
- if (!stopword_table_name
- || fts_valid_stopword_table(stopword_table_name)) {
- *static_cast<const char**>(save) = stopword_table_name;
- ret = 0;
- }
+ int ret = stopword_table_name && !fts_valid_stopword_table(
+ stopword_table_name);
row_mysql_unlock_data_dictionary(trx);
+ if (!ret) {
+ if (stopword_table_name == buff) {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ stopword_table_name = thd_strmake(thd,
+ stopword_table_name,
+ len);
+ }
+
+ *static_cast<const char**>(save) = stopword_table_name;
+ }
+
return(ret);
}
@@ -17817,9 +17799,10 @@ innodb_stopword_table_validate(
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
+@param[in,out] thd connection
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
-static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
+static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
char buf[STRING_BUFFER_USUAL_SIZE];
@@ -17833,6 +17816,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
+ if (table_name == buf) {
+ ut_ad(static_cast<size_t>(len)
+ < sizeof buf);
+ table_name = thd_strmake(thd,
+ table_name,
+ len);
+ }
+
+
*static_cast<const char**>(save) = table_name;
return 0;
}
@@ -18531,52 +18523,43 @@ exit:
return;
}
-#ifdef __WIN__
-/*************************************************************//**
-Validate if passed-in "value" is a valid value for
-innodb_buffer_pool_filename. On Windows, file names with colon (:)
-are not allowed.
-
+/** Validate SET GLOBAL innodb_buffer_pool_filename.
+On Windows, file names with colon (:) are not allowed.
+@param thd connection
+@param save &srv_buf_dump_filename
+@param value new value to be validated
@return 0 for valid name */
-static
-int
-innodb_srv_buf_dump_filename_validate(
-/*==================================*/
- THD* thd, /*!< in: thread handle */
- struct st_mysql_sys_var* var, /*!< in: pointer to system
- variable */
- void* save, /*!< out: immediate result
- for update function */
- struct st_mysql_value* value) /*!< in: incoming string */
+static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*,
+ void *save,
+ st_mysql_value *value)
{
- const char* buf_name;
- char buff[OS_FILE_MAX_PATH];
- int len= sizeof(buff);
-
- ut_a(save != NULL);
- ut_a(value != NULL);
-
- buf_name = value->val_str(value, buff, &len);
-
- if (buf_name) {
- if (is_filename_allowed(buf_name, len, FALSE)){
- *static_cast<const char**>(save) = buf_name;
- return(0);
- } else {
- push_warning_printf(thd,
- Sql_condition::WARN_LEVEL_WARN,
- ER_WRONG_ARGUMENTS,
- "InnoDB: innodb_buffer_pool_filename "
- "cannot have colon (:) in the file name.");
+ char buff[OS_FILE_MAX_PATH];
+ int len= sizeof buff;
- }
- }
+ if (const char *buf_name= value->val_str(value, buff, &len))
+ {
+#ifdef __WIN__
+ if (!is_filename_allowed(buf_name, len, FALSE))
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "InnoDB: innodb_buffer_pool_filename "
+ "cannot have colon (:) in the file name.");
+ return 1;
+ }
+#endif /* __WIN__ */
+ if (buf_name == buff)
+ {
+ ut_ad(static_cast<size_t>(len) < sizeof buff);
+ buf_name= thd_strmake(thd, buf_name, len);
+ }
+
+ *static_cast<const char**>(save)= buf_name;
+ return 0;
+ }
- return(1);
+ return 1;
}
-#else /* __WIN__ */
-# define innodb_srv_buf_dump_filename_validate NULL
-#endif /* __WIN__ */
#ifdef UNIV_DEBUG
static char* srv_buffer_pool_evict;
@@ -19465,11 +19448,14 @@ static
void
innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save)
{
- *static_cast<my_bool*>(var) = *static_cast<const my_bool*>(save);
- mysql_mutex_unlock(&LOCK_global_system_variables);
- /* Wakeup server monitor thread. */
- os_event_set(srv_monitor_event);
- mysql_mutex_lock(&LOCK_global_system_variables);
+ *static_cast<my_bool*>(var)= *static_cast<const my_bool*>(save);
+ if (srv_monitor_event)
+ {
+ mysql_mutex_unlock(&LOCK_global_system_variables);
+ /* Wakeup server monitor thread. */
+ os_event_set(srv_monitor_event);
+ mysql_mutex_lock(&LOCK_global_system_variables);
+ }
}
/** Update the system variable innodb_encryption_threads.
@@ -21079,7 +21065,7 @@ static MYSQL_SYSVAR_UINT(data_file_size_debug,
srv_sys_space_size_debug,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"InnoDB system tablespace size to be set in recovery.",
- NULL, NULL, 0, 0, UINT_MAX32, 0);
+ NULL, NULL, 0, 0, 256U << 20, 0);
static MYSQL_SYSVAR_ULONG(fil_make_page_dirty_debug,
srv_fil_make_page_dirty_debug, PLUGIN_VAR_OPCMDARG,
@@ -21155,7 +21141,7 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, bzip2, or snappy",
innodb_compression_algorithm_validate, NULL,
/* We use here the largest number of supported compression method to
enable all those methods that are available. Availability of compression
@@ -21206,7 +21192,7 @@ static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
"scrubbing",
NULL,
innodb_encryption_threads_update,
- srv_n_fil_crypt_threads, 0, UINT_MAX32, 0);
+ 0, 0, 255, 0);
static MYSQL_SYSVAR_UINT(encryption_rotate_key_age,
srv_fil_crypt_rotate_key_age,
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index e1b2dcd2441..4126f6b60e0 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -3388,6 +3388,12 @@ err_exit:
trx_free_for_mysql(ctx->trx);
trx_commit_for_mysql(ctx->prebuilt->trx);
+ for (uint i = 0; i < ctx->num_to_add_fk; i++) {
+ if (ctx->add_fk[i]) {
+ dict_foreign_free(ctx->add_fk[i]);
+ }
+ }
+
delete ctx;
ha_alter_info->handler_ctx = NULL;
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 8eb53502da8..9813e993411 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -2553,7 +2553,7 @@ i_s_metrics_fill(
time_diff = 0;
}
- /* Unless MONITOR__NO_AVERAGE is marked, we will need
+ /* Unless MONITOR_NO_AVERAGE is set, we must
to calculate the average value. If this is a monitor set
owner marked by MONITOR_SET_OWNER, divide
the value by another counter (number of calls) designated
@@ -2561,8 +2561,9 @@ i_s_metrics_fill(
Otherwise average the counter value by the time between the
time that the counter is enabled and time it is disabled
or time it is sampled. */
- if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && (monitor_info->monitor_type & MONITOR_SET_OWNER)
+ if ((monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE | MONITOR_SET_OWNER))
+ == MONITOR_SET_OWNER
&& monitor_info->monitor_related_id) {
mon_type_t value_start
= MONITOR_VALUE_SINCE_START(
@@ -2578,18 +2579,18 @@ i_s_metrics_fill(
fields[METRIC_AVG_VALUE_START]->set_null();
}
- if (MONITOR_VALUE(monitor_info->monitor_related_id)) {
- OK(fields[METRIC_AVG_VALUE_RESET]->store(
- MONITOR_VALUE(count)
- / MONITOR_VALUE(
- monitor_info->monitor_related_id),
- FALSE));
+ if (mon_type_t related_value =
+ MONITOR_VALUE(monitor_info->monitor_related_id)) {
+ OK(fields[METRIC_AVG_VALUE_RESET]
+ ->store(MONITOR_VALUE(count)
+ / related_value, false));
+ fields[METRIC_AVG_VALUE_RESET]->set_notnull();
} else {
fields[METRIC_AVG_VALUE_RESET]->set_null();
}
- } else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE)
- && !(monitor_info->monitor_type
- & MONITOR_DISPLAY_CURRENT)) {
+ } else if (!(monitor_info->monitor_type
+ & (MONITOR_NO_AVERAGE
+ | MONITOR_DISPLAY_CURRENT))) {
if (time_diff) {
OK(fields[METRIC_AVG_VALUE_START]->store(
(double) MONITOR_VALUE_SINCE_START(
@@ -3367,6 +3368,8 @@ no_fts:
conv_str.f_len = sizeof word;
conv_str.f_str = word;
+ rw_lock_s_lock(&cache->lock);
+
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
fts_index_cache_t* index_cache;
@@ -3377,6 +3380,7 @@ no_fts:
index_cache, thd, &conv_str, tables));
}
+ rw_lock_s_unlock(&cache->lock);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index 264d1677afa..6f11daa7363 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -63,6 +63,7 @@ UNIV_INTERN my_bool srv_ibuf_disable_background_merge;
#include "que0que.h"
#include "srv0start.h" /* srv_shutdown_state */
#include "ha_prototypes.h"
+#include "ut0crc32.h"
#include "rem0cmp.h"
/* STRUCTURE OF AN INSERT BUFFER RECORD
@@ -587,7 +588,7 @@ ibuf_init_at_db_start(void)
mutex_enter(&ibuf_mutex);
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, NULL), &mtr);
header_page = ibuf_header_page_get(&mtr);
@@ -2138,7 +2139,7 @@ ibuf_add_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
header_page = ibuf_header_page_get(&mtr);
@@ -2222,7 +2223,7 @@ ibuf_remove_free_page(void)
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
- mtr_x_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(IBUF_SPACE_ID, &flags), &mtr);
zip_size = fsp_flags_get_zip_size(flags);
header_page = ibuf_header_page_get(&mtr);
@@ -2925,42 +2926,28 @@ ibuf_contract_after_insert(
} while (size > 0 && sum_sizes < entry_size);
}
-/*********************************************************************//**
-Determine if an insert buffer record has been encountered already.
-@return TRUE if a new record, FALSE if possible duplicate */
-static
-ibool
-ibuf_get_volume_buffered_hash(
-/*==========================*/
- const rec_t* rec, /*!< in: ibuf record in post-4.1 format */
- const byte* types, /*!< in: fields */
- const byte* data, /*!< in: start of user record data */
- ulint comp, /*!< in: 0=ROW_FORMAT=REDUNDANT,
- nonzero=ROW_FORMAT=COMPACT */
- ulint* hash, /*!< in/out: hash array */
- ulint size) /*!< in: number of elements in hash array */
+/** Determine if a change buffer record has been encountered already.
+@param rec change buffer record in the MySQL 5.5 format
+@param hash hash table of encountered records
+@param size number of elements in hash
+@retval true if a distinct record
+@retval false if this may be duplicating an earlier record */
+static bool ibuf_get_volume_buffered_hash(const rec_t *rec, ulint *hash,
+ ulint size)
{
- ulint len;
- ulint fold;
- ulint bitmask;
-
- len = ibuf_rec_get_size(
- rec, types,
- rec_get_n_fields_old(rec) - IBUF_REC_FIELD_USER, comp);
- fold = ut_fold_binary(data, len);
-
- hash += (fold / (CHAR_BIT * sizeof *hash)) % size;
- bitmask = static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
-
- if (*hash & bitmask) {
-
- return(FALSE);
- }
-
- /* We have not seen this record yet. Insert it. */
- *hash |= bitmask;
-
- return(TRUE);
+ ut_ad(rec_get_n_fields_old(rec) > IBUF_REC_FIELD_USER);
+ const ulint start= rec_get_field_start_offs(rec, IBUF_REC_FIELD_USER);
+ const ulint len= rec_get_data_size_old(rec) - start;
+ const uint32_t fold= ut_crc32(rec + start, len);
+ hash+= (fold / (CHAR_BIT * sizeof *hash)) % size;
+ ulint bitmask= static_cast<ulint>(1) << (fold % (CHAR_BIT * sizeof(*hash)));
+
+ if (*hash & bitmask)
+ return false;
+
+ /* We have not seen this record yet. Remember it. */
+ *hash|= bitmask;
+ return true;
}
#ifdef UNIV_DEBUG
@@ -3052,11 +3039,7 @@ ibuf_get_volume_buffered_count_func(
case IBUF_OP_DELETE_MARK:
/* There must be a record to delete-mark.
See if this record has been already buffered. */
- if (n_recs && ibuf_get_volume_buffered_hash(
- rec, types + IBUF_REC_INFO_SIZE,
- types + len,
- types[IBUF_REC_OFFSET_FLAGS] & IBUF_REC_COMPACT,
- hash, size)) {
+ if (n_recs && ibuf_get_volume_buffered_hash(rec, hash, size)) {
(*n_recs)++;
}
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index e8a82f2e3e4..39fceeef384 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -1528,7 +1528,7 @@ buf_page_encrypt_before_write(
NOTE! The definition appears here only for other modules of this
directory (buf) to see it. Do not use from outside! */
-typedef struct {
+struct buf_tmp_buffer_t {
private:
int32 reserved; /*!< true if this slot is reserved
*/
@@ -1558,7 +1558,7 @@ public:
return !my_atomic_fas32_explicit(&reserved, true,
MY_MEMORY_ORDER_RELAXED);
}
-} buf_tmp_buffer_t;
+};
/** The common buffer control block structure
for compressed and uncompressed frames */
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 475391a3f75..c5ea95b7c08 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -1026,16 +1026,18 @@ dict_table_x_lock_indexes(
/*======================*/
dict_table_t* table) /*!< in: table */
{
- dict_index_t* index;
-
ut_ad(mutex_own(&dict_sys->mutex));
+ dict_index_t* clust_index = dict_table_get_first_index(table);
+
/* Loop through each index of the table and lock them */
- for (index = dict_table_get_first_index(table);
+ for (dict_index_t* index = dict_table_get_next_index(clust_index);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
}
+
+ rw_lock_x_lock(dict_index_get_lock(clust_index));
}
/*********************************************************************//**
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 1dcc3ebdd0c..f39c89d8e4b 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -864,6 +864,10 @@ struct dict_foreign_t{
does not generate new indexes
implicitly */
dict_index_t* referenced_index;/*!< referenced index */
+
+ /** Check whether the fulltext index gets affected by
+ foreign key constraint */
+ bool affects_fulltext() const;
};
std::ostream&
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index a4274f4d8a6..78878fa75fc 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -300,6 +300,8 @@ struct fil_space_t {
/*!< recovered tablespace size in pages;
0 if no size change was read from the redo log,
or if the size change was implemented */
+ /** the committed size of the tablespace in pages */
+ ulint committed_size;
ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags;
see fsp0fsp.h,
fsp_flags_is_valid(),
@@ -364,6 +366,15 @@ struct fil_space_t {
{
return stop_new_ops;
}
+
+ /** Clamp a page number for batched I/O, such as read-ahead.
+ @param offset page number limit
+ @return offset clamped to the tablespace size */
+ ulint max_page_number_for_io(ulint offset) const
+ {
+ const ulint limit= committed_size;
+ return limit > offset ? offset : limit;
+ }
};
/** Value of fil_space_t::magic_n */
@@ -574,16 +585,6 @@ ulint
fil_space_get_zip_size(
/*===================*/
ulint id); /*!< in: space id */
-/*******************************************************************//**
-Checks if the pair space, page_no refers to an existing page in a tablespace
-file space. The tablespace must be cached in the memory cache.
-@return TRUE if the address is meaningful */
-UNIV_INTERN
-ibool
-fil_check_adress_in_tablespace(
-/*===========================*/
- ulint id, /*!< in: space id */
- ulint page_no);/*!< in: page number */
/****************************************************************//**
Initializes the tablespace memory cache. */
UNIV_INTERN
@@ -704,34 +705,6 @@ UNIV_INTERN
void
fil_space_release_for_io(fil_space_t* space);
-/** Return the next fil_space_t.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last */
-UNIV_INTERN
-fil_space_t*
-fil_space_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
-/** Return the next fil_space_t from key rotation list.
-Once started, the caller must keep calling this until it returns NULL.
-fil_space_acquire() and fil_space_release() are invoked here which
-blocks a concurrent operation from dropping the tablespace.
-@param[in,out] prev_space Pointer to the previous fil_space_t.
-If NULL, use the first fil_space_t on fil_system->space_list.
-@return pointer to the next fil_space_t.
-@retval NULL if this was the last*/
-UNIV_INTERN
-fil_space_t*
-fil_space_keyrotate_next(
- fil_space_t* prev_space)
- MY_ATTRIBUTE((warn_unused_result));
-
/** Wrapper with reference-counting for a fil_space_t. */
class FilSpace
{
diff --git a/storage/xtradb/include/fts0ast.h b/storage/xtradb/include/fts0ast.h
index b7d467e0082..b7870cbc7bc 100644
--- a/storage/xtradb/include/fts0ast.h
+++ b/storage/xtradb/include/fts0ast.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2018, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -204,19 +204,6 @@ fts_ast_visit(
operator, currently we only
ignore FTS_IGNORE operator */
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
-list. Merge the sub-expression result with that of parent expression list.
-@return DB_SUCCESS if all went well */
-UNIV_INTERN
-dberr_t
-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 */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************
Create a lex instance.*/
UNIV_INTERN
diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h
index 714f811db27..4d07ac1612f 100644
--- a/storage/xtradb/include/fts0fts.h
+++ b/storage/xtradb/include/fts0fts.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -899,21 +899,19 @@ fts_valid_stopword_table(
name */
/****************************************************************//**
This function loads specified stopword into FTS cache
-@return TRUE if success */
+@return true if success */
UNIV_INTERN
-ibool
+bool
fts_load_stopword(
/*==============*/
const dict_table_t*
table, /*!< in: Table with FTS */
trx_t* trx, /*!< in: Transaction */
- const char* global_stopword_table, /*!< in: Global stopword table
- name */
const char* session_stopword_table, /*!< in: Session stopword table
name */
- ibool stopword_is_on, /*!< in: Whether stopword
+ bool stopword_is_on, /*!< in: Whether stopword
option is turned on/off */
- ibool reload); /*!< in: Whether it is during
+ bool reload); /*!< in: Whether it is during
reload of FTS table */
/****************************************************************//**
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index 878a42ea81b..a6b6e08b68b 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -1013,8 +1014,6 @@ std::string
lock_get_info(
const lock_t*);
-#define wsrep_on_trx(trx) ((trx)->mysql_thd && wsrep_on((trx)->mysql_thd))
-
#ifndef UNIV_NONINL
#include "lock0lock.ic"
#endif
diff --git a/storage/xtradb/include/mtr0mtr.h b/storage/xtradb/include/mtr0mtr.h
index 2d3da4d2a25..7d115eed5fd 100644
--- a/storage/xtradb/include/mtr0mtr.h
+++ b/storage/xtradb/include/mtr0mtr.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -57,6 +58,7 @@ first 3 values must be RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
#endif /* UNIV_DEBUG */
#define MTR_MEMO_S_LOCK 55
#define MTR_MEMO_X_LOCK 56
+#define MTR_MEMO_SPACE_X_LOCK 57
/** @name Log item types
The log items are declared 'byte' so that the compiler can warn if val
@@ -293,6 +295,8 @@ This macro locks an rw-lock in s-mode. */
This macro locks an rw-lock in x-mode. */
#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\
(MTR))
+#define mtr_x_space_lock(B, MTR) mtr_x_space_lock_func(B, __FILE__, __LINE__,\
+ MTR)
/*********************************************************************//**
NOTE! Use the macro above!
Locks a lock in s-mode. */
@@ -315,6 +319,14 @@ mtr_x_lock_func(
const char* file, /*!< in: file name */
ulint line, /*!< in: line number */
mtr_t* mtr); /*!< in: mtr */
+
+/** Acquire exclusive tablespace latch.
+@param lock fil_space_t::latch
+@param file source code file name of the caller
+@param line source code line number of the caller
+@param mtr mini-transaction */
+inline void mtr_x_space_lock_func(prio_rw_lock_t *lock,
+ const char *file, ulint line, mtr_t *mtr);
#endif /* !UNIV_HOTBACKUP */
/***************************************************//**
diff --git a/storage/xtradb/include/mtr0mtr.ic b/storage/xtradb/include/mtr0mtr.ic
index a44728463ae..0aea0994267 100644
--- a/storage/xtradb/include/mtr0mtr.ic
+++ b/storage/xtradb/include/mtr0mtr.ic
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -78,7 +79,7 @@ mtr_memo_push(
ut_ad(object);
ut_ad(type >= MTR_MEMO_PAGE_S_FIX);
- ut_ad(type <= MTR_MEMO_X_LOCK);
+ ut_ad(type <= MTR_MEMO_SPACE_X_LOCK);
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
@@ -293,4 +294,16 @@ mtr_x_lock_func(
mtr_memo_push(mtr, lock, MTR_MEMO_X_LOCK);
}
+
+/** Acquire exclusive tablespace latch.
+@param lock fil_space_t::latch
+@param file source code file name of the caller
+@param line source code line number of the caller
+@param mtr mini-transaction */
+inline void mtr_x_space_lock_func(prio_rw_lock_t *lock,
+ const char *file, ulint line, mtr_t *mtr)
+{
+ rw_lock_x_lock_inline(lock, 0, file, line);
+ mtr_memo_push(mtr, lock, MTR_MEMO_SPACE_X_LOCK);
+}
#endif /* !UNIV_HOTBACKUP */
diff --git a/storage/xtradb/include/page0page.h b/storage/xtradb/include/page0page.h
index 2efc2d302a1..b377aa68ac7 100644
--- a/storage/xtradb/include/page0page.h
+++ b/storage/xtradb/include/page0page.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
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
@@ -749,21 +749,6 @@ page_mem_alloc_free(
free record list */
ulint need); /*!< in: number of bytes allocated */
/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-UNIV_INTERN
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no);/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-/************************************************************//**
Puts a record to free list. */
UNIV_INLINE
void
diff --git a/storage/xtradb/include/sync0rw.h b/storage/xtradb/include/sync0rw.h
index 2e25a27192e..19b4793fc7b 100644
--- a/storage/xtradb/include/sync0rw.h
+++ b/storage/xtradb/include/sync0rw.h
@@ -2,6 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -763,13 +764,6 @@ struct rw_lock_t {
/* last s-lock file/line is not guaranteed to be correct */
const char* last_s_file_name;/*!< File name where last s-locked */
const char* last_x_file_name;/*!< File name where last x-locked */
- ibool writer_is_wait_ex;
- /*!< This is TRUE if the writer field is
- RW_LOCK_WAIT_EX; this field is located far
- from the memory update hotspot fields which
- are at the start of this struct, thus we can
- peek this field without causing much memory
- bus traffic */
unsigned cline:14; /*!< Line where created */
unsigned last_s_line:14; /*!< Line number where last time s-locked */
unsigned last_x_line:14; /*!< Line number where last time x-locked */
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index 448b2429126..5fed8d68e50 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -818,15 +818,21 @@ struct trx_t{
ro_trx_list the first time they try to acquire a lock ie. by default
we treat all read-only transactions as non-locking. */
trx_state_t state;
-
trx_lock_t lock; /*!< Information about the transaction
locks and state. Protected by
trx->mutex or lock_sys->mutex
or both */
- ulint is_recovered; /*!< 0=normal transaction,
- 1=recovered, must be rolled back,
+ bool is_recovered; /*!< false=normal transaction,
+ true=recovered, must be rolled back,
protected by trx_sys->mutex when
trx->in_rw_trx_list holds */
+#ifdef WITH_WSREP
+ /** whether wsrep_on(mysql_thd) held at the start of transaction */
+ bool wsrep;
+ bool is_wsrep() const { return UNIV_UNLIKELY(wsrep); }
+#else /* WITH_WSREP */
+ bool is_wsrep() const { return false; }
+#endif /* WITH_WSREP */
/* These fields are not protected by any mutex. */
const char* op_info; /*!< English text describing the
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 011921d9a39..61a8639691a 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -45,10 +45,10 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_MAJOR 5
#define INNODB_VERSION_MINOR 6
-#define INNODB_VERSION_BUGFIX 45
+#define INNODB_VERSION_BUGFIX 49
#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 86.1
+#define PERCONA_INNODB_VERSION 89.0
#endif
/* Enable UNIV_LOG_ARCHIVE in XtraDB */
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index c110c83cbe7..4d40111ac20 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -1770,7 +1770,7 @@ wsrep_kill_victim(
ut_ad(trx_mutex_own(lock->trx));
/* quit for native mysql */
- if (!wsrep_on(trx->mysql_thd)) return;
+ if (!trx->is_wsrep()) return;
my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
@@ -1856,7 +1856,7 @@ lock_rec_other_has_conflicting(
#ifdef WITH_WSREP
if (lock_rec_has_to_wait(TRUE, trx, mode, lock, is_supremum)) {
- if (wsrep_on_trx(trx)) {
+ if (trx->is_wsrep()) {
trx_mutex_enter(lock->trx);
/* Below function will roll back either trx
or lock->trx depending on priority of the
@@ -2318,8 +2318,7 @@ lock_rec_create(
ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
- if (c_lock &&
- wsrep_on_trx(trx) &&
+ if (c_lock && trx->is_wsrep() &&
wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
@@ -5009,7 +5008,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock && wsrep_on_trx(trx)) {
+ if (c_lock && trx->is_wsrep()) {
if (wsrep_thd_is_wsrep(trx->mysql_thd)
&& wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
UT_LIST_INSERT_AFTER(
@@ -5248,7 +5247,7 @@ lock_table_enqueue_waiting(
/* Enqueue the lock request that will wait to be granted */
#ifdef WITH_WSREP
- if (trx->lock.was_chosen_as_deadlock_victim && wsrep_on_trx(trx)) {
+ if (trx->lock.was_chosen_as_deadlock_victim && trx->is_wsrep()) {
return(DB_DEADLOCK);
}
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index fe43ef3cc73..70ade1191d7 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2019, MariaDB Corporation.
+Copyright (c) 2014, 2020, MariaDB Corporation.
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
@@ -255,8 +255,7 @@ wsrep_is_BF_lock_timeout(
const trx_t* trx,
bool locked = true)
{
- if (wsrep_on_trx(trx)
- && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ if (trx->is_wsrep() && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
fprintf(stderr, "WSREP: BF lock wait long for trx " TRX_ID_FMT "\n", trx->id);
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
@@ -447,7 +446,7 @@ lock_wait_suspend_thread(
if (lock_wait_timeout < 100000000
&& wait_time > (double) lock_wait_timeout) {
#ifdef WITH_WSREP
- if (!wsrep_on_trx(trx) ||
+ if (!trx->is_wsrep() ||
(!wsrep_is_BF_lock_timeout(trx) &&
trx->error_state != DB_DEADLOCK)) {
#endif /* WITH_WSREP */
diff --git a/storage/xtradb/mtr/mtr0mtr.cc b/storage/xtradb/mtr/mtr0mtr.cc
index 77af6e9eb60..ce1002a00f0 100644
--- a/storage/xtradb/mtr/mtr0mtr.cc
+++ b/storage/xtradb/mtr/mtr0mtr.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -88,6 +89,15 @@ mtr_memo_slot_release_func(
case MTR_MEMO_X_LOCK:
rw_lock_x_unlock((prio_rw_lock_t*) object);
break;
+ case MTR_MEMO_SPACE_X_LOCK:
+ {
+ fil_space_t* space = reinterpret_cast<fil_space_t*>(
+ static_cast<char*>(object)
+ - my_offsetof(fil_space_t, latch));
+ space->committed_size = space->size;
+ rw_lock_x_unlock(&space->latch);
+ }
+ break;
#ifdef UNIV_DEBUG
default:
ut_ad(slot->type == MTR_MEMO_MODIFY);
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 1e0f28d393f..66af4a39f7c 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -2716,6 +2716,7 @@ os_file_set_size(
errno = err;
return false;
case EINVAL:
+ case EOPNOTSUPP:
/* fall back to the code below */
break;
}
diff --git a/storage/xtradb/page/page0cur.cc b/storage/xtradb/page/page0cur.cc
index e9ac4b4bb04..94e861ab554 100644
--- a/storage/xtradb/page/page0cur.cc
+++ b/storage/xtradb/page/page0cur.cc
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
+Copyright (c) 2020, MariaDB Corporation.
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
@@ -941,6 +942,52 @@ page_cur_parse_insert_rec(
return(ptr + end_seg_len);
}
+/************************************************************//**
+Allocates a block of memory from the heap of an index page.
+@return pointer to start of allocated buffer, or NULL if allocation fails */
+static
+byte*
+page_mem_alloc_heap(
+/*================*/
+ page_t* page, /*!< in/out: index page */
+ page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
+ space available for inserting the record,
+ or NULL */
+ ulint need, /*!< in: total number of bytes needed */
+ ulint* heap_no)/*!< out: this contains the heap number
+ of the allocated record
+ if allocation succeeds */
+{
+ byte* block;
+ ulint avl_space;
+
+ ut_ad(page && heap_no);
+
+ avl_space = page_get_max_insert_size(page, 1);
+
+ if (avl_space >= need) {
+ const ulint h = page_dir_get_n_heap(page);
+ if (UNIV_UNLIKELY(h >= 8191)) {
+ /* At the minimum record size of 5+2 bytes,
+ we can only reach this condition when using
+ innodb_page_size=64k. */
+ ut_ad(srv_page_size == 65536);
+ return(NULL);
+ }
+ *heap_no = h;
+
+ block = page_header_get_ptr(page, PAGE_HEAP_TOP);
+
+ page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
+ block + need);
+ page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
+
+ return(block);
+ }
+
+ return(NULL);
+}
+
/***********************************************************//**
Inserts a record next to page cursor on an uncompressed page.
Returns pointer to inserted record if succeed, i.e., enough
diff --git a/storage/xtradb/page/page0page.cc b/storage/xtradb/page/page0page.cc
index 16587f872ef..ee31c9dbd87 100644
--- a/storage/xtradb/page/page0page.cc
+++ b/storage/xtradb/page/page0page.cc
@@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2018, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
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,44 +240,6 @@ page_set_max_trx_id(
}
}
-/************************************************************//**
-Allocates a block of memory from the heap of an index page.
-@return pointer to start of allocated buffer, or NULL if allocation fails */
-UNIV_INTERN
-byte*
-page_mem_alloc_heap(
-/*================*/
- page_t* page, /*!< in/out: index page */
- page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
- space available for inserting the record,
- or NULL */
- ulint need, /*!< in: total number of bytes needed */
- ulint* heap_no)/*!< out: this contains the heap number
- of the allocated record
- if allocation succeeds */
-{
- byte* block;
- ulint avl_space;
-
- ut_ad(page && heap_no);
-
- avl_space = page_get_max_insert_size(page, 1);
-
- if (avl_space >= need) {
- block = page_header_get_ptr(page, PAGE_HEAP_TOP);
-
- page_header_set_ptr(page, page_zip, PAGE_HEAP_TOP,
- block + need);
- *heap_no = page_dir_get_n_heap(page);
-
- page_dir_set_n_heap(page, page_zip, 1 + *heap_no);
-
- return(block);
- }
-
- return(NULL);
-}
-
#ifndef UNIV_HOTBACKUP
/**********************************************************//**
Writes a log record of page creation. */
diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc
index 0c7f9b6feff..d85594c5ce3 100644
--- a/storage/xtradb/page/page0zip.cc
+++ b/storage/xtradb/page/page0zip.cc
@@ -4927,35 +4927,28 @@ page_zip_verify_checksum(
ib_uint32_t crc32 = 0 /* silence bogus warning */;
ib_uint32_t innodb = 0 /* silence bogus warning */;
- stored = static_cast<ib_uint32_t>(mach_read_from_4(
- static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+ const srv_checksum_algorithm_t curr_algo =
+ static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-#if FIL_PAGE_LSN % 8
-#error "FIL_PAGE_LSN must be 64 bit aligned"
-#endif
+ if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
+ return true;
+ }
- /* Check if page is empty */
- if (stored == 0
- && *reinterpret_cast<const ib_uint64_t*>(static_cast<const char*>(
- data)
- + FIL_PAGE_LSN) == 0) {
- /* make sure that the page is really empty */
- for (ulint i = 0; i < size; i++) {
- if (*((const char*) data + i) != 0) {
- return(FALSE);
- }
+ bool all_zeroes = true;
+ for (size_t i = 0; i < size; i++) {
+ if (static_cast<const byte*>(data)[i] != 0) {
+ all_zeroes = false;
+ break;
}
- /* Empty page */
- return(TRUE);
}
- const srv_checksum_algorithm_t curr_algo =
- static_cast<srv_checksum_algorithm_t>(srv_checksum_algorithm);
-
- if (curr_algo == SRV_CHECKSUM_ALGORITHM_NONE) {
- return(TRUE);
+ if (all_zeroes) {
+ return true;
}
+ stored = static_cast<ib_uint32_t>(mach_read_from_4(
+ static_cast<const unsigned char*>(data) + FIL_PAGE_SPACE_OR_CHKSUM));
+
calc = static_cast<ib_uint32_t>(page_zip_calc_checksum(
data, size, curr_algo));
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index 5b371cfbf74..2121b00d009 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -561,14 +561,6 @@ protected:
/** Space id of the file being iterated over. */
ulint m_space;
- /** Minimum page number for which the free list has not been
- initialized: the pages >= this limit are, by definition, free;
- note that in a single-table tablespace where size < 64 pages,
- this number is 64, i.e., we have initialized the space about
- the first extent, but have not physically allocted those pages
- to the file. @see FSP_LIMIT. */
- ulint m_free_limit;
-
/** Current size of the space in pages */
ulint m_size;
@@ -647,7 +639,6 @@ AbstractCallback::init(
ut_a(m_space == ULINT_UNDEFINED);
m_size = mach_read_from_4(page + FSP_SIZE);
- m_free_limit = mach_read_from_4(page + FSP_FREE_LIMIT);
m_space = mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID);
return set_current_xdes(0, page);
@@ -1353,8 +1344,8 @@ uncompressed:
return(DB_ERROR);
} else if (m_table->n_cols != m_n_cols) {
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
- "Number of columns don't match, table has %u"
- " columns but the tablespace meta-data file has "
+ "Number of columns don't match, table has %u "
+ "columns but the tablespace meta-data file has "
ULINTPF " columns",
m_table->n_cols, m_n_cols);
@@ -1924,6 +1915,23 @@ PageConverter::update_index_page(
return(DB_SUCCESS);
}
+ if (m_index && block->page.offset == m_index->m_page_no) {
+ byte *b = FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF + FSEG_HDR_SPACE
+ + page;
+ mach_write_to_4(b, block->page.space);
+
+ memcpy(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP + FSEG_HDR_SPACE
+ + page, b, 4);
+ if (UNIV_LIKELY_NULL(block->page.zip.data)) {
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_TOP
+ + FSEG_HDR_SPACE], b, 4);
+ memcpy(&block->page.zip.data[FIL_PAGE_DATA
+ + PAGE_BTR_SEG_LEAF
+ + FSEG_HDR_SPACE], b, 4);
+ }
+ }
+
#ifdef UNIV_ZIP_DEBUG
ut_a(!is_compressed_table()
|| page_zip_validate(m_page_zip_ptr, page, m_index->m_srv_index));
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index 50da7fb40ad..c78f5bc8dc4 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -516,7 +516,7 @@ row_ins_cascade_calc_update_vec(
n_fields_updated = 0;
- *fts_col_affected = FALSE;
+ *fts_col_affected = foreign->affects_fulltext();
if (table->fts) {
doc_id_pos = dict_table_get_nth_col_pos(
@@ -637,16 +637,6 @@ row_ins_cascade_calc_update_vec(
padded_data, min_size);
}
- /* Check whether the current column has
- FTS index on it */
- if (table->fts
- && dict_table_is_fts_column(
- table->fts->indexes,
- dict_col_get_no(col))
- != ULINT_UNDEFINED) {
- *fts_col_affected = TRUE;
- }
-
/* If Doc ID is updated, check whether the
Doc ID is valid */
if (table->fts
@@ -983,7 +973,6 @@ row_ins_foreign_check_on_constraint(
upd_t* update;
ulint n_to_update;
dberr_t err;
- ulint i;
trx_t* trx;
mem_heap_t* tmp_heap = NULL;
doc_id_t doc_id = FTS_NULL_DOC_ID;
@@ -1197,7 +1186,7 @@ row_ins_foreign_check_on_constraint(
UNIV_MEM_INVALID(update->fields,
update->n_fields * sizeof *update->fields);
- for (i = 0; i < foreign->n_fields; i++) {
+ for (ulint i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
ufield->field_no = dict_table_get_nth_col_pos(
@@ -1206,32 +1195,14 @@ row_ins_foreign_check_on_constraint(
ufield->orig_len = 0;
ufield->exp = NULL;
dfield_set_null(&ufield->new_val);
-
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i))
- != ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
- }
}
- if (fts_col_affacted) {
- fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
- }
- } else if (table->fts && cascade->is_delete) {
- /* DICT_FOREIGN_ON_DELETE_CASCADE case */
- for (i = 0; i < foreign->n_fields; i++) {
- if (table->fts && dict_table_is_fts_column(
- table->fts->indexes,
- dict_index_get_nth_col_no(index, i))
- != ULINT_UNDEFINED) {
- fts_col_affacted = TRUE;
- }
- }
-
- if (fts_col_affacted) {
+ if (foreign->affects_fulltext()) {
fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
+ } else if (table->fts && cascade->is_delete
+ && foreign->affects_fulltext()) {
+ fts_trx_add_op(trx, table, doc_id, FTS_DELETE, NULL);
}
if (!node->is_delete
@@ -1651,7 +1622,7 @@ run_again:
if (check_ref) {
err = DB_SUCCESS;
#ifdef WITH_WSREP
- if (!wsrep_on(trx->mysql_thd)) {
+ if (!trx->is_wsrep()) {
goto end_scan;
}
enum wsrep_key_type key_type;
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index b5bd626db63..587fcda27b1 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -3209,6 +3209,16 @@ row_discard_tablespace_for_mysql(
err = DB_ERROR;
} else {
+ bool fts_exist = (dict_table_has_fts_index(table)
+ || DICT_TF2_FLAG_IS_SET(
+ table, DICT_TF2_FTS_HAS_DOC_ID));
+
+ if (fts_exist) {
+ row_mysql_unlock_data_dictionary(trx);
+ fts_optimize_remove_table(table);
+ row_mysql_lock_data_dictionary(trx);
+ }
+
/* Do foreign key constraint checks. */
err = row_discard_tablespace_foreign_key_checks(trx, table);
@@ -3216,6 +3226,11 @@ row_discard_tablespace_for_mysql(
if (err == DB_SUCCESS) {
err = row_discard_tablespace(trx, table);
}
+
+ if (fts_exist && err != DB_SUCCESS) {
+ fts_optimize_add_table(table);
+ }
+
}
return(row_discard_tablespace_end(trx, table, err));
diff --git a/storage/xtradb/row/row0sel.cc b/storage/xtradb/row/row0sel.cc
index c9c7f1dd9c1..a968fc83243 100644
--- a/storage/xtradb/row/row0sel.cc
+++ b/storage/xtradb/row/row0sel.cc
@@ -2,7 +2,7 @@
Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2015, 2018, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -3740,9 +3740,16 @@ bool row_search_with_covering_prefix(
return false;
}
+ /* We can avoid a clustered index lookup if
+ all of the following hold:
+ (1) all columns are in the secondary index
+ (2) all values for columns that are prefix-only
+ indexes are shorter than the prefix size
+ This optimization can avoid many IOs for certain schemas. */
for (ulint i = 0; i < prebuilt->n_template; i++) {
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
ulint j = templ->rec_prefix_field_no;
+ ut_ad(!templ->mbminlen == !templ->mbmaxlen);
/** Condition (1) : is the field in the index. */
if (j == ULINT_UNDEFINED) {
@@ -3752,34 +3759,29 @@ bool row_search_with_covering_prefix(
/** Condition (2): If this is a prefix index then
row's value size shorter than prefix length. */
- if (!templ->rec_field_is_prefix) {
+ if (!templ->rec_field_is_prefix
+ || rec_offs_nth_sql_null(offsets, j)) {
continue;
}
- ulint rec_size = rec_offs_nth_size(offsets, j);
const dict_field_t* field = dict_index_get_nth_field(index, j);
- ulint max_chars = field->prefix_len / templ->mbmaxlen;
- ut_a(field->prefix_len > 0);
-
- if (rec_size < max_chars) {
- /* Record in bytes shorter than the index
- prefix length in char. */
+ if (!field->prefix_len) {
continue;
}
- if (rec_size * templ->mbminlen >= field->prefix_len) {
+ const ulint rec_size = rec_offs_nth_size(offsets, j);
+
+ if (rec_size >= field->prefix_len) {
/* Shortest representation string by the
byte length of the record is longer than the
maximum possible index prefix. */
return false;
}
-
- size_t num_chars = rec_field_len_in_chars(
- field->col, j, rec, offsets);
-
- if (num_chars >= max_chars) {
+ if (templ->mbminlen != templ->mbmaxlen
+ && rec_field_len_in_chars(field->col, j, rec, offsets)
+ >= field->prefix_len / templ->mbmaxlen) {
/* No of chars to store the record exceeds
the index prefix character length. */
return false;
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 6324c1d71a1..a5e5988113d 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2018, 2019, MariaDB Corporation.
+Copyright (c) 2018, 2020, MariaDB Corporation.
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
@@ -1814,7 +1814,7 @@ row_upd_store_row(
inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
{
- if (!wsrep_on_trx(trx)) {
+ if (!trx->is_wsrep()) {
return false;
}
return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
diff --git a/storage/xtradb/srv/srv0conc.cc b/storage/xtradb/srv/srv0conc.cc
index 3433d968eb2..d2ededc3894 100644
--- a/storage/xtradb/srv/srv0conc.cc
+++ b/storage/xtradb/srv/srv0conc.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2017, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -218,8 +218,7 @@ srv_conc_enter_innodb_with_atomics(
for (;;) {
ulint sleep_in_us;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
if (wsrep_debug)
fprintf(stderr,
"srv_conc_enter due to MUST_ABORT");
@@ -430,8 +429,7 @@ retry:
return;
}
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_thd_is_brute_force(trx->mysql_thd)) {
srv_conc_force_enter_innodb(trx);
return;
}
@@ -514,8 +512,7 @@ retry:
srv_conc.n_waiting++;
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_trx_is_aborting(trx->mysql_thd)) {
+ if (trx->is_wsrep() && wsrep_trx_is_aborting(trx->mysql_thd)) {
os_fast_mutex_unlock(&srv_conc_mutex);
if (wsrep_debug)
fprintf(stderr, "srv_conc_enter due to MUST_ABORT");
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index bc7f6c948de..84417b5888b 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -3,7 +3,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -678,7 +678,6 @@ current_time % 60 == 0 and no tasks will be performed when
current_time % 5 != 0. */
# define SRV_MASTER_CHECKPOINT_INTERVAL (7)
-# define SRV_MASTER_PURGE_INTERVAL (10)
#ifdef MEM_PERIODIC_CHECK
# define SRV_MASTER_MEM_VALIDATE_INTERVAL (13)
#endif /* MEM_PERIODIC_CHECK */
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc
index 153599391dc..b61a8349b07 100644
--- a/storage/xtradb/srv/srv0start.cc
+++ b/storage/xtradb/srv/srv0start.cc
@@ -3,7 +3,7 @@
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2009, Percona Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1240,6 +1240,10 @@ check_first_page:
}
}
+ if (fil_space_t* s = fil_space_get(0)) {
+ s->committed_size = s->size;
+ }
+
return(DB_SUCCESS);
}
@@ -1408,6 +1412,10 @@ srv_undo_tablespace_open(
if (fil_node_create(name, (ulint) n_pages, space, FALSE)) {
err = DB_SUCCESS;
}
+
+ if (fil_space_t* s = fil_space_get(space)) {
+ s->committed_size = n_pages;
+ }
}
return(err);
diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc
index c085e8ebcf5..4de46089790 100644
--- a/storage/xtradb/sync/sync0arr.cc
+++ b/storage/xtradb/sync/sync0arr.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2019, MariaDB Corporation.
+Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -1164,7 +1164,7 @@ sync_array_print_long_waits(
sync_array_exit(arr);
}
- if (noticed) {
+ if (noticed && srv_monitor_event) {
ibool old_val;
fprintf(stderr,
diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc
index 97f08d1fa0c..7624d92a831 100644
--- a/storage/xtradb/trx/trx0roll.cc
+++ b/storage/xtradb/trx/trx0roll.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2020, MariaDB Corporation.
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
@@ -379,8 +379,7 @@ trx_rollback_to_savepoint_for_mysql_low(
trx->op_info = "";
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- trx->lock.was_chosen_as_deadlock_victim) {
+ if (trx->is_wsrep()) {
trx->lock.was_chosen_as_deadlock_victim = FALSE;
}
#endif
@@ -1083,12 +1082,6 @@ trx_roll_try_truncate(
if (trx->update_undo) {
trx_undo_truncate_end(trx, trx->update_undo, limit);
}
-
-#ifdef WITH_WSREP_OUT
- if (wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif /* WITH_WSREP */
}
/***********************************************************************//**
diff --git a/storage/xtradb/trx/trx0rseg.cc b/storage/xtradb/trx/trx0rseg.cc
index 1d0eb6d29fd..8ce6fb6729f 100644
--- a/storage/xtradb/trx/trx0rseg.cc
+++ b/storage/xtradb/trx/trx0rseg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2011, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -65,7 +65,7 @@ trx_rseg_header_create(
ut_ad(mtr);
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
- MTR_MEMO_X_LOCK));
+ MTR_MEMO_SPACE_X_LOCK));
/* Allocate a new file segment for the rollback segment */
block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
@@ -312,7 +312,7 @@ trx_rseg_create(ulint space)
/* To obey the latching order, acquire the file space
x-latch before the trx_sys->mutex. */
- mtr_x_lock(fil_space_get_latch(space, NULL), &mtr);
+ mtr_x_space_lock(fil_space_get_latch(space, NULL), &mtr);
slot_no = trx_sysf_rseg_find_free(&mtr);
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index fcdce291cf0..94a79a1f944 100644
--- a/storage/xtradb/trx/trx0sys.cc
+++ b/storage/xtradb/trx/trx0sys.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2018, MariaDB Corporation.
+Copyright (c) 2017, 2020, MariaDB Corporation.
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
@@ -554,7 +554,7 @@ trx_sysf_create(
then enter the kernel: we must do it in this order to conform
to the latching order rules. */
- mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
+ mtr_x_space_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), mtr);
/* Create the trx sys file block in a new allocated file segment */
block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,
diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc
index a65132cf572..bfbd15d62a2 100644
--- a/storage/xtradb/trx/trx0trx.cc
+++ b/storage/xtradb/trx/trx0trx.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2015, 2019, MariaDB Corporation.
+Copyright (c) 2015, 2020, MariaDB Corporation.
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
@@ -1555,11 +1555,7 @@ trx_commit_in_memory(
ut_ad(!trx->in_ro_trx_list);
ut_ad(!trx->in_rw_trx_list);
-#ifdef WITH_WSREP
- if (trx->mysql_thd && wsrep_on(trx->mysql_thd)) {
- trx->lock.was_chosen_as_deadlock_victim = FALSE;
- }
-#endif
+ trx->lock.was_chosen_as_deadlock_victim = FALSE;
trx->dict_operation = TRX_DICT_OP_NONE;
trx->error_state = DB_SUCCESS;
diff --git a/strings/decimal.c b/strings/decimal.c
index 56d09e8f303..dd2e1236489 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -812,6 +812,24 @@ internal_str2dec(const char *from, decimal_t *to, char **end, my_bool fixed)
while (s < end_of_string && my_isdigit(&my_charset_latin1, *s))
s++;
intg= (int) (s-s1);
+ /*
+ If the integer part is long enough and it has multiple leading zeros,
+ let's trim them, so this expression can return 1 without overflowing:
+ CAST(CONCAT(REPEAT('0',90),'1') AS DECIMAL(10))
+ */
+ if (intg > DIG_PER_DEC1 && s1[0] == '0' && s1[1] == '0')
+ {
+ /*
+ Keep at least one digit, to avoid an empty string.
+ So we trim '0000' to '0' rather than to ''.
+ Otherwise the below code (converting digits to to->buf)
+ would fail on a fatal error.
+ */
+ const char *iend= s - 1;
+ for ( ; s1 < iend && *s1 == '0'; s1++)
+ { }
+ intg= (int) (s-s1);
+ }
if (s < end_of_string && *s=='.')
{
endp= s+1;
diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
index 62ad8bcffc9..363646a0647 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -114,21 +114,6 @@ IF(UNIX)
${CMAKE_CURRENT_BINARY_DIR}/mariadb.service
DESTINATION ${inst_location}/systemd COMPONENT SupportFiles)
- IF(INSTALL_SYSTEMD_SYSUSERSDIR)
- CONFIGURE_FILE(sysusers.conf.in
- ${CMAKE_CURRENT_BINARY_DIR}/sysusers.conf @ONLY)
- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/sysusers.conf
- DESTINATION ${INSTALL_SYSTEMD_SYSUSERSDIR} COMPONENT Server)
- ENDIF()
-
- IF(INSTALL_SYSTEMD_TMPFILESDIR)
- get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY)
- CONFIGURE_FILE(tmpfiles.conf.in
- ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf @ONLY)
- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf
- DESTINATION ${INSTALL_SYSTEMD_TMPFILESDIR} COMPONENT Server)
- ENDIF()
-
# @ in directory name broken between CMake version 2.8.12.2 and 3.3
# http://public.kitware.com/Bug/view.php?id=14782
IF(NOT CMAKE_VERSION VERSION_LESS 3.3.0 OR NOT RPM)
@@ -155,6 +140,26 @@ IF(UNIX)
ENDIF()
ENDIF()
+ # Allow installing sysusers and tmpusers without requiring SYSTEMD on the
+ # system. This is useful for distributions running other init systems to
+ # parse these files and create appropriate users & tmpfiles.
+ IF((HAVE_SYSTEMD OR INSTALL_SYSTEMD_SYSUSERS) AND INSTALL_SYSTEMD_SYSUSERSDIR)
+ CONFIGURE_FILE(sysusers.conf.in
+ ${CMAKE_CURRENT_BINARY_DIR}/sysusers.conf @ONLY)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/sysusers.conf
+ DESTINATION ${INSTALL_SYSTEMD_SYSUSERSDIR}
+ RENAME mariadb.conf COMPONENT Server)
+ ENDIF()
+
+ IF((HAVE_SYSTEMD OR INSTALL_SYSTEMD_TMPUSERS) AND INSTALL_SYSTEMD_TMPFILESDIR)
+ get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY)
+ CONFIGURE_FILE(tmpfiles.conf.in
+ ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf @ONLY)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tmpfiles.conf
+ DESTINATION ${INSTALL_SYSTEMD_TMPFILESDIR}
+ RENAME mariadb.conf COMPONENT Server)
+ ENDIF()
+
IF (INSTALL_SYSCONFDIR)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql-log-rotate DESTINATION ${INSTALL_SYSCONFDIR}/logrotate.d
RENAME mysql COMPONENT SupportFiles)
diff --git a/support-files/mariadb.pc.in b/support-files/mariadb.pc.in
index bc84a5c5c4c..7d321f28491 100644
--- a/support-files/mariadb.pc.in
+++ b/support-files/mariadb.pc.in
@@ -20,4 +20,4 @@ Description: @CPACK_PACKAGE_DESCRIPTION_SUMMARY@
URL: @CPACK_PACKAGE_URL@
Version: @VERSION@
Libs: -L${libdir} @LIBS_FOR_CLIENTS@
-Cflags: -I${includedir} -I${includedir}/.. @CFLAGS_FOR_CLIENTS@
+Cflags: -I${includedir} @CFLAGS_FOR_CLIENTS@
diff --git a/support-files/mariadb.service.in b/support-files/mariadb.service.in
index ede97c04112..398b01f1f5d 100644
--- a/support-files/mariadb.service.in
+++ b/support-files/mariadb.service.in
@@ -70,7 +70,7 @@ PermissionsStartOnly=true
# Do not panic if galera_recovery script is not available. (MDEV-10538)
ExecStartPre=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION"
ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
- VAR=`@bindir@/galera_recovery`; [ $? -eq 0 ] \
+ VAR=`cd @bindir@/..; @bindir@/galera_recovery`; [ $? -eq 0 ] \
&& systemctl set-environment _WSREP_START_POSITION=$VAR || exit 1"
# Needed to create system tables etc.
@@ -133,8 +133,8 @@ TimeoutStopSec=900
## isn't executed.
##
-# Number of files limit. previously [mysqld_safe] open-file-limit
-LimitNOFILE=16364
+# Number of files limit. previously [mysqld_safe] open-files-limit
+LimitNOFILE=16384
# Maximium core size. previously [mysqld_safe] core-file-size
# LimitCore=
diff --git a/support-files/mariadb@.service.in b/support-files/mariadb@.service.in
index 1f84b582e4e..b260349040b 100644
--- a/support-files/mariadb@.service.in
+++ b/support-files/mariadb@.service.in
@@ -76,14 +76,14 @@ PermissionsStartOnly=true
ExecStartPre=/bin/sh -c "systemctl unset-environment _WSREP_START_POSITION%I"
ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
- VAR=`@bindir@/galera_recovery --defaults-file=@sysconf2dir@/my%I.cnf`; [ $? -eq 0 ] \
+ VAR=`cd @bindir@/..; @bindir@/galera_recovery --defaults-file=@sysconf2dir@/my%I.cnf`; [ $? -eq 0 ] \
&& systemctl set-environment _WSREP_START_POSITION%I=$VAR || exit 1"
# Alternate: (remove ConditionPathExists above)
# use [mysqld.INSTANCENAME] as sections in my.cnf
#
#ExecStartPre=/bin/sh -c "[ ! -e @bindir@/galera_recovery ] && VAR= || \
-# VAR=`@bindir@/galera_recovery --defaults-group-suffix=%I`; [ $? -eq 0 ] \
+# VAR=`cd @bindir@/..; @bindir@/galera_recovery --defaults-group-suffix=%I`; [ $? -eq 0 ] \
# && systemctl set-environment _WSREP_START_POSITION%I=$VAR || exit 1"
# Needed to create system tables etc.
@@ -154,8 +154,8 @@ TimeoutStopSec=900
## isn't executed.
##
-# Number of files limit. previously [mysqld_safe] open-file-limit
-LimitNOFILE=16364
+# Number of files limit. previously [mysqld_safe] open-files-limit
+LimitNOFILE=16384
# Maximium core size. previously [mysqld_safe] core-file-size
# LimitCore=
diff --git a/support-files/rpm/my.cnf b/support-files/rpm/my.cnf
index 913b88f8328..5cda317d29e 100644
--- a/support-files/rpm/my.cnf
+++ b/support-files/rpm/my.cnf
@@ -1,11 +1,11 @@
#
-# This group is read both both by the client and the server
+# This group is read both by the client and the server
# use it for options that affect everything
#
[client-server]
#
-# include all files from the config directory
+# include *.cnf from the config directory
#
!includedir /etc/my.cnf.d
diff --git a/support-files/use_galera_new_cluster.conf b/support-files/use_galera_new_cluster.conf
index 90e0365ffd8..79d191094d4 100644
--- a/support-files/use_galera_new_cluster.conf
+++ b/support-files/use_galera_new_cluster.conf
@@ -15,8 +15,13 @@ ConditionPathExists=
Type=oneshot
Restart=no
+# Don't install or try to prepare for galera SST.
+ExecStartPre=
+
# Override the multi instance service for a bootstrap start instance
ExecStart=
ExecStart=/usr/bin/echo "Please use galera_new_cluster to start the mariadb service with --wsrep-new-cluster"
ExecStart=/usr/bin/false
+# This isn't a service meant to execute anything but a message
+ExecStartPost=
diff --git a/tests/big_record.pl b/tests/big_record.pl
index cb1f8998468..b08f7ea60e2 100755
--- a/tests/big_record.pl
+++ b/tests/big_record.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/tests/drop_test.pl b/tests/drop_test.pl
index 329f65eb65d..6ed05abb7ab 100755
--- a/tests/drop_test.pl
+++ b/tests/drop_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000 MySQL AB
# Use is subject to license terms
diff --git a/tests/export.pl b/tests/export.pl
index f99798ecac8..dace79feb30 100755
--- a/tests/export.pl
+++ b/tests/export.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/fork2_test.pl b/tests/fork2_test.pl
index 356055733fa..55e494dcedc 100755
--- a/tests/fork2_test.pl
+++ b/tests/fork2_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/fork_big.pl b/tests/fork_big.pl
index 623377ab5cd..bd048e8fcb0 100755
--- a/tests/fork_big.pl
+++ b/tests/fork_big.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
use strict;
# Copyright (c) 2001, 2006 MySQL AB
diff --git a/tests/fork_big2.pl b/tests/fork_big2.pl
index c844d290834..d0c17af8cb1 100644
--- a/tests/fork_big2.pl
+++ b/tests/fork_big2.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (c) 2002, 2003, 2005, 2006 MySQL AB
# Use is subject to license terms
diff --git a/tests/grant.pl b/tests/grant.pl
index cd651643316..b50481a93fc 100755
--- a/tests/grant.pl
+++ b/tests/grant.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2000, 2005 MySQL AB, 2009 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/tests/index_corrupt.pl b/tests/index_corrupt.pl
index 6b04ce8a59c..e40bb7afdbb 100755
--- a/tests/index_corrupt.pl
+++ b/tests/index_corrupt.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2005 MySQL AB
# Use is subject to license terms
diff --git a/tests/insert_and_repair.pl b/tests/insert_and_repair.pl
index 18091c92718..a8e74e5f30e 100755
--- a/tests/insert_and_repair.pl
+++ b/tests/insert_and_repair.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/lock_test.pl b/tests/lock_test.pl
index 98c4ad6377d..8a8a0322467 100755
--- a/tests/lock_test.pl
+++ b/tests/lock_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2000 MySQL AB
# Use is subject to license terms
diff --git a/tests/mail_to_db.pl b/tests/mail_to_db.pl
index e50415d96f3..bab9e7eb74a 100755
--- a/tests/mail_to_db.pl
+++ b/tests/mail_to_db.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright Abandoned 1998 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind
#
diff --git a/tests/pmail.pl b/tests/pmail.pl
index 359256c25b3..cf46f5a054d 100755
--- a/tests/pmail.pl
+++ b/tests/pmail.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2005 MySQL AB
# Use is subject to license terms
diff --git a/tests/rename_test.pl b/tests/rename_test.pl
index d7097df1e4e..aa0befa125d 100755
--- a/tests/rename_test.pl
+++ b/tests/rename_test.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/table_types.pl b/tests/table_types.pl
index c633a153098..782b8f254bf 100755
--- a/tests/table_types.pl
+++ b/tests/table_types.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (C) 2000, 2003 MySQL AB
# Use is subject to license terms
diff --git a/tests/test_delayed_insert.pl b/tests/test_delayed_insert.pl
index cb5b86a228d..f0702e6378b 100755
--- a/tests/test_delayed_insert.pl
+++ b/tests/test_delayed_insert.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2000, 2001 MySQL AB
# Use is subject to license terms
diff --git a/tests/truncate.pl b/tests/truncate.pl
index 98791a15b2c..21d469662d9 100755
--- a/tests/truncate.pl
+++ b/tests/truncate.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
# Copyright (C) 2002 MySQL AB
# Use is subject to license terms
diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt
index dd0db94a77c..dd1aa85c9c6 100644
--- a/unittest/mysys/CMakeLists.txt
+++ b/unittest/mysys/CMakeLists.txt
@@ -15,7 +15,7 @@
MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring
aes
- LINK_LIBRARIES mysys)
+ queues stacktrace LINK_LIBRARIES mysys)
MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys)
ADD_DEFINITIONS(${SSL_DEFINES})
diff --git a/unittest/mysys/queues-t.c b/unittest/mysys/queues-t.c
new file mode 100644
index 00000000000..23cb0da1a32
--- /dev/null
+++ b/unittest/mysys/queues-t.c
@@ -0,0 +1,139 @@
+/* Copyright (c) 2020, MariaDB Corporation
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <queues.h>
+#include <my_rnd.h>
+#include "tap.h"
+
+int cmp(void *arg __attribute__((unused)), uchar *a, uchar *b)
+{
+ return *a < *b ? -1 : *a > *b;
+}
+
+#define rnd(R) ((uint)(my_rnd(R) * INT_MAX32))
+
+#define el(Q,I) ((uint)*queue_element(Q, I))
+
+my_bool verbose;
+
+my_bool check_queue(QUEUE *queue)
+{
+ char b[1024]={0}, *s, *e=b+sizeof(b)-2;
+ my_bool ok=1;
+ uint i;
+
+ s= b + my_snprintf(b, e-b, "%x", el(queue, 1));
+ for (i=2; i <= queue->elements; i++)
+ {
+ s+= my_snprintf(s, e-s, ", %x", el(queue, i));
+ ok &= el(queue, i) <= el(queue, i>>1);
+ }
+ if (!ok || verbose)
+ diag("%s", b);
+ return ok;
+}
+
+int main(int argc __attribute__((unused)), char *argv[])
+{
+ QUEUE q, *queue=&q;
+ MY_INIT(argv[0]);
+ plan(19);
+
+ verbose=1;
+
+ init_queue(queue, 256, 0, 1, cmp, NULL, 0, 0);
+ queue_insert(queue, (uchar*)"\x99");
+ queue_insert(queue, (uchar*)"\x19");
+ queue_insert(queue, (uchar*)"\x36");
+ queue_insert(queue, (uchar*)"\x17");
+ queue_insert(queue, (uchar*)"\x12");
+ queue_insert(queue, (uchar*)"\x05");
+ queue_insert(queue, (uchar*)"\x25");
+ queue_insert(queue, (uchar*)"\x09");
+ queue_insert(queue, (uchar*)"\x15");
+ queue_insert(queue, (uchar*)"\x06");
+ queue_insert(queue, (uchar*)"\x11");
+ queue_insert(queue, (uchar*)"\x01");
+ queue_insert(queue, (uchar*)"\x04");
+ queue_insert(queue, (uchar*)"\x13");
+ queue_insert(queue, (uchar*)"\x24");
+ ok(check_queue(queue), "after insert");
+ queue_remove(queue, 5);
+ ok(check_queue(queue), "after remove 5th");
+
+ queue_element(queue, 1) = (uchar*)"\x01";
+ queue_element(queue, 2) = (uchar*)"\x10";
+ queue_element(queue, 3) = (uchar*)"\x04";
+ queue_element(queue, 4) = (uchar*)"\x09";
+ queue_element(queue, 5) = (uchar*)"\x13";
+ queue_element(queue, 6) = (uchar*)"\x03";
+ queue_element(queue, 7) = (uchar*)"\x08";
+ queue_element(queue, 8) = (uchar*)"\x07";
+ queue_element(queue, 9) = (uchar*)"\x06";
+ queue_element(queue,10) = (uchar*)"\x12";
+ queue_element(queue,11) = (uchar*)"\x05";
+ queue_element(queue,12) = (uchar*)"\x02";
+ queue_element(queue,13) = (uchar*)"\x11";
+ queue->elements= 13;
+ ok(!check_queue(queue), "manually filled (queue property violated)");
+
+ queue_fix(queue);
+ ok(check_queue(queue), "fixed");
+
+ ok(*queue_remove_top(queue) == 0x13, "remove top 13");
+ ok(*queue_remove_top(queue) == 0x12, "remove top 12");
+ ok(*queue_remove_top(queue) == 0x11, "remove top 11");
+ ok(*queue_remove_top(queue) == 0x10, "remove top 10");
+ ok(*queue_remove_top(queue) == 0x09, "remove top 9");
+ ok(*queue_remove_top(queue) == 0x08, "remove top 8");
+ ok(*queue_remove_top(queue) == 0x07, "remove top 7");
+ ok(*queue_remove_top(queue) == 0x06, "remove top 6");
+ ok(*queue_remove_top(queue) == 0x05, "remove top 5");
+ ok(*queue_remove_top(queue) == 0x04, "remove top 4");
+ ok(*queue_remove_top(queue) == 0x03, "remove top 3");
+ ok(*queue_remove_top(queue) == 0x02, "remove top 2");
+ ok(*queue_remove_top(queue) == 0x01, "remove top 1");
+
+ /* random test */
+ {
+ int i, res;
+ struct my_rnd_struct rand;
+ my_rnd_init(&rand, (ulong)(intptr)&i, (ulong)(intptr)argv);
+ verbose=0;
+
+ for (res= i=1; i <= 250; i++)
+ {
+ uchar *s=alloca(2);
+ *s= rnd(&rand) % 251;
+ queue_insert(queue, s);
+ res &= check_queue(queue);
+ }
+ ok(res, "inserted 250");
+
+ while (queue->elements)
+ {
+ queue_remove(queue, (rnd(&rand) % queue->elements) + 1);
+ res &= check_queue(queue);
+ }
+ ok(res, "removed 250");
+ }
+
+ delete_queue(queue);
+ my_end(0);
+ return exit_status();
+}
+
diff --git a/unittest/mysys/stacktrace-t.c b/unittest/mysys/stacktrace-t.c
new file mode 100644
index 00000000000..8fa0db15b36
--- /dev/null
+++ b/unittest/mysys/stacktrace-t.c
@@ -0,0 +1,67 @@
+
+/* Copyright (c) 2020, MariaDB Corporation.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
+
+#include <my_global.h>
+#include <my_sys.h>
+#include <stdio.h>
+#include <my_stacktrace.h>
+#include <tap.h>
+
+char b_bss[10];
+
+void test_my_safe_print_str()
+{
+ char b_stack[10];
+ char *b_heap= strdup("LEGAL");
+ memcpy(b_stack, "LEGAL", 6);
+ memcpy(b_bss, "LEGAL", 6);
+
+#ifndef __SANITIZE_ADDRESS__
+ fprintf(stderr, "\n===== stack =====\n");
+ my_safe_print_str(b_stack, 65535);
+ fprintf(stderr, "\n===== heap =====\n");
+ my_safe_print_str(b_heap, 65535);
+ fprintf(stderr, "\n===== BSS =====\n");
+ my_safe_print_str(b_bss, 65535);
+ fprintf(stderr, "\n===== data =====\n");
+ my_safe_print_str("LEGAL", 65535);
+ fprintf(stderr, "\n===== Above is a junk, but it is expected. =====\n");
+#endif /*__SANITIZE_ADDRESS__*/
+ fprintf(stderr, "\n===== Nornal length test =====\n");
+ my_safe_print_str("LEGAL", 5);
+ fprintf(stderr, "\n===== NULL =====\n");
+ my_safe_print_str(0, 5);
+#ifndef __SANITIZE_ADDRESS__
+ fprintf(stderr, "\n===== (const char*) 1 =====\n");
+ my_safe_print_str((const char*)1, 5);
+#endif /*__SANITIZE_ADDRESS__*/
+
+ free(b_heap);
+
+ ok(1, "test_my_safe_print_str");
+}
+
+
+int main(int argc __attribute__((unused)), char **argv)
+{
+ MY_INIT(argv[0]);
+ plan(1);
+
+ test_my_safe_print_str();
+
+ my_end(0);
+ return exit_status();
+}
diff --git a/unittest/unit.pl b/unittest/unit.pl
index fb9a16fbe49..dc72a57d20c 100644
--- a/unittest/unit.pl
+++ b/unittest/unit.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Copyright (c) 2006 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
# Use is subject to license terms.
#
diff --git a/vio/viosocket.c b/vio/viosocket.c
index e22e8e85ff6..a6c68584515 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -926,7 +926,7 @@ static my_bool socket_peek_read(Vio *vio, uint *bytes)
@param timeout Interval (in milliseconds) to wait for an I/O event.
A negative timeout value means an infinite timeout.
- @remark sock_errno is set to SOCKET_ETIMEDOUT on timeout.
+ @remark socket_errno is set to SOCKET_ETIMEDOUT on timeout.
@return A three-state value which indicates the operation status.
@retval -1 Failure, socket_errno indicates the error.
diff --git a/win/packaging/heidisql.cmake b/win/packaging/heidisql.cmake
index a3d884adb56..6290ada9704 100644
--- a/win/packaging/heidisql.cmake
+++ b/win/packaging/heidisql.cmake
@@ -1,4 +1,4 @@
-SET(HEIDISQL_BASE_NAME "HeidiSQL_10.2_32_Portable")
+SET(HEIDISQL_BASE_NAME "HeidiSQL_11.0_32_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})
diff --git a/win/packaging/heidisql.wxi.in b/win/packaging/heidisql.wxi.in
index 4244b47d0d8..58d95210783 100644
--- a/win/packaging/heidisql.wxi.in
+++ b/win/packaging/heidisql.wxi.in
@@ -33,20 +33,25 @@
<RegistryValue Root="HKCU" Key="Software\@CPACK_WIX_PACKAGE_NAME@\Uninstall" Name="shortcuts.heidisql" Value="1" Type="string" KeyPath="yes" />
<Shortcut Id="startmenuHeidiSQL" Directory="ShortcutFolder" Name="HeidiSQL" Target="[D.HeidiSQL]\heidisql.exe"/>
</Component>
+
+
<Component Id="component.HeidiSQL_libmysql.dll" Guid="*" Win64="no">
<File Id="heidisql.libmysql.dll" Name="libmysql.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmysql.dll" />
</Component>
+ <Component Id="component.HeidiSQL_libmysql_6.1.dll" Guid="*" Win64="no">
+ <File Id="heidisql.libmysql_6.1.dll" Name="libmysql-6.1.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmysql-6.1.dll" />
+ </Component>
<Component Id="component.HeidiSQL_libmariadb.dll" Guid="*" Win64="no">
<File Id="heidisql.libmariadb.dll" Name="libmariadb.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libmariadb.dll" />
</Component>
- <Component Id="component.HeidiSQL_libeay32.dll" Guid="*" Win64="no">
- <File Id="heidisql.libeay32.dll" Name="libeay32.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libeay32.dll" />
+ <Component Id="component.HeidiSQL_libssl_1_1.dll" Guid="*" Win64="no">
+ <File Id="heidisql.libssl_1_1.dll" Name="libssl-1_1.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libssl-1_1.dll" />
</Component>
- <Component Id="component.HeidiSQL_libpq.dll" Guid="*" Win64="no">
- <File Id="heidisql.libpq.dll" Name="libpq.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libpq.dll" />
+ <Component Id="component.HeidiSQL_libpq_10.dll" Guid="*" Win64="no">
+ <File Id="heidisql.libpq_10.dll" Name="libpq-10.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libpq-10.dll" />
</Component>
- <Component Id="component.HeidiSQL_ssleay32.dll" Guid="*" Win64="no">
- <File Id="heidisql.ssleay32.dll" Name="ssleay32.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\ssleay32.dll" />
+ <Component Id="component.HeidiSQL_libcrypto_1_1.dll" Guid="*" Win64="no">
+ <File Id="heidisql.libcrypto_1_1.dll" Name="libcrypto-1_1.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libcrypto-1_1.dll" />
</Component>
<Component Id="component.HeidiSQL_libintl_8.dll" Guid="*" Win64="no">
<File Id="heidisql.libintl_8.dll" Name="libintl-8.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libintl-8.dll" />
@@ -54,6 +59,9 @@
<Component Id="component.HeidiSQL_libiconv_2.dll" Guid="*" Win64="no">
<File Id="heidisql.libiconv_2.dll" Name="libiconv-2.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\libiconv-2.dll" />
</Component>
+ <Component Id="component.HeidiSQL_sqlite3.dll" Guid="*" Win64="no">
+ <File Id="heidisql.sqlite3.dll" Name="sqlite3.dll" Source="${HEIDISQL_DOWNLOAD_DIR}\sqlite3.dll" />
+ </Component>
<Directory Id="D.HeidiSQL.plugins" Name="plugins">
<?foreach dll in $(var.pluginlist) ?>
@@ -76,11 +84,13 @@
<ComponentRef Id="component.HeidiSQL_MenuShortcut"/>
<ComponentRef Id="component.HeidiSQL_libmysql.dll"/>
<ComponentRef Id="component.HeidiSQL_libmariadb.dll"/>
- <ComponentRef Id="component.HeidiSQL_libeay32.dll" />
- <ComponentRef Id="component.HeidiSQL_libpq.dll" />
- <ComponentRef Id="component.HeidiSQL_ssleay32.dll" />
+ <ComponentRef Id="component.HeidiSQL_libssl_1_1.dll" />
+ <ComponentRef Id="component.HeidiSQL_libpq_10.dll" />
+ <ComponentRef Id="component.HeidiSQL_libcrypto_1_1.dll" />
<ComponentRef Id="component.HeidiSQL_libintl_8.dll" />
<ComponentRef Id="component.HeidiSQL_libiconv_2.dll" />
+ <ComponentRef Id="component.HeidiSQL_sqlite3.dll" />
+ <ComponentRef Id="component.HeidiSQL_libmysql_6.1.dll" />
<?foreach dll in $(var.pluginlist)?>
<ComponentRef Id="component.HeidiSQL_$(var.dll)" />
<?endforeach?>